blob: d530f47ad77218068a9ad8caf3c36a6a6bde291a [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;
37import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
38import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070039import static android.view.WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070040import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041
42import com.android.internal.app.IBatteryStats;
43import com.android.internal.policy.PolicyManager;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080044import com.android.internal.policy.impl.PhoneWindowManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import com.android.internal.view.IInputContext;
46import com.android.internal.view.IInputMethodClient;
47import com.android.internal.view.IInputMethodManager;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080048import com.android.internal.view.WindowManagerPolicyThread;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080049import com.android.server.AttributeCache;
50import com.android.server.EventLogTags;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080051import com.android.server.Watchdog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052import com.android.server.am.BatteryStatsService;
Jeff Brownfa25bf52012-07-23 19:26:30 -070053import com.android.server.display.DisplayManagerService;
Jeff Brown4532e612012-04-05 14:27:12 -070054import com.android.server.input.InputManagerService;
Jeff Brown4f8ecd82012-06-18 18:29:13 -070055import com.android.server.power.PowerManagerService;
56import com.android.server.power.ShutdownThread;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057
58import android.Manifest;
59import android.app.ActivityManagerNative;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070060import android.app.ActivityOptions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.app.IActivityManager;
Joe Onoratoac0ee892011-01-30 15:38:30 -080062import android.app.StatusBarManager;
Jim Millerd6b57052010-06-07 17:52:42 -070063import android.app.admin.DevicePolicyManager;
Jeff Brownff7e6ef2012-08-15 02:05:18 -070064import android.animation.ValueAnimator;
Jim Miller284b62e2010-06-08 14:27:42 -070065import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.content.Context;
Jim Miller284b62e2010-06-08 14:27:42 -070067import android.content.Intent;
68import android.content.IntentFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069import android.content.pm.ActivityInfo;
70import android.content.pm.PackageManager;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070071import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072import android.content.res.Configuration;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080073import android.graphics.Bitmap;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070074import android.graphics.Canvas;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.graphics.Matrix;
76import android.graphics.PixelFormat;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -070077import android.graphics.Point;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078import android.graphics.Rect;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070079import android.graphics.RectF;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.graphics.Region;
Craig Mautnerb47bbc32012-08-22 17:41:48 -070081import android.hardware.display.DisplayManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082import android.os.Binder;
Dianne Hackborn75804932009-10-20 20:15:20 -070083import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import android.os.Debug;
85import android.os.Handler;
86import android.os.IBinder;
Dianne Hackborn38e29a62011-09-18 14:43:08 -070087import android.os.IRemoteCallback;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088import android.os.Looper;
89import android.os.Message;
90import android.os.Parcel;
91import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import android.os.PowerManager;
93import android.os.Process;
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -070094import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095import android.os.RemoteException;
96import android.os.ServiceManager;
Brad Fitzpatrickec062f62010-11-03 09:56:54 -070097import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098import android.os.SystemClock;
99import android.os.SystemProperties;
Dianne Hackborn1ded0b12012-04-26 14:14:50 -0700100import android.os.Trace;
Craig Mautner259328c2012-08-21 19:30:58 -0700101import android.os.WorkSource;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import android.provider.Settings;
Dianne Hackborn723738c2009-06-25 19:48:04 -0700103import android.util.DisplayMetrics;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104import android.util.EventLog;
Michael Jurka4accb6a2012-03-26 09:18:46 -0700105import android.util.FloatMath;
Jim Millerd6b57052010-06-07 17:52:42 -0700106import android.util.Log;
Craig Mautner59c00972012-07-30 12:10:24 -0700107import android.util.SparseArray;
Dianne Hackborn38e29a62011-09-18 14:43:08 -0700108import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800109import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110import android.util.SparseIntArray;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700111import android.util.TypedValue;
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800112import android.view.Choreographer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113import android.view.Display;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700114import android.view.DisplayInfo;
Adam Powelldfee59a2011-08-05 20:48:30 -0700115import android.view.Gravity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116import android.view.IApplicationToken;
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -0700117import android.view.IDisplayContentChangeListener;
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -0700118import android.view.IInputFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119import android.view.IOnKeyguardExitResult;
120import android.view.IRotationWatcher;
121import android.view.IWindow;
122import android.view.IWindowManager;
123import android.view.IWindowSession;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700124import android.view.InputChannel;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700125import android.view.InputDevice;
Jeff Brownbbda99d2010-07-28 15:48:59 -0700126import android.view.InputEvent;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800127import android.view.InputEventReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128import android.view.KeyEvent;
129import android.view.MotionEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130import android.view.Surface;
131import android.view.SurfaceSession;
132import android.view.View;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700133import android.view.ViewTreeObserver;
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -0700134import android.view.WindowInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135import android.view.WindowManager;
Jeff Brown98365d72012-08-19 20:30:52 -0700136import android.view.WindowManagerGlobal;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137import android.view.WindowManagerPolicy;
138import android.view.WindowManager.LayoutParams;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700139import android.view.WindowManagerPolicy.FakeWindow;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700140import android.view.animation.AlphaAnimation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141import android.view.animation.Animation;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700142import android.view.animation.AnimationSet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143import android.view.animation.AnimationUtils;
Michael Jurkac016aaa2012-06-05 17:22:24 -0700144import android.view.animation.DecelerateInterpolator;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700145import android.view.animation.Interpolator;
146import android.view.animation.ScaleAnimation;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700147import android.view.animation.Transformation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148
149import java.io.BufferedWriter;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700150import java.io.DataInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151import java.io.File;
152import java.io.FileDescriptor;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700153import java.io.FileInputStream;
154import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155import java.io.IOException;
156import java.io.OutputStream;
157import java.io.OutputStreamWriter;
158import java.io.PrintWriter;
159import java.io.StringWriter;
160import java.net.Socket;
Jeff Brownd7a04de2012-06-17 14:17:52 -0700161import java.text.DateFormat;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162import java.util.ArrayList;
Jeff Brownd7a04de2012-06-17 14:17:52 -0700163import java.util.Date;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164import java.util.HashMap;
165import java.util.HashSet;
166import java.util.Iterator;
167import java.util.List;
Craig Mautner59c00972012-07-30 12:10:24 -0700168import java.util.NoSuchElementException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169
170/** {@hide} */
Dianne Hackbornddca3ee2009-07-23 19:01:31 -0700171public class WindowManagerService extends IWindowManager.Stub
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700172 implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs,
Craig Mautner722285e2012-09-07 13:55:58 -0700173 DisplayManagerService.WindowManagerFuncs, DisplayManager.DisplayListener {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 static final String TAG = "WindowManager";
175 static final boolean DEBUG = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700176 static final boolean DEBUG_ADD_REMOVE = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800177 static final boolean DEBUG_FOCUS = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178 static final boolean DEBUG_ANIM = false;
Dianne Hackborn9b52a212009-12-11 14:51:35 -0800179 static final boolean DEBUG_LAYOUT = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800180 static final boolean DEBUG_RESIZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181 static final boolean DEBUG_LAYERS = false;
182 static final boolean DEBUG_INPUT = false;
183 static final boolean DEBUG_INPUT_METHOD = false;
184 static final boolean DEBUG_VISIBILITY = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700185 static final boolean DEBUG_WINDOW_MOVEMENT = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800186 static final boolean DEBUG_TOKEN_MOVEMENT = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 static final boolean DEBUG_ORIENTATION = false;
Dianne Hackbornbc7386c2011-06-06 17:27:54 -0700188 static final boolean DEBUG_APP_ORIENTATION = false;
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700189 static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190 static final boolean DEBUG_APP_TRANSITIONS = false;
191 static final boolean DEBUG_STARTING_WINDOW = false;
192 static final boolean DEBUG_REORDER = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800193 static final boolean DEBUG_WALLPAPER = false;
Christopher Tate994ef922011-01-12 20:06:07 -0800194 static final boolean DEBUG_DRAG = false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700195 static final boolean DEBUG_SCREEN_ON = false;
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -0700196 static final boolean DEBUG_SCREENSHOT = false;
Dianne Hackborn38cc8962011-10-13 11:33:55 -0700197 static final boolean DEBUG_BOOT = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700198 static final boolean DEBUG_LAYOUT_REPEATS = true;
Craig Mautner7358fbf2012-04-12 21:06:33 -0700199 static final boolean DEBUG_SURFACE_TRACE = false;
Craig Mautner7d8df392012-04-06 15:26:23 -0700200 static final boolean DEBUG_WINDOW_TRACE = false;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700201 static final boolean SHOW_SURFACE_ALLOC = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800202 static final boolean SHOW_TRANSACTIONS = false;
Dianne Hackborn36991742011-10-11 21:35:26 -0700203 static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700204 static final boolean HIDE_STACK_CRAWLS = true;
Craig Mautnercf8cbbe2012-03-25 21:54:36 -0700205 static final int LAYOUT_REPEAT_THRESHOLD = 4;
Michael Chan53071d62009-05-13 17:29:48 -0700206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 static final boolean PROFILE_ORIENTATION = false;
Dave Bortcfe65242009-04-09 14:51:04 -0700208 static final boolean localLOGV = DEBUG;
Romain Guy06882f82009-06-10 13:36:04 -0700209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800210 /** How much to multiply the policy's type layer, to reserve room
211 * for multiple windows of the same type and Z-ordering adjustment
212 * with TYPE_LAYER_OFFSET. */
213 static final int TYPE_LAYER_MULTIPLIER = 10000;
Romain Guy06882f82009-06-10 13:36:04 -0700214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
216 * or below others in the same layer. */
217 static final int TYPE_LAYER_OFFSET = 1000;
Romain Guy06882f82009-06-10 13:36:04 -0700218
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219 /** How much to increment the layer for each window, to reserve room
220 * for effect surfaces between them.
221 */
222 static final int WINDOW_LAYER_MULTIPLIER = 5;
Romain Guy06882f82009-06-10 13:36:04 -0700223
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800224 /**
225 * Dim surface layer is immediately below target window.
226 */
227 static final int LAYER_OFFSET_DIM = 1;
228
229 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700230 * Blur surface layer is immediately below dim layer.
231 */
232 static final int LAYER_OFFSET_BLUR = 2;
233
234 /**
235 * Animation thumbnail is as far as possible below the window above
236 * the thumbnail (or in other words as far as possible above the window
237 * below it).
238 */
239 static final int LAYER_OFFSET_THUMBNAIL = WINDOW_LAYER_MULTIPLIER-1;
240
241 /**
Dianne Hackborn7916ac62011-05-16 20:45:48 -0700242 * Layer at which to put the rotation freeze snapshot.
243 */
244 static final int FREEZE_LAYER = (TYPE_LAYER_MULTIPLIER * 200) + 1;
245
246 /**
247 * Layer at which to put the mask for emulated screen sizes.
248 */
249 static final int MASK_LAYER = TYPE_LAYER_MULTIPLIER * 200;
250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251 /** The maximum length we will accept for a loaded animation duration:
252 * this is 10 seconds.
253 */
254 static final int MAX_ANIMATION_DURATION = 10*1000;
255
256 /** Amount of time (in milliseconds) to animate the dim surface from one
257 * value to another, when no window animation is driving it.
258 */
259 static final int DEFAULT_DIM_DURATION = 200;
260
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700261 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
262 * compatible windows.
263 */
264 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
265
Dianne Hackborna1111872010-11-23 20:55:11 -0800266 /**
267 * If true, the window manager will do its own custom freezing and general
268 * management of the screen during rotation.
269 */
270 static final boolean CUSTOM_SCREEN_ROTATION = true;
271
Jeff Brownb09abc12011-01-13 21:08:27 -0800272 // Maximum number of milliseconds to wait for input devices to be enumerated before
273 // proceding with safe mode detection.
274 private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
Jim Miller28637ba2011-07-06 19:57:05 -0700275
Jeff Brown349703e2010-06-22 01:27:15 -0700276 // Default input dispatching timeout in nanoseconds.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800277 static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
Romain Guy06882f82009-06-10 13:36:04 -0700278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 static final int UPDATE_FOCUS_NORMAL = 0;
280 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
281 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
282 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700283
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700285 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286
Craig Mautner5642a482012-08-23 12:16:53 -0700287 final private KeyguardDisableHandler mKeyguardDisableHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700289 private final boolean mHeadless;
290
Michael Jurkac016aaa2012-06-05 17:22:24 -0700291 private static final float THUMBNAIL_ANIMATION_DECELERATE_FACTOR = 1.5f;
292
Jim Miller284b62e2010-06-08 14:27:42 -0700293 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
294 @Override
295 public void onReceive(Context context, Intent intent) {
Craig Mautner9dc52bc2012-08-06 14:15:42 -0700296 final String action = intent.getAction();
297 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
Craig Mautner5642a482012-08-23 12:16:53 -0700298 mKeyguardDisableHandler.sendEmptyMessage(
299 KeyguardDisableHandler.KEYGUARD_POLICY_CHANGED);
Jim Miller284b62e2010-06-08 14:27:42 -0700300 }
301 }
302 };
303
Craig Mautner9dc52bc2012-08-06 14:15:42 -0700304 // Current user when multi-user is enabled. Don't show windows of non-current user.
305 int mCurrentUserId;
306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307 final Context mContext;
308
309 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700310
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700311 final boolean mAllowBootMessages;
312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
316
317 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700318
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700320
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800321 /**
322 * All currently active sessions with clients.
323 */
324 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 /**
327 * Mapping from an IWindow IBinder to the server's Window object.
328 * This is also used as the lock for all of our state.
329 */
330 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
331
332 /**
333 * Mapping from a token IBinder to a WindowToken object.
334 */
335 final HashMap<IBinder, WindowToken> mTokenMap =
336 new HashMap<IBinder, WindowToken>();
337
338 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339 * Window tokens that are in the process of exiting, but still
340 * on screen for animations.
341 */
342 final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
343
344 /**
Craig Mautneref25d7a2012-05-15 23:01:47 -0700345 * List controlling the ordering of windows in different applications which must
346 * be kept in sync with ActivityManager.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347 */
Craig Mautnerbec53f72012-04-05 11:49:05 -0700348 final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349
350 /**
Craig Mautneref25d7a2012-05-15 23:01:47 -0700351 * AppWindowTokens in the Z order they were in at the start of an animation. Between
352 * animations this list is maintained in the exact order of mAppTokens. If tokens
353 * are added to mAppTokens during an animation an attempt is made to insert them at the same
354 * logical location in this list. Note that this list is always in sync with mWindows.
355 */
356 ArrayList<AppWindowToken> mAnimatingAppTokens = new ArrayList<AppWindowToken>();
357
358 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800359 * Application tokens that are in the process of exiting, but still
360 * on screen for animations.
361 */
362 final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
363
364 /**
365 * List of window tokens that have finished starting their application,
366 * and now need to have the policy remove their windows.
367 */
368 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
369
370 /**
Dianne Hackborndf89e652011-10-06 22:35:11 -0700371 * Fake windows added to the window manager. Note: ordered from top to
372 * bottom, opposite of mWindows.
373 */
374 final ArrayList<FakeWindowImpl> mFakeWindows = new ArrayList<FakeWindowImpl>();
375
376 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 * Windows that are being resized. Used so we can tell the client about
378 * the resize after closing the transaction in which we resized the
379 * underlying surface.
380 */
381 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
382
383 /**
384 * Windows whose animations have ended and now must be removed.
385 */
386 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
387
388 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800389 * Used when processing mPendingRemove to avoid working on the original array.
390 */
391 WindowState[] mPendingRemoveTmp = new WindowState[20];
392
393 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 * Windows whose surface should be destroyed.
395 */
396 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
397
398 /**
399 * Windows that have lost input focus and are waiting for the new
400 * focus window to be displayed before they are told about this.
401 */
402 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
403
404 /**
405 * This is set when we have run out of memory, and will either be an empty
406 * list or contain windows that need to be force removed.
407 */
408 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700409
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800410 /**
Dianne Hackborn38e29a62011-09-18 14:43:08 -0700411 * Windows that clients are waiting to have drawn.
412 */
413 ArrayList<Pair<WindowState, IRemoteCallback>> mWaitingForDrawn
414 = new ArrayList<Pair<WindowState, IRemoteCallback>>();
415
416 /**
Dianne Hackborn12d3a942012-04-27 14:16:30 -0700417 * Windows that have called relayout() while we were running animations,
418 * so we need to tell when the animation is done.
419 */
420 final ArrayList<WindowState> mRelayoutWhileAnimating = new ArrayList<WindowState>();
421
422 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800423 * Used when rebuilding window list to keep track of windows that have
424 * been removed.
425 */
426 WindowState[] mRebuildTmp = new WindowState[20];
427
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800428 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700429
Craig Mautner7358fbf2012-04-12 21:06:33 -0700430 final SurfaceSession mFxSession;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700431 Watermark mWatermark;
Brad Fitzpatrick68044332010-11-22 18:19:48 -0800432 StrictModeFlash mStrictModeFlash;
Romain Guy06882f82009-06-10 13:36:04 -0700433
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800434 final float[] mTmpFloats = new float[9];
435
Jeff Browne215f262012-09-10 16:01:14 -0700436 boolean mDisplayReady;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437 boolean mSafeMode;
438 boolean mDisplayEnabled = false;
439 boolean mSystemBooted = false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700440 boolean mForceDisplayEnabled = false;
Dianne Hackborn661cd522011-08-22 00:26:20 -0700441 boolean mShowingBootMessages = false;
Dianne Hackborn1fbee792011-11-30 11:29:58 -0800442
Jeff Brownd7a04de2012-06-17 14:17:52 -0700443 String mLastANRState;
444
Craig Mautner59c00972012-07-30 12:10:24 -0700445 /** All DisplayDontents in the world, kept here */
446 private SparseArray<DisplayContent> mDisplayContents = new SparseArray<DisplayContent>();
Dianne Hackborn1fbee792011-11-30 11:29:58 -0800447
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800448 int mRotation = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborndacea8c2011-04-21 17:26:39 -0700450 boolean mAltOrientation = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 ArrayList<IRotationWatcher> mRotationWatchers
452 = new ArrayList<IRotationWatcher>();
Jeff Brown01a98dd2011-09-20 15:08:29 -0700453 int mDeferredRotationPauseCount;
Romain Guy06882f82009-06-10 13:36:04 -0700454
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700455 final Rect mSystemDecorRect = new Rect();
456 int mSystemDecorLayer = 0;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700457 final Rect mScreenRect = new Rect();
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700458
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800459 boolean mTraversalScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800460 boolean mDisplayFrozen = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800461 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462 boolean mWindowsFreezingScreen = false;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700463 boolean mClientFreezingScreen = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800464 int mAppsFreezingScreen = 0;
Dianne Hackbornbc7386c2011-06-06 17:27:54 -0700465 int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800466
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800467 int mLayoutSeq = 0;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700468
469 int mLastStatusBarVisibility = 0;
470
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800471 // State while inside of layoutAndPlaceSurfacesLocked().
472 boolean mFocusMayChange;
Craig Mautner01cd0e72012-06-18 10:19:11 -0700473
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800474 Configuration mCurConfiguration = new Configuration();
Craig Mautner01cd0e72012-06-18 10:19:11 -0700475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800476 // This is held as long as we have the screen frozen, to give us time to
477 // perform a rotation animation when turning off shows the lock screen which
478 // changes the orientation.
479 PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700480
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800481 // State management of app transitions. When we are preparing for a
482 // transition, mNextAppTransition will be the kind of transition to
483 // perform or TRANSIT_NONE if we are not waiting. If we are waiting,
484 // mOpeningApps and mClosingApps are the lists of tokens that will be
485 // made visible or hidden at the next transition.
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700486 int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700487 int mNextAppTransitionType = ActivityOptions.ANIM_NONE;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700488 String mNextAppTransitionPackage;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700489 Bitmap mNextAppTransitionThumbnail;
Michael Jurka832cb222012-04-13 09:32:47 -0700490 // Used for thumbnail transitions. True if we're scaling up, false if scaling down
491 boolean mNextAppTransitionScaleUp;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700492 IRemoteCallback mNextAppTransitionCallback;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700493 int mNextAppTransitionEnter;
494 int mNextAppTransitionExit;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700495 int mNextAppTransitionStartX;
496 int mNextAppTransitionStartY;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700497 int mNextAppTransitionStartWidth;
498 int mNextAppTransitionStartHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800499 boolean mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -0700500 boolean mAppTransitionRunning = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501 boolean mAppTransitionTimeout = false;
502 boolean mStartingIconInTransition = false;
503 boolean mSkipAppTransitionAnimation = false;
504 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
505 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700506
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700507 boolean mIsTouchDevice;
508
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700509 final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Jeff Brownbc68a592011-07-25 12:58:12 -0700510 final DisplayMetrics mRealDisplayMetrics = new DisplayMetrics();
Dianne Hackborn48a76512011-06-08 21:51:44 -0700511 final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics();
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700512 final DisplayMetrics mCompatDisplayMetrics = new DisplayMetrics();
513
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800514 final H mH = new H();
515
516 final Choreographer mChoreographer = Choreographer.getInstance();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517
518 WindowState mCurrentFocus = null;
519 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700520
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800521 /** This just indicates the window the input method is on top of, not
522 * necessarily the window its input is going to. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523 WindowState mInputMethodTarget = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800524
525 /** If true hold off on modifying the animation layer of mInputMethodTarget */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 boolean mInputMethodTargetWaitingAnim;
527 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700528
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800529 WindowState mInputMethodWindow = null;
530 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
531
Jeff Brown2992ea72011-01-28 22:04:14 -0800532 boolean mHardKeyboardAvailable;
533 boolean mHardKeyboardEnabled;
534 OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
535
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700536 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800537
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700538 // If non-null, this is the currently visible window that is associated
539 // with the wallpaper.
540 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700541 // If non-null, we are in the middle of animating from one wallpaper target
542 // to another, and this is the lower one in Z-order.
Craig Mautner918b53b2012-07-09 14:15:54 -0700543 private WindowState mLowerWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700544 // If non-null, we are in the middle of animating from one wallpaper target
545 // to another, and this is the higher one in Z-order.
Craig Mautner918b53b2012-07-09 14:15:54 -0700546 private WindowState mUpperWallpaperTarget = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700547 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700548 float mLastWallpaperX = -1;
549 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800550 float mLastWallpaperXStep = -1;
551 float mLastWallpaperYStep = -1;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700552 // This is set when we are waiting for a wallpaper to tell us it is done
553 // changing its scroll position.
554 WindowState mWaitingOnWallpaper;
555 // The last time we had a timeout when waiting for a wallpaper.
556 long mLastWallpaperTimeoutTime;
557 // We give a wallpaper up to 150ms to finish scrolling.
558 static final long WALLPAPER_TIMEOUT = 150;
559 // Time we wait after a timeout before trying to wait again.
560 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800561
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800562 AppWindowToken mFocusedApp = null;
563
564 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700565
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800566 float mWindowAnimationScale = 1.0f;
567 float mTransitionAnimationScale = 1.0f;
Chet Haasec38fa1f2012-02-01 16:37:46 -0800568 float mAnimatorDurationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700569
Jeff Brown4532e612012-04-05 14:27:12 -0700570 final InputManagerService mInputManager;
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700571 final DisplayManagerService mDisplayManagerService;
572 final DisplayManager mDisplayManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800573
574 // Who is holding the screen on.
575 Session mHoldingScreenOn;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700576 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700577
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700578 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800579
Christopher Tatea53146c2010-09-07 11:57:52 -0700580 DragState mDragState = null;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800581
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800582 /** Pulled out of performLayoutAndPlaceSurfacesLockedInner in order to refactor into multiple
583 * methods. */
Craig Mautnera608b882012-03-30 13:03:49 -0700584 class LayoutFields {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700585 static final int SET_UPDATE_ROTATION = 1 << 0;
586 static final int SET_WALLPAPER_MAY_CHANGE = 1 << 1;
587 static final int SET_FORCE_HIDING_CHANGED = 1 << 2;
Craig Mautner2639da52012-07-09 09:39:06 -0700588 static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3;
Craig Mautner7d8df392012-04-06 15:26:23 -0700589 static final int SET_TURN_ON_SCREEN = 1 << 4;
Craig Mautnera608b882012-03-30 13:03:49 -0700590
Craig Mautner764983d2012-03-22 11:37:36 -0700591 boolean mWallpaperForceHidingChanged = false;
592 boolean mWallpaperMayChange = false;
Craig Mautner764983d2012-03-22 11:37:36 -0700593 boolean mOrientationChangeComplete = true;
Craig Mautnere7ae2502012-03-26 17:11:19 -0700594 int mAdjResult = 0;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800595 private Session mHoldScreen = null;
596 private boolean mObscured = false;
Craig Mautner764983d2012-03-22 11:37:36 -0700597 boolean mDimming = false;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800598 private boolean mSyswin = false;
599 private float mScreenBrightness = -1;
600 private float mButtonBrightness = -1;
Craig Mautnera608b882012-03-30 13:03:49 -0700601 private boolean mUpdateRotation = false;
Craig Mautner65d11b32012-10-01 13:59:52 -0700602
603 private static final int DISPLAY_CONTENT_UNKNOWN = 0;
604 private static final int DISPLAY_CONTENT_MIRROR = 1;
605 private static final int DISPLAY_CONTENT_UNIQUE = 2;
606 private int mDisplayHasContent = DISPLAY_CONTENT_UNKNOWN;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800607 }
Craig Mautner01cd0e72012-06-18 10:19:11 -0700608 final LayoutFields mInnerFields = new LayoutFields();
609
Craig Mautner322e4032012-07-13 13:35:20 -0700610 static class AppWindowAnimParams {
611 AppWindowAnimator mAppAnimator;
612 ArrayList<WindowStateAnimator> mWinAnimators;
613
614 public AppWindowAnimParams(final AppWindowAnimator appAnimator) {
615 mAppAnimator = appAnimator;
616
Craig Mautner5c0e78c2012-09-12 16:45:36 -0700617 final AppWindowToken atoken = appAnimator.mAppToken;
Craig Mautner322e4032012-07-13 13:35:20 -0700618 mWinAnimators = new ArrayList<WindowStateAnimator>();
Craig Mautner5c0e78c2012-09-12 16:45:36 -0700619 final int N = atoken.allAppWindows.size();
Craig Mautner322e4032012-07-13 13:35:20 -0700620 for (int i = 0; i < N; i++) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -0700621 mWinAnimators.add(atoken.allAppWindows.get(i).mWinAnimator);
Craig Mautner322e4032012-07-13 13:35:20 -0700622 }
623 }
624 }
625
Craig Mautner711f90a2012-07-03 18:43:52 -0700626 static class LayoutToAnimatorParams {
Craig Mautner322e4032012-07-13 13:35:20 -0700627 boolean mParamsModified;
628
Craig Mautner918b53b2012-07-09 14:15:54 -0700629 static final long WALLPAPER_TOKENS_CHANGED = 1 << 0;
630 long mChanges;
631
Craig Mautner711f90a2012-07-03 18:43:52 -0700632 boolean mAnimationScheduled;
Craig Mautnera91f9e22012-09-14 16:22:08 -0700633 SparseArray<WinAnimatorList> mWinAnimatorLists = new SparseArray<WinAnimatorList>();
Craig Mautner711f90a2012-07-03 18:43:52 -0700634 WindowState mWallpaperTarget;
Craig Mautner918b53b2012-07-09 14:15:54 -0700635 WindowState mLowerWallpaperTarget;
636 WindowState mUpperWallpaperTarget;
Craig Mautnera91f9e22012-09-14 16:22:08 -0700637 SparseArray<DimAnimator.Parameters> mDimParams = new SparseArray<DimAnimator.Parameters>();
Craig Mautner918b53b2012-07-09 14:15:54 -0700638 ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Craig Mautner322e4032012-07-13 13:35:20 -0700639 ArrayList<AppWindowAnimParams> mAppWindowAnimParams = new ArrayList<AppWindowAnimParams>();
Craig Mautner711f90a2012-07-03 18:43:52 -0700640 }
Craig Mautner918b53b2012-07-09 14:15:54 -0700641 /** Params from WindowManagerService to WindowAnimator. Do not modify or read without first
642 * locking on either mWindowMap or mAnimator and then on mLayoutToAnim */
Craig Mautner711f90a2012-07-03 18:43:52 -0700643 final LayoutToAnimatorParams mLayoutToAnim = new LayoutToAnimatorParams();
Craig Mautner01cd0e72012-06-18 10:19:11 -0700644
645 /** The lowest wallpaper target with a detached wallpaper animation on it. */
646 WindowState mWindowDetachedWallpaper = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800647
Craig Mautner6fbda632012-07-03 09:26:39 -0700648 /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
649 * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
650 private int mTransactionSequence;
651
Craig Mautnerbb1449b2012-03-23 16:11:14 -0700652 /** Only do a maximum of 6 repeated layouts. After that quit */
653 private int mLayoutRepeatCount;
654
Craig Mautner764983d2012-03-22 11:37:36 -0700655 final WindowAnimator mAnimator;
Jeff Brown4a06c802012-02-15 15:06:01 -0800656
Jeff Brown32cbc38552011-12-01 14:01:49 -0800657 final class DragInputEventReceiver extends InputEventReceiver {
658 public DragInputEventReceiver(InputChannel inputChannel, Looper looper) {
659 super(inputChannel, looper);
660 }
661
Christopher Tatea53146c2010-09-07 11:57:52 -0700662 @Override
Jeff Brown32cbc38552011-12-01 14:01:49 -0800663 public void onInputEvent(InputEvent event) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700664 boolean handled = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700665 try {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800666 if (event instanceof MotionEvent
667 && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
Jeff Brown3915bb82010-11-05 15:02:16 -0700668 && mDragState != null) {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800669 final MotionEvent motionEvent = (MotionEvent)event;
Jeff Brown3915bb82010-11-05 15:02:16 -0700670 boolean endDrag = false;
Jeff Brown4952dfd2011-11-30 19:23:22 -0800671 final float newX = motionEvent.getRawX();
672 final float newY = motionEvent.getRawY();
Jeff Brown3915bb82010-11-05 15:02:16 -0700673
Jeff Brown4952dfd2011-11-30 19:23:22 -0800674 switch (motionEvent.getAction()) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700675 case MotionEvent.ACTION_DOWN: {
676 if (DEBUG_DRAG) {
677 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
678 }
679 } break;
680
681 case MotionEvent.ACTION_MOVE: {
682 synchronized (mWindowMap) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700683 // move the surface and tell the involved window(s) where we are
Christopher Tatea53146c2010-09-07 11:57:52 -0700684 mDragState.notifyMoveLw(newX, newY);
685 }
686 } break;
687
688 case MotionEvent.ACTION_UP: {
689 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
690 + newX + "," + newY);
691 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700692 endDrag = mDragState.notifyDropLw(newX, newY);
Christopher Tatea53146c2010-09-07 11:57:52 -0700693 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700694 } break;
695
696 case MotionEvent.ACTION_CANCEL: {
697 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
698 endDrag = true;
699 } break;
700 }
701
702 if (endDrag) {
703 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
704 // tell all the windows that the drag has ended
Chris Tate59943592010-10-11 20:33:44 -0700705 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700706 mDragState.endDragLw();
Chris Tate59943592010-10-11 20:33:44 -0700707 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700708 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700709
710 handled = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700711 }
712 } catch (Exception e) {
713 Slog.e(TAG, "Exception caught by drag handleMotion", e);
714 } finally {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800715 finishInputEvent(event, handled);
Christopher Tatea53146c2010-09-07 11:57:52 -0700716 }
717 }
Jeff Brown32cbc38552011-12-01 14:01:49 -0800718 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700719
720 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800721 * Whether the UI is currently running in touch mode (not showing
722 * navigational focus because the user is directly pressing the screen).
723 */
Michael Jurkae99adc72011-08-11 18:28:01 -0700724 boolean mInTouchMode = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800725
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -0700726 // Temp regions for intermediary calculations.
727 private final Region mTempRegion = new Region();
728
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800729 private ViewServer mViewServer;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700730 private ArrayList<WindowChangeListener> mWindowChangeListeners =
731 new ArrayList<WindowChangeListener>();
732 private boolean mWindowsChanged = false;
733
734 public interface WindowChangeListener {
735 public void windowsChanged();
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -0700736 public void focusChanged();
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700737 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800738
Dianne Hackbornc485a602009-03-24 22:39:49 -0700739 final Configuration mTempConfiguration = new Configuration();
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700740
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700741 // The desired scaling factor for compatible apps.
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400742 float mCompatibleScreenScale;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700743
Jeff Brown780c46f2012-06-24 12:15:38 -0700744 // If true, only the core apps and services are being launched because the device
745 // is in a special boot mode, such as being encrypted or waiting for a decryption password.
746 // For example, when this flag is true, there will be no wallpaper service.
747 final boolean mOnlyCore;
748
Jeff Brownbd6e1502012-08-28 03:27:37 -0700749 public static WindowManagerService main(final Context context,
750 final PowerManagerService pm, final DisplayManagerService dm,
Jeff Browna9d131c2012-09-20 16:48:17 -0700751 final InputManagerService im,
Jeff Brownbd6e1502012-08-28 03:27:37 -0700752 final Handler uiHandler, final Handler wmHandler,
753 final boolean haveInputMethods, final boolean showBootMsgs,
754 final boolean onlyCore) {
755 final WindowManagerService[] holder = new WindowManagerService[1];
756 wmHandler.runWithScissors(new Runnable() {
757 @Override
758 public void run() {
Jeff Browna9d131c2012-09-20 16:48:17 -0700759 holder[0] = new WindowManagerService(context, pm, dm, im,
Jeff Brownbd6e1502012-08-28 03:27:37 -0700760 uiHandler, haveInputMethods, showBootMsgs, onlyCore);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800761 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700762 }, 0);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700763 return holder[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800764 }
Romain Guy06882f82009-06-10 13:36:04 -0700765
Jeff Brownbd6e1502012-08-28 03:27:37 -0700766 private void initPolicy(Handler uiHandler) {
767 uiHandler.runWithScissors(new Runnable() {
768 @Override
769 public void run() {
770 WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
Romain Guy06882f82009-06-10 13:36:04 -0700771
Jeff Brownbd6e1502012-08-28 03:27:37 -0700772 mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
773 mAnimator.mAboveUniverseLayer = mPolicy.getAboveUniverseLayer()
774 * TYPE_LAYER_MULTIPLIER
775 + TYPE_LAYER_OFFSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700777 }, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800778 }
779
780 private WindowManagerService(Context context, PowerManagerService pm,
Jeff Browna9d131c2012-09-20 16:48:17 -0700781 DisplayManagerService displayManager, InputManagerService inputManager,
782 Handler uiHandler,
Jeff Brown780c46f2012-06-24 12:15:38 -0700783 boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800784 mContext = context;
785 mHaveInputMethods = haveInputMethods;
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700786 mAllowBootMessages = showBootMsgs;
Jeff Brown780c46f2012-06-24 12:15:38 -0700787 mOnlyCore = onlyCore;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800788 mLimitedAlphaCompositing = context.getResources().getBoolean(
789 com.android.internal.R.bool.config_sf_limitedAlpha);
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700790 mDisplayManagerService = displayManager;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700791 mHeadless = displayManager.isHeadless();
Romain Guy06882f82009-06-10 13:36:04 -0700792
Craig Mautner722285e2012-09-07 13:55:58 -0700793 mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
794 mDisplayManager.registerDisplayListener(this, null);
795 Display[] displays = mDisplayManager.getDisplays();
796 for (Display display : displays) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -0700797 createDisplayContentLocked(display);
Craig Mautner722285e2012-09-07 13:55:58 -0700798 }
799
Craig Mautner5642a482012-08-23 12:16:53 -0700800 mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);
801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800802 mPowerManager = pm;
803 mPowerManager.setPolicy(mPolicy);
804 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
805 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
806 "SCREEN_FROZEN");
807 mScreenFrozenLock.setReferenceCounted(false);
808
809 mActivityManager = ActivityManagerNative.getDefault();
810 mBatteryStats = BatteryStatsService.getService();
811
812 // Get persisted window scale setting
813 mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
814 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
815 mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
816 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Jeff Brownff7e6ef2012-08-15 02:05:18 -0700817 setAnimatorDurationScale(Settings.System.getFloat(context.getContentResolver(),
818 Settings.System.ANIMATOR_DURATION_SCALE, mTransitionAnimationScale));
Romain Guy06882f82009-06-10 13:36:04 -0700819
Jim Miller284b62e2010-06-08 14:27:42 -0700820 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
821 IntentFilter filter = new IntentFilter();
822 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
823 mContext.registerReceiver(mBroadcastReceiver, filter);
824
Dianne Hackbornb80395c2012-06-14 19:38:20 -0700825 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
Craig Mautner259328c2012-08-21 19:30:58 -0700826 | PowerManager.ON_AFTER_RELEASE, TAG);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700827 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800828
Jeff Browna9d131c2012-09-20 16:48:17 -0700829 mInputManager = inputManager;
Craig Mautner9e809442012-06-22 17:13:04 -0700830 mFxSession = new SurfaceSession();
Craig Mautner918b53b2012-07-09 14:15:54 -0700831 mAnimator = new WindowAnimator(this);
Romain Guy06882f82009-06-10 13:36:04 -0700832
Jeff Brownbd6e1502012-08-28 03:27:37 -0700833 initPolicy(uiHandler);
Romain Guy06882f82009-06-10 13:36:04 -0700834
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800835 // Add ourself to the Watchdog monitors.
836 Watchdog.getInstance().addMonitor(this);
Craig Mautner7358fbf2012-04-12 21:06:33 -0700837
838 Surface.openTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700839 try {
840 createWatermarkInTransaction();
841 } finally {
842 Surface.closeTransaction();
843 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800844 }
845
Jeff Browna9d131c2012-09-20 16:48:17 -0700846 public InputMonitor getInputMonitor() {
847 return mInputMonitor;
Jeff Brown4532e612012-04-05 14:27:12 -0700848 }
849
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850 @Override
851 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
852 throws RemoteException {
853 try {
854 return super.onTransact(code, data, reply, flags);
855 } catch (RuntimeException e) {
856 // The window manager only throws security exceptions, so let's
857 // log all others.
858 if (!(e instanceof SecurityException)) {
Dianne Hackborn89620282011-09-11 12:47:45 -0700859 Log.wtf(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800860 }
861 throw e;
862 }
863 }
864
Jeff Browne33348b2010-07-15 23:54:05 -0700865 private void placeWindowAfter(WindowState pos, WindowState window) {
Craig Mautner59c00972012-07-30 12:10:24 -0700866 final WindowList windows = pos.getWindowList();
867 final int i = windows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800868 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800869 TAG, "Adding window " + window + " at "
Craig Mautner59c00972012-07-30 12:10:24 -0700870 + (i+1) + " of " + windows.size() + " (after " + pos + ")");
871 windows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700872 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800873 }
874
Jeff Browne33348b2010-07-15 23:54:05 -0700875 private void placeWindowBefore(WindowState pos, WindowState window) {
Craig Mautner59c00972012-07-30 12:10:24 -0700876 final WindowList windows = pos.getWindowList();
877 final int i = windows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800878 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800879 TAG, "Adding window " + window + " at "
Craig Mautner59c00972012-07-30 12:10:24 -0700880 + i + " of " + windows.size() + " (before " + pos + ")");
881 windows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700882 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800883 }
884
885 //This method finds out the index of a window that has the same app token as
886 //win. used for z ordering the windows in mWindows
887 private int findIdxBasedOnAppTokens(WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -0700888 WindowList windows = win.getWindowList();
889 for(int j = windows.size() - 1; j >= 0; j--) {
890 WindowState wentry = windows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800891 if(wentry.mAppToken == win.mAppToken) {
892 return j;
893 }
894 }
895 return -1;
896 }
Romain Guy06882f82009-06-10 13:36:04 -0700897
Craig Mautnerefb735d2012-09-07 15:40:24 -0700898 /**
899 * Return the list of Windows from the passed token on the given Display.
900 * @param token The token with all the windows.
901 * @param displayContent The display we are interested in.
902 * @return List of windows from token that are on displayContent.
903 */
Craig Mautner69b08182012-09-05 13:07:13 -0700904 WindowList getTokenWindowsOnDisplay(WindowToken token, DisplayContent displayContent) {
905 final WindowList windowList = new WindowList();
906 final int count = token.windows.size();
907 for (int i = 0; i < count; i++) {
908 final WindowState win = token.windows.get(i);
909 if (win.mDisplayContent == displayContent) {
910 windowList.add(win);
911 }
912 }
913 return windowList;
914 }
915
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800916 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
917 final IWindow client = win.mClient;
918 final WindowToken token = win.mToken;
Craig Mautner69b08182012-09-05 13:07:13 -0700919 final DisplayContent displayContent = win.mDisplayContent;
Romain Guy06882f82009-06-10 13:36:04 -0700920
Craig Mautner59c00972012-07-30 12:10:24 -0700921 final WindowList windows = win.getWindowList();
922 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800923 final WindowState attached = win.mAttachedWindow;
924 int i;
Craig Mautner69b08182012-09-05 13:07:13 -0700925 WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800926 if (attached == null) {
Craig Mautner69b08182012-09-05 13:07:13 -0700927 int tokenWindowsPos = 0;
928 int windowListPos = tokenWindowList.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800929 if (token.appWindowToken != null) {
Craig Mautner69b08182012-09-05 13:07:13 -0700930 int index = windowListPos - 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800931 if (index >= 0) {
932 // If this application has existing windows, we
933 // simply place the new window on top of them... but
934 // keep the starting window on top.
935 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
936 // Base windows go behind everything else.
Craig Mautner69b08182012-09-05 13:07:13 -0700937 WindowState lowestWindow = tokenWindowList.get(0);
938 placeWindowBefore(lowestWindow, win);
939 tokenWindowsPos = token.windows.indexOf(lowestWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800940 } else {
941 AppWindowToken atoken = win.mAppToken;
Craig Mautner69b08182012-09-05 13:07:13 -0700942 WindowState lastWindow = tokenWindowList.get(index);
943 if (atoken != null && lastWindow == atoken.startingWindow) {
944 placeWindowBefore(lastWindow, win);
Craig Mautnerefb735d2012-09-07 15:40:24 -0700945 tokenWindowsPos = token.windows.indexOf(lastWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800946 } else {
Craig Mautner69b08182012-09-05 13:07:13 -0700947 int newIdx = findIdxBasedOnAppTokens(win);
948 //there is a window above this one associated with the same
949 //apptoken note that the window could be a floating window
950 //that was created later or a window at the top of the list of
951 //windows associated with this token.
952 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
953 Slog.v(TAG, "Adding window " + win + " at "
Craig Mautnerefb735d2012-09-07 15:40:24 -0700954 + (newIdx + 1) + " of " + N);
Romain Guy06882f82009-06-10 13:36:04 -0700955 }
Craig Mautnerefb735d2012-09-07 15:40:24 -0700956 windows.add(newIdx + 1, win);
957 if (newIdx < 0) {
958 // No window from token found on win's display.
959 tokenWindowsPos = 0;
960 } else {
961 tokenWindowsPos = token.windows.indexOf(windows.get(newIdx)) + 1;
962 }
Craig Mautner69b08182012-09-05 13:07:13 -0700963 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800964 }
965 }
966 } else {
Craig Mautner69b08182012-09-05 13:07:13 -0700967 // No windows from this token on this display
Joe Onorato8a9b2202010-02-26 18:56:32 -0800968 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969 TAG, "Figuring out where to add app window "
970 + client.asBinder() + " (token=" + token + ")");
971 // Figure out where the window should go, based on the
972 // order of applications.
Craig Mautneref25d7a2012-05-15 23:01:47 -0700973 final int NA = mAnimatingAppTokens.size();
Jeff Browne33348b2010-07-15 23:54:05 -0700974 WindowState pos = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975 for (i=NA-1; i>=0; i--) {
Craig Mautneref25d7a2012-05-15 23:01:47 -0700976 AppWindowToken t = mAnimatingAppTokens.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800977 if (t == token) {
978 i--;
979 break;
980 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800981
Dianne Hackborna8f60182009-09-01 19:01:50 -0700982 // We haven't reached the token yet; if this token
Craig Mautner69b08182012-09-05 13:07:13 -0700983 // is not going to the bottom and has windows on this display, we can
Dianne Hackborna8f60182009-09-01 19:01:50 -0700984 // use it as an anchor for when we do reach the token.
Craig Mautner69b08182012-09-05 13:07:13 -0700985 tokenWindowList = getTokenWindowsOnDisplay(t, win.mDisplayContent);
986 if (!t.sendingToBottom && tokenWindowList.size() > 0) {
987 pos = tokenWindowList.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800988 }
989 }
990 // We now know the index into the apps. If we found
991 // an app window above, that gives us the position; else
992 // we need to look some more.
993 if (pos != null) {
994 // Move behind any windows attached to this one.
Jeff Browne33348b2010-07-15 23:54:05 -0700995 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800996 if (atoken != null) {
Craig Mautner69b08182012-09-05 13:07:13 -0700997 tokenWindowList =
998 getTokenWindowsOnDisplay(atoken, win.mDisplayContent);
999 final int NC = tokenWindowList.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000 if (NC > 0) {
Craig Mautner69b08182012-09-05 13:07:13 -07001001 WindowState bottom = tokenWindowList.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001002 if (bottom.mSubLayer < 0) {
1003 pos = bottom;
1004 }
1005 }
1006 }
1007 placeWindowBefore(pos, win);
1008 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -07001009 // Continue looking down until we find the first
Craig Mautner69b08182012-09-05 13:07:13 -07001010 // token that has windows on this display.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001011 while (i >= 0) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07001012 AppWindowToken t = mAnimatingAppTokens.get(i);
Craig Mautner69b08182012-09-05 13:07:13 -07001013 tokenWindowList = getTokenWindowsOnDisplay(t, win.mDisplayContent);
1014 final int NW = tokenWindowList.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001015 if (NW > 0) {
Craig Mautner69b08182012-09-05 13:07:13 -07001016 pos = tokenWindowList.get(NW-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001017 break;
1018 }
1019 i--;
1020 }
1021 if (pos != null) {
1022 // Move in front of any windows attached to this
1023 // one.
Jeff Browne33348b2010-07-15 23:54:05 -07001024 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001025 if (atoken != null) {
1026 final int NC = atoken.windows.size();
1027 if (NC > 0) {
1028 WindowState top = atoken.windows.get(NC-1);
1029 if (top.mSubLayer >= 0) {
1030 pos = top;
1031 }
1032 }
1033 }
1034 placeWindowAfter(pos, win);
1035 } else {
1036 // Just search for the start of this layer.
1037 final int myLayer = win.mBaseLayer;
1038 for (i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07001039 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001040 if (w.mBaseLayer > myLayer) {
1041 break;
1042 }
1043 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001044 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
1045 Slog.v(TAG, "Adding window " + win + " at "
1046 + i + " of " + N);
1047 }
Craig Mautner59c00972012-07-30 12:10:24 -07001048 windows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001049 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001050 }
1051 }
1052 }
1053 } else {
1054 // Figure out where window should go, based on layer.
1055 final int myLayer = win.mBaseLayer;
1056 for (i=N-1; i>=0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07001057 if (windows.get(i).mBaseLayer <= myLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001058 break;
1059 }
1060 }
Craig Mautner69b08182012-09-05 13:07:13 -07001061 i++;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001062 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001063 TAG, "Adding window " + win + " at "
1064 + i + " of " + N);
Craig Mautner59c00972012-07-30 12:10:24 -07001065 windows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001066 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001067 }
Craig Mautner59c00972012-07-30 12:10:24 -07001068
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001069 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001070 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001071 token.windows.add(tokenWindowsPos, win);
1072 }
1073
1074 } else {
1075 // Figure out this window's ordering relative to the window
1076 // it is attached to.
Craig Mautner69b08182012-09-05 13:07:13 -07001077 final int NA = tokenWindowList.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001078 final int sublayer = win.mSubLayer;
1079 int largestSublayer = Integer.MIN_VALUE;
1080 WindowState windowWithLargestSublayer = null;
1081 for (i=0; i<NA; i++) {
Craig Mautner69b08182012-09-05 13:07:13 -07001082 WindowState w = tokenWindowList.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001083 final int wSublayer = w.mSubLayer;
1084 if (wSublayer >= largestSublayer) {
1085 largestSublayer = wSublayer;
1086 windowWithLargestSublayer = w;
1087 }
1088 if (sublayer < 0) {
1089 // For negative sublayers, we go below all windows
1090 // in the same sublayer.
1091 if (wSublayer >= sublayer) {
1092 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001093 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001094 token.windows.add(i, win);
1095 }
Craig Mautner59c00972012-07-30 12:10:24 -07001096 placeWindowBefore(wSublayer >= 0 ? attached : w, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001097 break;
1098 }
1099 } else {
1100 // For positive sublayers, we go above all windows
1101 // in the same sublayer.
1102 if (wSublayer > sublayer) {
1103 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001104 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001105 token.windows.add(i, win);
1106 }
1107 placeWindowBefore(w, win);
1108 break;
1109 }
1110 }
1111 }
1112 if (i >= NA) {
1113 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001114 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001115 token.windows.add(win);
1116 }
1117 if (sublayer < 0) {
1118 placeWindowBefore(attached, win);
1119 } else {
1120 placeWindowAfter(largestSublayer >= 0
1121 ? windowWithLargestSublayer
1122 : attached,
1123 win);
1124 }
1125 }
1126 }
Romain Guy06882f82009-06-10 13:36:04 -07001127
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001128 if (win.mAppToken != null && addToToken) {
1129 win.mAppToken.allAppWindows.add(win);
1130 }
1131 }
Romain Guy06882f82009-06-10 13:36:04 -07001132
Craig Mautneref25d7a2012-05-15 23:01:47 -07001133 /** TODO(cmautner): Is this the same as {@link WindowState#canReceiveKeys()} */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001134 static boolean canBeImeTarget(WindowState w) {
1135 final int fl = w.mAttrs.flags
1136 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
Dianne Hackborne75d8722011-01-27 19:37:40 -08001137 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)
Craig Mautner65d11b32012-10-01 13:59:52 -07001138 || w.mAttrs.type == TYPE_APPLICATION_STARTING) {
Dianne Hackborne75d8722011-01-27 19:37:40 -08001139 if (DEBUG_INPUT_METHOD) {
1140 Slog.i(TAG, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
1141 if (!w.isVisibleOrAdding()) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07001142 Slog.i(TAG, " mSurface=" + w.mWinAnimator.mSurface
Dianne Hackborne75d8722011-01-27 19:37:40 -08001143 + " relayoutCalled=" + w.mRelayoutCalled + " viewVis=" + w.mViewVisibility
Dianne Hackbornac920872012-05-22 11:49:49 -07001144 + " policyVis=" + w.mPolicyVisibility
1145 + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim
1146 + " attachHid=" + w.mAttachedHidden
Dianne Hackborne75d8722011-01-27 19:37:40 -08001147 + " exiting=" + w.mExiting + " destroying=" + w.mDestroying);
1148 if (w.mAppToken != null) {
1149 Slog.i(TAG, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
1150 }
1151 }
1152 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001153 return w.isVisibleOrAdding();
1154 }
1155 return false;
1156 }
Romain Guy06882f82009-06-10 13:36:04 -07001157
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001158 /**
1159 * Dig through the WindowStates and find the one that the Input Method will target.
1160 * @param willMove
1161 * @return The index+1 in mWindows of the discovered target.
1162 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001163 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001164 // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
1165 // same display. Or even when the current IME/target are not on the same screen as the next
1166 // IME/target. For now only look for input windows on the main screen.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001167 WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07001168 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001169 WindowState w = null;
1170 int i = N;
1171 while (i > 0) {
1172 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07001173 w = windows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -07001174
Dianne Hackborne75d8722011-01-27 19:37:40 -08001175 if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG, "Checking window @" + i
1176 + " " + w + " fl=0x" + Integer.toHexString(w.mAttrs.flags));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001177 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001178 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -07001179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001180 // Yet more tricksyness! If this window is a "starting"
1181 // window, we do actually want to be on top of it, but
1182 // it is not -really- where input will go. So if the caller
1183 // is not actually looking to move the IME, look down below
1184 // for a real window to target...
1185 if (!willMove
Craig Mautner65d11b32012-10-01 13:59:52 -07001186 && w.mAttrs.type == TYPE_APPLICATION_STARTING
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001187 && i > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001188 WindowState wb = windows.get(i-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001189 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1190 i--;
1191 w = wb;
1192 }
1193 }
1194 break;
1195 }
1196 }
Romain Guy06882f82009-06-10 13:36:04 -07001197
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001198 // Now w is either mWindows[0] or an IME (or null if mWindows is empty).
1199
Dianne Hackborne75d8722011-01-27 19:37:40 -08001200 if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG, "Proposed new IME target: " + w);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001201
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001202 // Now, a special case -- if the last target's window is in the
1203 // process of exiting, and is above the new target, keep on the
1204 // last target to avoid flicker. Consider for example a Dialog with
1205 // the IME shown: when the Dialog is dismissed, we want to keep
1206 // the IME above it until it is completely gone so it doesn't drop
1207 // behind the dialog or its full-screen scrim.
Craig Mautner59c00972012-07-30 12:10:24 -07001208 final WindowState curTarget = mInputMethodTarget;
1209 if (curTarget != null && w != null
1210 && curTarget.isDisplayedLw()
1211 && curTarget.mExiting) {
1212 if (curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
1213 w = curTarget;
1214 i = windows.indexOf(w);
Dianne Hackborne75d8722011-01-27 19:37:40 -08001215 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Current target higher, switching to: " + w);
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001216 }
1217 }
Romain Guy06882f82009-06-10 13:36:04 -07001218
Joe Onorato8a9b2202010-02-26 18:56:32 -08001219 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001220 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -07001221
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001222 if (willMove && w != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07001223 AppWindowToken token = curTarget == null ? null : curTarget.mAppToken;
1224 if (token != null) {
Romain Guy06882f82009-06-10 13:36:04 -07001225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001226 // Now some fun for dealing with window animations that
1227 // modify the Z order. We need to look at all windows below
1228 // the current target that are in this app, finding the highest
1229 // visible one in layering.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001230 WindowState highestTarget = null;
1231 int highestPos = 0;
Craig Mautner59431632012-04-04 11:56:44 -07001232 if (token.mAppAnimator.animating || token.mAppAnimator.animation != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07001233 WindowList curWindows = curTarget.getWindowList();
1234 int pos = curWindows.indexOf(curTarget);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001235 while (pos >= 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001236 WindowState win = curWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001237 if (win.mAppToken != token) {
1238 break;
1239 }
1240 if (!win.mRemoved) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001241 if (highestTarget == null || win.mWinAnimator.mAnimLayer >
1242 highestTarget.mWinAnimator.mAnimLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001243 highestTarget = win;
1244 highestPos = pos;
1245 }
1246 }
1247 pos--;
1248 }
1249 }
Romain Guy06882f82009-06-10 13:36:04 -07001250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001251 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001252 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001253 + mNextAppTransition + " " + highestTarget
Craig Mautnera2c77052012-03-26 12:14:43 -07001254 + " animating=" + highestTarget.mWinAnimator.isAnimating()
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001255 + " layer=" + highestTarget.mWinAnimator.mAnimLayer
1256 + " new layer=" + w.mWinAnimator.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001257
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001258 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001259 // If we are currently setting up for an animation,
1260 // hold everything until we can find out what will happen.
1261 mInputMethodTargetWaitingAnim = true;
1262 mInputMethodTarget = highestTarget;
1263 return highestPos + 1;
Craig Mautnera2c77052012-03-26 12:14:43 -07001264 } else if (highestTarget.mWinAnimator.isAnimating() &&
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001265 highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001266 // If the window we are currently targeting is involved
1267 // with an animation, and it is on top of the next target
1268 // we will be over, then hold off on moving until
1269 // that is done.
Dianne Hackborne75d8722011-01-27 19:37:40 -08001270 mInputMethodTargetWaitingAnim = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001271 mInputMethodTarget = highestTarget;
1272 return highestPos + 1;
1273 }
1274 }
1275 }
1276 }
Romain Guy06882f82009-06-10 13:36:04 -07001277
Joe Onorato8a9b2202010-02-26 18:56:32 -08001278 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001279 if (w != null) {
1280 if (willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001281 if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to "
1282 + w + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001283 mInputMethodTarget = w;
Dianne Hackborne75d8722011-01-27 19:37:40 -08001284 mInputMethodTargetWaitingAnim = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001285 if (w.mAppToken != null) {
Craig Mautner59431632012-04-04 11:56:44 -07001286 setInputMethodAnimLayerAdjustment(w.mAppToken.mAppAnimator.animLayerAdjustment);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001287 } else {
1288 setInputMethodAnimLayerAdjustment(0);
1289 }
1290 }
1291 return i+1;
1292 }
1293 if (willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001294 if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to null."
1295 + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001296 mInputMethodTarget = null;
1297 setInputMethodAnimLayerAdjustment(0);
1298 }
1299 return -1;
1300 }
Romain Guy06882f82009-06-10 13:36:04 -07001301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001302 void addInputMethodWindowToListLocked(WindowState win) {
1303 int pos = findDesiredInputMethodWindowIndexLocked(true);
1304 if (pos >= 0) {
1305 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001306 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001307 TAG, "Adding input method window " + win + " at " + pos);
Craig Mautner59c00972012-07-30 12:10:24 -07001308 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001309 getDefaultWindowListLocked().add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001310 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001311 moveInputMethodDialogsLocked(pos+1);
1312 return;
1313 }
1314 win.mTargetAppToken = null;
1315 addWindowToListInOrderLocked(win, true);
1316 moveInputMethodDialogsLocked(pos);
1317 }
Romain Guy06882f82009-06-10 13:36:04 -07001318
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001319 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001320 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001321 mInputMethodAnimLayerAdjustment = adj;
1322 WindowState imw = mInputMethodWindow;
1323 if (imw != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001324 imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001325 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001326 + " anim layer: " + imw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001327 int wi = imw.mChildWindows.size();
1328 while (wi > 0) {
1329 wi--;
Jeff Browne33348b2010-07-15 23:54:05 -07001330 WindowState cw = imw.mChildWindows.get(wi);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001331 cw.mWinAnimator.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001332 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001333 + " anim layer: " + cw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001334 }
1335 }
1336 int di = mInputMethodDialogs.size();
1337 while (di > 0) {
1338 di --;
1339 imw = mInputMethodDialogs.get(di);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001340 imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001341 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001342 + " anim layer: " + imw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001343 }
1344 }
Romain Guy06882f82009-06-10 13:36:04 -07001345
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001346 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -07001347 WindowList windows = win.getWindowList();
1348 int wpos = windows.indexOf(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 if (wpos >= 0) {
1350 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001351 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
Craig Mautner59c00972012-07-30 12:10:24 -07001352 windows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001353 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001354 int NC = win.mChildWindows.size();
1355 while (NC > 0) {
1356 NC--;
Jeff Browne33348b2010-07-15 23:54:05 -07001357 WindowState cw = win.mChildWindows.get(NC);
Craig Mautner59c00972012-07-30 12:10:24 -07001358 int cpos = windows.indexOf(cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001359 if (cpos >= 0) {
1360 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001361 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001362 + cpos + ": " + cw);
Craig Mautner59c00972012-07-30 12:10:24 -07001363 windows.remove(cpos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001364 }
1365 }
1366 }
1367 return interestingPos;
1368 }
Romain Guy06882f82009-06-10 13:36:04 -07001369
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001370 private void reAddWindowToListInOrderLocked(WindowState win) {
1371 addWindowToListInOrderLocked(win, false);
1372 // This is a hack to get all of the child windows added as well
1373 // at the right position. Child windows should be rare and
1374 // this case should be rare, so it shouldn't be that big a deal.
Craig Mautner59c00972012-07-30 12:10:24 -07001375 WindowList windows = win.getWindowList();
1376 int wpos = windows.indexOf(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001377 if (wpos >= 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001378 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos + ": " + win);
1379 windows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001380 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001381 reAddWindowLocked(wpos, win);
1382 }
1383 }
Romain Guy06882f82009-06-10 13:36:04 -07001384
Craig Mautner59c00972012-07-30 12:10:24 -07001385 void logWindowList(final WindowList windows, String prefix) {
1386 int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001387 while (N > 0) {
1388 N--;
Craig Mautner59c00972012-07-30 12:10:24 -07001389 Slog.v(TAG, prefix + "#" + N + ": " + windows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390 }
1391 }
Romain Guy06882f82009-06-10 13:36:04 -07001392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001393 void moveInputMethodDialogsLocked(int pos) {
1394 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001395
Craig Mautner59c00972012-07-30 12:10:24 -07001396 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001397 WindowList windows = getDefaultWindowListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001398 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001399 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001400 for (int i=0; i<N; i++) {
1401 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1402 }
1403 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001404 Slog.v(TAG, "Window list w/pos=" + pos);
Craig Mautner59c00972012-07-30 12:10:24 -07001405 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001406 }
Romain Guy06882f82009-06-10 13:36:04 -07001407
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001408 if (pos >= 0) {
1409 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
Craig Mautner59c00972012-07-30 12:10:24 -07001410 if (pos < windows.size()) {
1411 WindowState wp = windows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001412 if (wp == mInputMethodWindow) {
1413 pos++;
1414 }
1415 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001416 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001417 for (int i=0; i<N; i++) {
1418 WindowState win = dialogs.get(i);
1419 win.mTargetAppToken = targetAppToken;
1420 pos = reAddWindowLocked(pos, win);
1421 }
1422 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001423 Slog.v(TAG, "Final window list:");
Craig Mautner59c00972012-07-30 12:10:24 -07001424 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001425 }
1426 return;
1427 }
1428 for (int i=0; i<N; i++) {
1429 WindowState win = dialogs.get(i);
1430 win.mTargetAppToken = null;
1431 reAddWindowToListInOrderLocked(win);
1432 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001433 Slog.v(TAG, "No IM target, final list:");
Craig Mautner59c00972012-07-30 12:10:24 -07001434 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001435 }
1436 }
1437 }
Romain Guy06882f82009-06-10 13:36:04 -07001438
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001439 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1440 final WindowState imWin = mInputMethodWindow;
1441 final int DN = mInputMethodDialogs.size();
1442 if (imWin == null && DN == 0) {
1443 return false;
1444 }
Romain Guy06882f82009-06-10 13:36:04 -07001445
Craig Mautner59c00972012-07-30 12:10:24 -07001446 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001447 WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07001448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001449 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1450 if (imPos >= 0) {
1451 // In this case, the input method windows are to be placed
1452 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001453
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001454 // First check to see if the input method windows are already
1455 // located here, and contiguous.
Craig Mautner59c00972012-07-30 12:10:24 -07001456 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001457 WindowState firstImWin = imPos < N
Craig Mautner59c00972012-07-30 12:10:24 -07001458 ? windows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001459
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001460 // Figure out the actual input method window that should be
1461 // at the bottom of their stack.
1462 WindowState baseImWin = imWin != null
1463 ? imWin : mInputMethodDialogs.get(0);
1464 if (baseImWin.mChildWindows.size() > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001465 WindowState cw = baseImWin.mChildWindows.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001466 if (cw.mSubLayer < 0) baseImWin = cw;
1467 }
Romain Guy06882f82009-06-10 13:36:04 -07001468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001469 if (firstImWin == baseImWin) {
1470 // The windows haven't moved... but are they still contiguous?
1471 // First find the top IM window.
1472 int pos = imPos+1;
1473 while (pos < N) {
Craig Mautner59c00972012-07-30 12:10:24 -07001474 if (!(windows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001475 break;
1476 }
1477 pos++;
1478 }
1479 pos++;
1480 // Now there should be no more input method windows above.
1481 while (pos < N) {
Craig Mautner59c00972012-07-30 12:10:24 -07001482 if ((windows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001483 break;
1484 }
1485 pos++;
1486 }
1487 if (pos >= N) {
1488 // All is good!
1489 return false;
1490 }
1491 }
Romain Guy06882f82009-06-10 13:36:04 -07001492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001493 if (imWin != null) {
1494 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001495 Slog.v(TAG, "Moving IM from " + imPos);
Craig Mautner59c00972012-07-30 12:10:24 -07001496 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001497 }
1498 imPos = tmpRemoveWindowLocked(imPos, imWin);
1499 if (DEBUG_INPUT_METHOD) {
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001500 Slog.v(TAG, "List after removing with new pos " + imPos + ":");
Craig Mautner59c00972012-07-30 12:10:24 -07001501 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001502 }
1503 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1504 reAddWindowLocked(imPos, imWin);
1505 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001506 Slog.v(TAG, "List after moving IM to " + imPos + ":");
Craig Mautner59c00972012-07-30 12:10:24 -07001507 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001508 }
1509 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1510 } else {
1511 moveInputMethodDialogsLocked(imPos);
1512 }
Romain Guy06882f82009-06-10 13:36:04 -07001513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001514 } else {
1515 // In this case, the input method windows go in a fixed layer,
1516 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001518 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001519 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520 tmpRemoveWindowLocked(0, imWin);
1521 imWin.mTargetAppToken = null;
1522 reAddWindowToListInOrderLocked(imWin);
1523 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001524 Slog.v(TAG, "List with no IM target:");
Craig Mautner59c00972012-07-30 12:10:24 -07001525 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001526 }
Craig Mautner01cd0e72012-06-18 10:19:11 -07001527 if (DN > 0) moveInputMethodDialogsLocked(-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001528 } else {
Craig Mautner01cd0e72012-06-18 10:19:11 -07001529 moveInputMethodDialogsLocked(-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001530 }
Romain Guy06882f82009-06-10 13:36:04 -07001531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001532 }
Romain Guy06882f82009-06-10 13:36:04 -07001533
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001534 if (needAssignLayers) {
Craig Mautner59c00972012-07-30 12:10:24 -07001535 assignLayersLocked(windows);
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 return true;
1539 }
Romain Guy06882f82009-06-10 13:36:04 -07001540
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001541 void adjustInputMethodDialogsLocked() {
1542 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1543 }
Romain Guy06882f82009-06-10 13:36:04 -07001544
Dianne Hackborn25994b42009-09-04 14:21:19 -07001545 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Craig Mautnerad3a9bb2012-03-09 11:31:06 -08001546 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001547 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1548 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
Craig Mautner59431632012-04-04 11:56:44 -07001549 ? wallpaperTarget.mAppToken.mAppAnimator.animation : null)
Dianne Hackborn25994b42009-09-04 14:21:19 -07001550 + " upper=" + mUpperWallpaperTarget
1551 + " lower=" + mLowerWallpaperTarget);
1552 return (wallpaperTarget != null
1553 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
Craig Mautner59431632012-04-04 11:56:44 -07001554 && wallpaperTarget.mAppToken.mAppAnimator.animation != null)))
Dianne Hackborn25994b42009-09-04 14:21:19 -07001555 || mUpperWallpaperTarget != null
1556 || mLowerWallpaperTarget != null;
1557 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001558
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001559 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1560 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001561
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001562 int adjustWallpaperWindowsLocked() {
Craig Mautnera608b882012-03-30 13:03:49 -07001563 mInnerFields.mWallpaperMayChange = false;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001564 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001565
Craig Mautner59c00972012-07-30 12:10:24 -07001566 // TODO(multidisplay): Wallpapers on main screen only.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001567 final DisplayInfo displayInfo = getDefaultDisplayContentLocked().getDisplayInfo();
Craig Mautner59c00972012-07-30 12:10:24 -07001568 final int dw = displayInfo.appWidth;
1569 final int dh = displayInfo.appHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001570
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001571 // First find top-most window that has asked to be on top of the
1572 // wallpaper; all wallpapers go behind it.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001573 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07001574 int N = windows.size();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001575 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001576 WindowState foundW = null;
1577 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001578 WindowState topCurW = null;
1579 int topCurI = 0;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001580 int windowDetachedI = -1;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001581 int i = N;
1582 while (i > 0) {
1583 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07001584 w = windows.get(i);
Craig Mautner65d11b32012-10-01 13:59:52 -07001585 if ((w.mAttrs.type == TYPE_WALLPAPER)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001586 if (topCurW == null) {
1587 topCurW = w;
1588 topCurI = i;
1589 }
1590 continue;
1591 }
1592 topCurW = null;
Craig Mautner01cd0e72012-06-18 10:19:11 -07001593 if (w != mWindowDetachedWallpaper && w.mAppToken != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001594 // If this window's app token is hidden and not animating,
1595 // it is of no interest to us.
Craig Mautner59431632012-04-04 11:56:44 -07001596 if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001597 if (DEBUG_WALLPAPER) Slog.v(TAG,
Craig Mautner1d961d42012-05-27 12:02:11 -07001598 "Skipping hidden and not animating token: " + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001599 continue;
1600 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001601 }
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001602 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win #" + i + " " + w + ": readyfordisplay="
Craig Mautner749a7bb2012-04-02 13:49:53 -07001603 + w.isReadyForDisplay() + " mDrawState=" + w.mWinAnimator.mDrawState);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001604 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07001605 && (mWallpaperTarget == w || w.isDrawnLw())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001606 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001607 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001608 foundW = w;
1609 foundI = i;
Craig Mautner4d7349b2012-04-20 14:52:47 -07001610 if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001611 // The current wallpaper target is animating, so we'll
1612 // look behind it for another possible target and figure
1613 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001614 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001615 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001616 continue;
1617 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001618 break;
Craig Mautner01cd0e72012-06-18 10:19:11 -07001619 } else if (w == mWindowDetachedWallpaper) {
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001620 windowDetachedI = i;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001621 }
1622 }
1623
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001624 if (foundW == null && windowDetachedI >= 0) {
1625 if (DEBUG_WALLPAPER) Slog.v(TAG,
1626 "Found animating detached wallpaper activity: #" + i + "=" + w);
1627 foundW = w;
1628 foundI = windowDetachedI;
1629 }
1630
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001631 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001632 // If we are currently waiting for an app transition, and either
1633 // the current target or the next target are involved with it,
1634 // then hold off on doing anything with the wallpaper.
1635 // Note that we are checking here for just whether the target
1636 // is part of an app token... which is potentially overly aggressive
1637 // (the app token may not be involved in the transition), but good
1638 // enough (we'll just wait until whatever transition is pending
1639 // executes).
1640 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001641 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001642 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001643 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001644 }
1645 if (foundW != null && foundW.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001646 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001647 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001648 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001649 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001650 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001651
Craig Mautner8863cca2012-09-18 15:04:34 -07001652 if (mWallpaperTarget != foundW
1653 && (mLowerWallpaperTarget == null || mLowerWallpaperTarget != foundW)) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001654 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001655 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001656 + " oldTarget: " + mWallpaperTarget);
1657 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001658
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001659 mLowerWallpaperTarget = null;
1660 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001661
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001662 WindowState oldW = mWallpaperTarget;
1663 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001664
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001665 // Now what is happening... if the current and new targets are
1666 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001667 if (foundW != null && oldW != null) {
Craig Mautnera2c77052012-03-26 12:14:43 -07001668 boolean oldAnim = oldW.mWinAnimator.mAnimation != null
Craig Mautner59431632012-04-04 11:56:44 -07001669 || (oldW.mAppToken != null
1670 && oldW.mAppToken.mAppAnimator.animation != null);
Craig Mautnera2c77052012-03-26 12:14:43 -07001671 boolean foundAnim = foundW.mWinAnimator.mAnimation != null
Craig Mautner59431632012-04-04 11:56:44 -07001672 || (foundW.mAppToken != null &&
1673 foundW.mAppToken.mAppAnimator.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001674 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001675 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001676 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001677 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001678 if (foundAnim && oldAnim) {
Craig Mautner59c00972012-07-30 12:10:24 -07001679 int oldI = windows.indexOf(oldW);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001680 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001681 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001682 }
1683 if (oldI >= 0) {
1684 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001685 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001686 + "=" + oldW + "; new#" + foundI
1687 + "=" + foundW);
1688 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001689
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001690 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001691 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001692 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001693 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001694 }
1695 mWallpaperTarget = oldW;
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001696 foundW = oldW;
1697 foundI = oldI;
Craig Mautner711f90a2012-07-03 18:43:52 -07001698 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001699 // Now set the upper and lower wallpaper targets
1700 // correctly, and make sure that we are positioning
1701 // the wallpaper below the lower.
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001702 else if (foundI > oldI) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001703 // The new target is on top of the old one.
1704 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001705 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001706 }
1707 mUpperWallpaperTarget = foundW;
1708 mLowerWallpaperTarget = oldW;
1709 foundW = oldW;
1710 foundI = oldI;
1711 } else {
1712 // The new target is below the old one.
1713 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001714 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001715 }
1716 mUpperWallpaperTarget = oldW;
1717 mLowerWallpaperTarget = foundW;
1718 }
1719 }
1720 }
1721 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001722
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001723 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001724 // Is it time to stop animating?
Craig Mautnera2c77052012-03-26 12:14:43 -07001725 boolean lowerAnimating = mLowerWallpaperTarget.mWinAnimator.mAnimation != null
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001726 || (mLowerWallpaperTarget.mAppToken != null
Craig Mautner59431632012-04-04 11:56:44 -07001727 && mLowerWallpaperTarget.mAppToken.mAppAnimator.animation != null);
Craig Mautnera2c77052012-03-26 12:14:43 -07001728 boolean upperAnimating = mUpperWallpaperTarget.mWinAnimator.mAnimation != null
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001729 || (mUpperWallpaperTarget.mAppToken != null
Craig Mautner59431632012-04-04 11:56:44 -07001730 && mUpperWallpaperTarget.mAppToken.mAppAnimator.animation != null);
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001731 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001732 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001733 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001734 }
1735 mLowerWallpaperTarget = null;
1736 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001737 }
1738 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001739
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001740 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001741 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001742 // The window is visible to the compositor... but is it visible
1743 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001744 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001745 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001746
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001747 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001748 // its layer adjustment. Only do this if we are not transfering
1749 // between two wallpaper targets.
1750 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001751 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Craig Mautner59431632012-04-04 11:56:44 -07001752 ? foundW.mAppToken.mAppAnimator.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001753
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001754 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1755 * TYPE_LAYER_MULTIPLIER
1756 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001757
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001758 // Now w is the window we are supposed to be behind... but we
1759 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001760 // AND any starting window associated with it, AND below the
1761 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001762 while (foundI > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001763 WindowState wb = windows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001764 if (wb.mBaseLayer < maxLayer &&
1765 wb.mAttachedWindow != foundW &&
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001766 (foundW.mAttachedWindow == null ||
1767 wb.mAttachedWindow != foundW.mAttachedWindow) &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001768 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001769 foundW.mToken == null || wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001770 // This window is not related to the previous one in any
1771 // interesting way, so stop here.
1772 break;
1773 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001774 foundW = wb;
1775 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001776 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001777 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001778 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001779 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001780
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001781 if (foundW == null && topCurW != null) {
1782 // There is no wallpaper target, so it goes at the bottom.
1783 // We will assume it is the same place as last time, if known.
1784 foundW = topCurW;
1785 foundI = topCurI+1;
1786 } else {
1787 // Okay i is the position immediately above the wallpaper. Look at
1788 // what is below it for later.
Craig Mautner59c00972012-07-30 12:10:24 -07001789 foundW = foundI > 0 ? windows.get(foundI-1) : null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001790 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001791
Dianne Hackborn284ac932009-08-28 10:34:25 -07001792 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001793 if (mWallpaperTarget.mWallpaperX >= 0) {
1794 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001795 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001796 }
1797 if (mWallpaperTarget.mWallpaperY >= 0) {
1798 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001799 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001800 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001801 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001802
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001803 // Start stepping backwards from here, ensuring that our wallpaper windows
1804 // are correctly placed.
1805 int curTokenIndex = mWallpaperTokens.size();
1806 while (curTokenIndex > 0) {
1807 curTokenIndex--;
1808 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001809 if (token.hidden == visible) {
1810 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1811 token.hidden = !visible;
1812 // Need to do a layout to ensure the wallpaper now has the
1813 // correct size.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001814 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001815 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001816
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001817 int curWallpaperIndex = token.windows.size();
1818 while (curWallpaperIndex > 0) {
1819 curWallpaperIndex--;
1820 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001821
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001822 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001823 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001824 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001825
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001826 // First, make sure the client has the current visibility
1827 // state.
Craig Mautner507a2ee2012-06-13 08:39:38 -07001828 dispatchWallpaperVisibility(wallpaper, visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001829
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001830 wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Craig Mautneref25d7a2012-05-15 23:01:47 -07001831 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "adjustWallpaper win "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001832 + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001833
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001834 // First, if this window is at the current index, then all
1835 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001836 if (wallpaper == foundW) {
1837 foundI--;
1838 foundW = foundI > 0
Craig Mautner59c00972012-07-30 12:10:24 -07001839 ? windows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001840 continue;
1841 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001842
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001843 // The window didn't match... the current wallpaper window,
1844 // wherever it is, is in the wrong place, so make sure it is
1845 // not in the list.
Craig Mautner59c00972012-07-30 12:10:24 -07001846 int oldIndex = windows.indexOf(wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001847 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001848 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001849 + oldIndex + ": " + wallpaper);
Craig Mautner59c00972012-07-30 12:10:24 -07001850 windows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001851 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001852 if (oldIndex < foundI) {
1853 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001854 }
1855 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001856
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001857 // Now stick it in.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001858 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
1859 Slog.v(TAG, "Moving wallpaper " + wallpaper
1860 + " from " + oldIndex + " to " + foundI);
1861 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001862
Craig Mautner59c00972012-07-30 12:10:24 -07001863 windows.add(foundI, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001864 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001865 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001866 }
1867 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001868
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001869 return changed;
1870 }
1871
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001872 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001873 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001874 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001875 mWallpaperAnimLayerAdjustment = adj;
1876 int curTokenIndex = mWallpaperTokens.size();
1877 while (curTokenIndex > 0) {
1878 curTokenIndex--;
1879 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1880 int curWallpaperIndex = token.windows.size();
1881 while (curWallpaperIndex > 0) {
1882 curWallpaperIndex--;
1883 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001884 wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + adj;
Craig Mautneref25d7a2012-05-15 23:01:47 -07001885 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "setWallpaper win "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001886 + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001887 }
1888 }
1889 }
1890
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001891 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
1892 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001893 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001894 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001895 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001896 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackbornffb3d932011-05-17 17:44:51 -07001897 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001898 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
1899 changed = wallpaperWin.mXOffset != offset;
1900 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001901 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001902 + wallpaperWin + " x: " + offset);
1903 wallpaperWin.mXOffset = offset;
1904 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001905 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001906 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001907 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001908 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001909 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001910
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001911 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001912 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001913 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1914 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1915 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001916 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001917 + wallpaperWin + " y: " + offset);
1918 changed = true;
1919 wallpaperWin.mYOffset = offset;
1920 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001921 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001922 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001923 wallpaperWin.mWallpaperYStep = wpys;
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
Craig Mautnerbb1449b2012-03-23 16:11:14 -07001927 if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
Chet Haasea8e5a2b2011-10-28 13:18:16 -07001928 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001929 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001930 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001931 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
1932 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001933 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001934 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001935 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001936 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001937 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
1938 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001939 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001940 if (mWaitingOnWallpaper != null) {
1941 long start = SystemClock.uptimeMillis();
1942 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
1943 < start) {
1944 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001945 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07001946 "Waiting for offset complete...");
1947 mWindowMap.wait(WALLPAPER_TIMEOUT);
1948 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001949 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001950 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07001951 if ((start+WALLPAPER_TIMEOUT)
1952 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001953 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07001954 + wallpaperWin);
1955 mLastWallpaperTimeoutTime = start;
1956 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001957 }
Dianne Hackborn75804932009-10-20 20:15:20 -07001958 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001959 }
1960 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001961 } catch (RemoteException e) {
1962 }
1963 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001964
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001965 return changed;
1966 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001967
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001968 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001969 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001970 if (mWaitingOnWallpaper != null &&
1971 mWaitingOnWallpaper.mClient.asBinder() == window) {
1972 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07001973 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001974 }
1975 }
1976 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001977
Chet Haasea8e5a2b2011-10-28 13:18:16 -07001978 void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Craig Mautner59c00972012-07-30 12:10:24 -07001979 final DisplayContent displayContent = changingTarget.mDisplayContent;
1980 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
1981 final int dw = displayInfo.appWidth;
1982 final int dh = displayInfo.appHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001983
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001984 WindowState target = mWallpaperTarget;
1985 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001986 if (target.mWallpaperX >= 0) {
1987 mLastWallpaperX = target.mWallpaperX;
1988 } else if (changingTarget.mWallpaperX >= 0) {
1989 mLastWallpaperX = changingTarget.mWallpaperX;
1990 }
1991 if (target.mWallpaperY >= 0) {
1992 mLastWallpaperY = target.mWallpaperY;
1993 } else if (changingTarget.mWallpaperY >= 0) {
1994 mLastWallpaperY = changingTarget.mWallpaperY;
1995 }
1996 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001997
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001998 int curTokenIndex = mWallpaperTokens.size();
1999 while (curTokenIndex > 0) {
2000 curTokenIndex--;
2001 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2002 int curWallpaperIndex = token.windows.size();
2003 while (curWallpaperIndex > 0) {
2004 curWallpaperIndex--;
2005 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2006 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002007 WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
2008 winAnimator.computeShownFrameLocked();
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002009 // No need to lay out the windows - we can just set the wallpaper position
2010 // directly.
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07002011 // TODO(cmautner): Don't move this from here, just lock the WindowAnimator.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002012 if (winAnimator.mSurfaceX != wallpaper.mShownFrame.left
2013 || winAnimator.mSurfaceY != wallpaper.mShownFrame.top) {
Craig Mautner12670b52012-07-03 19:15:35 -07002014 winAnimator.setWallpaperOffset((int) wallpaper.mShownFrame.left,
Craig Mautner48ba1e72012-04-02 13:18:16 -07002015 (int) wallpaper.mShownFrame.top);
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002016 }
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002017 // We only want to be synchronous with one wallpaper.
2018 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002019 }
2020 }
2021 }
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002022 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002023
Craig Mautner507a2ee2012-06-13 08:39:38 -07002024 /**
2025 * Check wallpaper for visiblity change and notify window if so.
2026 * @param wallpaper The wallpaper to test and notify.
2027 * @param visible Current visibility.
2028 */
2029 void dispatchWallpaperVisibility(final WindowState wallpaper, final boolean visible) {
2030 if (wallpaper.mWallpaperVisible != visible) {
2031 wallpaper.mWallpaperVisible = visible;
2032 try {
2033 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
2034 "Updating visibility of wallpaper " + wallpaper
2035 + ": " + visible + " Callers=" + Debug.getCallers(2));
2036 wallpaper.mClient.dispatchAppVisibility(visible);
2037 } catch (RemoteException e) {
2038 }
2039 }
2040 }
2041
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002042 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07002043 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Craig Mautner59c00972012-07-30 12:10:24 -07002044 final DisplayContent displayContent = mWallpaperTarget.mDisplayContent;
2045 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
2046 final int dw = displayInfo.appWidth;
2047 final int dh = displayInfo.appHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002048
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002049 int curTokenIndex = mWallpaperTokens.size();
2050 while (curTokenIndex > 0) {
2051 curTokenIndex--;
2052 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002053 if (token.hidden == visible) {
2054 token.hidden = !visible;
2055 // Need to do a layout to ensure the wallpaper now has the
2056 // correct size.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07002057 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002058 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002059
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002060 int curWallpaperIndex = token.windows.size();
2061 while (curWallpaperIndex > 0) {
2062 curWallpaperIndex--;
2063 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2064 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002065 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002066 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002067
Craig Mautner507a2ee2012-06-13 08:39:38 -07002068 dispatchWallpaperVisibility(wallpaper, visible);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002069 }
2070 }
2071 }
Craig Mautner711f90a2012-07-03 18:43:52 -07002072
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002073 public int addWindow(Session session, IWindow client, int seq,
Craig Mautner6881a102012-07-27 13:04:51 -07002074 WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002075 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002076 int res = mPolicy.checkAddPermission(attrs);
Jeff Brown98365d72012-08-19 20:30:52 -07002077 if (res != WindowManagerGlobal.ADD_OKAY) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002078 return res;
2079 }
Romain Guy06882f82009-06-10 13:36:04 -07002080
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002081 boolean reportNewConfig = false;
2082 WindowState attachedWindow = null;
2083 WindowState win = null;
Dianne Hackborn5132b372010-07-29 12:51:35 -07002084 long origId;
Romain Guy06882f82009-06-10 13:36:04 -07002085
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002086 synchronized(mWindowMap) {
Jeff Browne215f262012-09-10 16:01:14 -07002087 if (!mDisplayReady) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07002088 throw new IllegalStateException("Display has not been initialialized");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002089 }
Romain Guy06882f82009-06-10 13:36:04 -07002090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002091 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002092 Slog.w(TAG, "Window " + client + " is already added");
Jeff Brown98365d72012-08-19 20:30:52 -07002093 return WindowManagerGlobal.ADD_DUPLICATE_ADD;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002094 }
2095
2096 if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002097 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002098 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002099 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002100 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002101 return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002102 }
2103 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
2104 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002105 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002106 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002107 return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002108 }
2109 }
2110
2111 boolean addToken = false;
2112 WindowToken token = mTokenMap.get(attrs.token);
2113 if (token == null) {
2114 if (attrs.type >= FIRST_APPLICATION_WINDOW
2115 && attrs.type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002116 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002117 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002118 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002119 }
2120 if (attrs.type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002121 Slog.w(TAG, "Attempted to add input method window with unknown token "
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_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002124 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002125 if (attrs.type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002126 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002127 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002128 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002129 }
Daniel Sandler7d276c32012-01-30 14:33:52 -05002130 if (attrs.type == TYPE_DREAM) {
2131 Slog.w(TAG, "Attempted to add Dream window with unknown token "
2132 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002133 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Daniel Sandler7d276c32012-01-30 14:33:52 -05002134 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002135 token = new WindowToken(this, attrs.token, -1, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002136 addToken = true;
2137 } else if (attrs.type >= FIRST_APPLICATION_WINDOW
2138 && attrs.type <= LAST_APPLICATION_WINDOW) {
2139 AppWindowToken atoken = token.appWindowToken;
2140 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002141 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002142 + token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002143 return WindowManagerGlobal.ADD_NOT_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002144 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002145 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002146 + token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002147 return WindowManagerGlobal.ADD_APP_EXITING;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002148 }
2149 if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
2150 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002151 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002152 TAG, "**** NO NEED TO START: " + attrs.getTitle());
Jeff Brown98365d72012-08-19 20:30:52 -07002153 return WindowManagerGlobal.ADD_STARTING_NOT_NEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002154 }
2155 } else if (attrs.type == TYPE_INPUT_METHOD) {
2156 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002157 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002158 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002159 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002160 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002161 } else if (attrs.type == TYPE_WALLPAPER) {
2162 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002163 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002164 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002165 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002166 }
Daniel Sandler7d276c32012-01-30 14:33:52 -05002167 } else if (attrs.type == TYPE_DREAM) {
2168 if (token.windowType != TYPE_DREAM) {
2169 Slog.w(TAG, "Attempted to add Dream window with bad token "
2170 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002171 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Daniel Sandler7d276c32012-01-30 14:33:52 -05002172 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002173 }
2174
Craig Mautner5c0e78c2012-09-12 16:45:36 -07002175 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002176 win = new WindowState(this, session, client, token,
Craig Mautner59c00972012-07-30 12:10:24 -07002177 attachedWindow, seq, attrs, viewVisibility, displayContent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002178 if (win.mDeathRecipient == null) {
2179 // Client has apparently died, so there is no reason to
2180 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002181 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002182 + " that is dead, aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002183 return WindowManagerGlobal.ADD_APP_EXITING;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002184 }
2185
2186 mPolicy.adjustWindowParamsLw(win.mAttrs);
Romain Guy06882f82009-06-10 13:36:04 -07002187
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002188 res = mPolicy.prepareAddWindowLw(win, attrs);
Jeff Brown98365d72012-08-19 20:30:52 -07002189 if (res != WindowManagerGlobal.ADD_OKAY) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002190 return res;
2191 }
Craig Mautner918b53b2012-07-09 14:15:54 -07002192
Jeff Browncc4f7db2011-08-30 20:34:48 -07002193 if (outInputChannel != null && (attrs.inputFeatures
2194 & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002195 String name = win.makeInputChannelName();
2196 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
Jeff Browncc4f7db2011-08-30 20:34:48 -07002197 win.setInputChannel(inputChannels[0]);
Jeff Brown0a0ab122011-08-12 18:08:08 -07002198 inputChannels[1].transferTo(outInputChannel);
Craig Mautner918b53b2012-07-09 14:15:54 -07002199
Jeff Brown928e0542011-01-10 11:17:36 -08002200 mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002201 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002202
2203 // From now on, no exceptions or errors allowed!
2204
Jeff Brown98365d72012-08-19 20:30:52 -07002205 res = WindowManagerGlobal.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002206
Dianne Hackborn5132b372010-07-29 12:51:35 -07002207 origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002209 if (addToken) {
2210 mTokenMap.put(attrs.token, token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002211 }
2212 win.attach();
2213 mWindowMap.put(client.asBinder(), win);
2214
2215 if (attrs.type == TYPE_APPLICATION_STARTING &&
2216 token.appWindowToken != null) {
2217 token.appWindowToken.startingWindow = win;
Craig Mautner38b24782012-07-02 16:21:28 -07002218 if (DEBUG_STARTING_WINDOW) Slog.v (TAG, "addWindow: " + token.appWindowToken
2219 + " startingWindow=" + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002220 }
2221
2222 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002224 if (attrs.type == TYPE_INPUT_METHOD) {
satok1bc0a492012-04-25 22:47:12 +09002225 win.mGivenInsetsPending = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002226 mInputMethodWindow = win;
2227 addInputMethodWindowToListLocked(win);
2228 imMayMove = false;
2229 } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
2230 mInputMethodDialogs.add(win);
2231 addWindowToListInOrderLocked(win, true);
2232 adjustInputMethodDialogsLocked();
2233 imMayMove = false;
2234 } else {
2235 addWindowToListInOrderLocked(win, true);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002236 if (attrs.type == TYPE_WALLPAPER) {
2237 mLastWallpaperTimeoutTime = 0;
2238 adjustWallpaperWindowsLocked();
2239 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002240 adjustWallpaperWindowsLocked();
2241 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002242 }
Romain Guy06882f82009-06-10 13:36:04 -07002243
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002244 win.mWinAnimator.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002245
Craig Mautner69b08182012-09-05 13:07:13 -07002246 if (displayContent.isDefaultDisplay) {
2247 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
2248 } else {
2249 outContentInsets.setEmpty();
2250 }
Romain Guy06882f82009-06-10 13:36:04 -07002251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002252 if (mInTouchMode) {
Jeff Brown98365d72012-08-19 20:30:52 -07002253 res |= WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002254 }
Craig Mautner764983d2012-03-22 11:37:36 -07002255 if (win.mAppToken == null || !win.mAppToken.clientHidden) {
Jeff Brown98365d72012-08-19 20:30:52 -07002256 res |= WindowManagerGlobal.ADD_FLAG_APP_VISIBLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002257 }
Romain Guy06882f82009-06-10 13:36:04 -07002258
Jeff Brown2e44b072011-01-24 15:21:56 -08002259 mInputMonitor.setUpdateInputWindowsNeededLw();
2260
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002261 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002262 if (win.canReceiveKeys()) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002263 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
2264 false /*updateInputWindows*/);
Jeff Brown349703e2010-06-22 01:27:15 -07002265 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002266 imMayMove = false;
2267 }
2268 }
Romain Guy06882f82009-06-10 13:36:04 -07002269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002270 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002271 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002272 }
Romain Guy06882f82009-06-10 13:36:04 -07002273
Craig Mautner59c00972012-07-30 12:10:24 -07002274 assignLayersLocked(displayContent.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002275 // Don't do layout here, the window must call
2276 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002278 //dump();
2279
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002280 if (focusChanged) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002281 finishUpdateFocusedWindowAfterAssignLayersLocked(false /*updateInputWindows*/);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002282 }
Jeff Brown2e44b072011-01-24 15:21:56 -08002283 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08002284
Joe Onorato8a9b2202010-02-26 18:56:32 -08002285 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002286 TAG, "New client " + client.asBinder()
2287 + ": window=" + win);
Craig Mautner9e809442012-06-22 17:13:04 -07002288
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002289 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002290 reportNewConfig = true;
2291 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002292 }
2293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002294 if (reportNewConfig) {
2295 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002296 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07002297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002298 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002300 return res;
2301 }
Romain Guy06882f82009-06-10 13:36:04 -07002302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002303 public void removeWindow(Session session, IWindow client) {
2304 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002305 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002306 if (win == null) {
2307 return;
2308 }
2309 removeWindowLocked(session, win);
2310 }
2311 }
Romain Guy06882f82009-06-10 13:36:04 -07002312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002313 public void removeWindowLocked(Session session, WindowState win) {
2314
Joe Onorato8a9b2202010-02-26 18:56:32 -08002315 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002316 TAG, "Remove " + win + " client="
2317 + Integer.toHexString(System.identityHashCode(
2318 win.mClient.asBinder()))
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002319 + ", surface=" + win.mWinAnimator.mSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002320
2321 final long origId = Binder.clearCallingIdentity();
Craig Mautner764983d2012-03-22 11:37:36 -07002322
Jeff Brownc5ed5912010-07-14 18:48:53 -07002323 win.disposeInputChannel();
Romain Guy06882f82009-06-10 13:36:04 -07002324
Joe Onorato8a9b2202010-02-26 18:56:32 -08002325 if (DEBUG_APP_TRANSITIONS) Slog.v(
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002326 TAG, "Remove " + win + ": mSurface=" + win.mWinAnimator.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002327 + " mExiting=" + win.mExiting
Craig Mautnera2c77052012-03-26 12:14:43 -07002328 + " isAnimating=" + win.mWinAnimator.isAnimating()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002329 + " app-animation="
Craig Mautner59431632012-04-04 11:56:44 -07002330 + (win.mAppToken != null ? win.mAppToken.mAppAnimator.animation : null)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002331 + " inPendingTransaction="
2332 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2333 + " mDisplayFrozen=" + mDisplayFrozen);
2334 // Visibility of the removed window. Will be used later to update orientation later on.
2335 boolean wasVisible = false;
2336 // First, see if we need to run an animation. If we do, we have
2337 // to hold off on removing the window until the animation is done.
2338 // If the display is frozen, just remove immediately, since the
2339 // animation wouldn't be seen.
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002340 if (win.mHasSurface && okToDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002341 // If we are not currently running the exit animation, we
2342 // need to see about starting one.
Craig Mautner764983d2012-03-22 11:37:36 -07002343 wasVisible = win.isWinVisibleLw();
2344 if (wasVisible) {
Romain Guy06882f82009-06-10 13:36:04 -07002345
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002346 int transit = WindowManagerPolicy.TRANSIT_EXIT;
Craig Mautnerbb1449b2012-03-23 16:11:14 -07002347 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002348 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2349 }
2350 // Try starting an animation.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002351 if (win.mWinAnimator.applyAnimationLocked(transit, false)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002352 win.mExiting = true;
2353 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002354 scheduleNotifyWindowTranstionIfNeededLocked(win, transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002355 }
Craig Mautnera2c77052012-03-26 12:14:43 -07002356 if (win.mExiting || win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002357 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002358 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002359 win.mExiting = true;
2360 win.mRemoveOnExit = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07002361 win.mDisplayContent.layoutNeeded = true;
Jeff Brown3a22cd92011-01-21 13:59:04 -08002362 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2363 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002364 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08002365 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002366 if (win.mAppToken != null) {
2367 win.mAppToken.updateReportedVisibilityLocked();
2368 }
2369 //dump();
2370 Binder.restoreCallingIdentity(origId);
2371 return;
2372 }
2373 }
2374
2375 removeWindowInnerLocked(session, win);
2376 // Removing a visible window will effect the computed orientation
2377 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002378 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002379 != mForcedAppOrientation
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002380 && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002381 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002382 }
Jeff Brown3a22cd92011-01-21 13:59:04 -08002383 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002384 Binder.restoreCallingIdentity(origId);
2385 }
Romain Guy06882f82009-06-10 13:36:04 -07002386
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002387 private void removeWindowInnerLocked(Session session, WindowState win) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002388 if (win.mRemoved) {
2389 // Nothing to do.
2390 return;
2391 }
2392
2393 for (int i=win.mChildWindows.size()-1; i>=0; i--) {
2394 WindowState cwin = win.mChildWindows.get(i);
2395 Slog.w(TAG, "Force-removing child win " + cwin + " from container "
2396 + win);
2397 removeWindowInnerLocked(cwin.mSession, cwin);
2398 }
2399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002400 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002402 if (mInputMethodTarget == win) {
2403 moveInputMethodWindowsIfNeededLocked(false);
2404 }
Romain Guy06882f82009-06-10 13:36:04 -07002405
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002406 if (false) {
2407 RuntimeException e = new RuntimeException("here");
2408 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002409 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002410 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002411
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002412 mPolicy.removeWindowLw(win);
2413 win.removeLocked();
2414
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002415 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002416 mWindowMap.remove(win.mClient.asBinder());
Craig Mautner59c00972012-07-30 12:10:24 -07002417
2418 final WindowList windows = win.getWindowList();
2419 windows.remove(win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002420 mPendingRemove.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002421 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002422 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002423
2424 if (mInputMethodWindow == win) {
2425 mInputMethodWindow = null;
2426 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2427 mInputMethodDialogs.remove(win);
2428 }
Romain Guy06882f82009-06-10 13:36:04 -07002429
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002430 final WindowToken token = win.mToken;
2431 final AppWindowToken atoken = win.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002432 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + win + " from " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002433 token.windows.remove(win);
2434 if (atoken != null) {
2435 atoken.allAppWindows.remove(win);
2436 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002437 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002438 TAG, "**** Removing window " + win + ": count="
2439 + token.windows.size());
2440 if (token.windows.size() == 0) {
2441 if (!token.explicit) {
2442 mTokenMap.remove(token.token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002443 } else if (atoken != null) {
2444 atoken.firstWindowDrawn = false;
2445 }
2446 }
2447
2448 if (atoken != null) {
2449 if (atoken.startingWindow == win) {
Craig Mautner38b24782012-07-02 16:21:28 -07002450 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling startingWindow " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002451 atoken.startingWindow = null;
2452 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2453 // If this is the last window and we had requested a starting
2454 // transition window, well there is no point now.
Craig Mautner38b24782012-07-02 16:21:28 -07002455 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling last startingWindow");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002456 atoken.startingData = null;
2457 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2458 // If this is the last window except for a starting transition
2459 // window, we need to get rid of the starting transition.
2460 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002461 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002462 + ": no more real windows");
2463 }
2464 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2465 mH.sendMessage(m);
2466 }
2467 }
Romain Guy06882f82009-06-10 13:36:04 -07002468
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002469 if (win.mAttrs.type == TYPE_WALLPAPER) {
2470 mLastWallpaperTimeoutTime = 0;
2471 adjustWallpaperWindowsLocked();
2472 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002473 adjustWallpaperWindowsLocked();
2474 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002476 if (!mInLayout) {
Craig Mautner59c00972012-07-30 12:10:24 -07002477 assignLayersLocked(windows);
Craig Mautner19d59bc2012-09-04 11:15:56 -07002478 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002479 performLayoutAndPlaceSurfacesLocked();
2480 if (win.mAppToken != null) {
2481 win.mAppToken.updateReportedVisibilityLocked();
2482 }
2483 }
Craig Mautner9e809442012-06-22 17:13:04 -07002484
Jeff Brown2e44b072011-01-24 15:21:56 -08002485 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002486 }
2487
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002488 static void logSurface(WindowState w, String msg, RuntimeException where) {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002489 String str = " SURFACE " + msg + ": " + w;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002490 if (where != null) {
2491 Slog.i(TAG, str, where);
2492 } else {
2493 Slog.i(TAG, str);
2494 }
2495 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002496
2497 static void logSurface(Surface s, String title, String msg, RuntimeException where) {
2498 String str = " SURFACE " + s + ": " + msg + " / " + title;
2499 if (where != null) {
2500 Slog.i(TAG, str, where);
2501 } else {
2502 Slog.i(TAG, str);
2503 }
2504 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07002505
2506 // TODO(cmautner): Move to WindowStateAnimator.
2507 void setTransparentRegionHint(final WindowStateAnimator winAnimator, final Region region) {
2508 mH.sendMessage(mH.obtainMessage(H.SET_TRANSPARENT_REGION,
2509 new Pair<WindowStateAnimator, Region>(winAnimator, region)));
2510 }
2511
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002512 void setTransparentRegionWindow(Session session, IWindow client, Region region) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002513 long origId = Binder.clearCallingIdentity();
2514 try {
2515 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002516 WindowState w = windowForClientLocked(session, client, false);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002517 if ((w != null) && w.mHasSurface) {
Craig Mautner48ba1e72012-04-02 13:18:16 -07002518 setTransparentRegionHint(w.mWinAnimator, region);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002519 }
2520 }
2521 } finally {
2522 Binder.restoreCallingIdentity(origId);
2523 }
2524 }
2525
2526 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002527 int touchableInsets, Rect contentInsets,
Jeff Brownfbf09772011-01-16 14:06:57 -08002528 Rect visibleInsets, Region touchableRegion) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002529 long origId = Binder.clearCallingIdentity();
2530 try {
2531 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002532 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002533 if (w != null) {
2534 w.mGivenInsetsPending = false;
2535 w.mGivenContentInsets.set(contentInsets);
2536 w.mGivenVisibleInsets.set(visibleInsets);
Jeff Brownfbf09772011-01-16 14:06:57 -08002537 w.mGivenTouchableRegion.set(touchableRegion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002538 w.mTouchableInsets = touchableInsets;
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002539 if (w.mGlobalScale != 1) {
2540 w.mGivenContentInsets.scale(w.mGlobalScale);
2541 w.mGivenVisibleInsets.scale(w.mGlobalScale);
2542 w.mGivenTouchableRegion.scale(w.mGlobalScale);
2543 }
Craig Mautner19d59bc2012-09-04 11:15:56 -07002544 w.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002545 performLayoutAndPlaceSurfacesLocked();
2546 }
2547 }
2548 } finally {
2549 Binder.restoreCallingIdentity(origId);
2550 }
2551 }
Romain Guy06882f82009-06-10 13:36:04 -07002552
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002553 public void getWindowDisplayFrame(Session session, IWindow client,
2554 Rect outDisplayFrame) {
2555 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002556 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002557 if (win == null) {
2558 outDisplayFrame.setEmpty();
2559 return;
2560 }
2561 outDisplayFrame.set(win.mDisplayFrame);
2562 }
2563 }
2564
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002565 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2566 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002567 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2568 window.mWallpaperX = x;
2569 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002570 window.mWallpaperXStep = xStep;
2571 window.mWallpaperYStep = yStep;
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002572 updateWallpaperOffsetLocked(window, true);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002573 }
2574 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002575
Dianne Hackborn75804932009-10-20 20:15:20 -07002576 void wallpaperCommandComplete(IBinder window, Bundle result) {
2577 synchronized (mWindowMap) {
2578 if (mWaitingOnWallpaper != null &&
2579 mWaitingOnWallpaper.mClient.asBinder() == window) {
2580 mWaitingOnWallpaper = null;
2581 mWindowMap.notifyAll();
2582 }
2583 }
2584 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002585
Dianne Hackborn75804932009-10-20 20:15:20 -07002586 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2587 String action, int x, int y, int z, Bundle extras, boolean sync) {
2588 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2589 || window == mUpperWallpaperTarget) {
2590 boolean doWait = sync;
2591 int curTokenIndex = mWallpaperTokens.size();
2592 while (curTokenIndex > 0) {
2593 curTokenIndex--;
2594 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2595 int curWallpaperIndex = token.windows.size();
2596 while (curWallpaperIndex > 0) {
2597 curWallpaperIndex--;
2598 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2599 try {
2600 wallpaper.mClient.dispatchWallpaperCommand(action,
2601 x, y, z, extras, sync);
2602 // We only want to be synchronous with one wallpaper.
2603 sync = false;
2604 } catch (RemoteException e) {
2605 }
2606 }
2607 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002608
Dianne Hackborn75804932009-10-20 20:15:20 -07002609 if (doWait) {
2610 // XXX Need to wait for result.
2611 }
2612 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002613
Dianne Hackborn75804932009-10-20 20:15:20 -07002614 return null;
2615 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002616
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002617 public void setUniverseTransformLocked(WindowState window, float alpha,
2618 float offx, float offy, float dsdx, float dtdx, float dsdy, float dtdy) {
2619 Transformation transform = window.mWinAnimator.mUniverseTransform;
2620 transform.setAlpha(alpha);
2621 Matrix matrix = transform.getMatrix();
2622 matrix.getValues(mTmpFloats);
2623 mTmpFloats[Matrix.MTRANS_X] = offx;
2624 mTmpFloats[Matrix.MTRANS_Y] = offy;
2625 mTmpFloats[Matrix.MSCALE_X] = dsdx;
2626 mTmpFloats[Matrix.MSKEW_Y] = dtdx;
2627 mTmpFloats[Matrix.MSKEW_X] = dsdy;
2628 mTmpFloats[Matrix.MSCALE_Y] = dtdy;
2629 matrix.setValues(mTmpFloats);
Craig Mautner59c00972012-07-30 12:10:24 -07002630 final DisplayInfo displayInfo = window.mDisplayContent.getDisplayInfo();
Jeff Brownfa25bf52012-07-23 19:26:30 -07002631 final RectF dispRect = new RectF(0, 0,
Craig Mautner59c00972012-07-30 12:10:24 -07002632 displayInfo.logicalWidth, displayInfo.logicalHeight);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002633 matrix.mapRect(dispRect);
Jeff Brownfa25bf52012-07-23 19:26:30 -07002634 window.mGivenTouchableRegion.set(0, 0,
Craig Mautner59c00972012-07-30 12:10:24 -07002635 displayInfo.logicalWidth, displayInfo.logicalHeight);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002636 window.mGivenTouchableRegion.op((int)dispRect.left, (int)dispRect.top,
2637 (int)dispRect.right, (int)dispRect.bottom, Region.Op.DIFFERENCE);
2638 window.mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
Craig Mautner19d59bc2012-09-04 11:15:56 -07002639 window.mDisplayContent.layoutNeeded = true;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002640 performLayoutAndPlaceSurfacesLocked();
2641 }
2642
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002643 public void onRectangleOnScreenRequested(IBinder token, Rect rectangle, boolean immediate) {
2644 synchronized (mWindowMap) {
2645 WindowState window = mWindowMap.get(token);
2646 if (window != null) {
2647 scheduleNotifyRectangleOnScreenRequestedIfNeededLocked(window, rectangle,
2648 immediate);
2649 }
2650 }
2651 }
2652
2653 private void scheduleNotifyRectangleOnScreenRequestedIfNeededLocked(WindowState window,
2654 Rect rectangle, boolean immediate) {
2655 DisplayContent displayContent = window.mDisplayContent;
2656 if (displayContent.mDisplayContentChangeListeners != null
2657 && displayContent.mDisplayContentChangeListeners.getRegisteredCallbackCount() > 0) {
2658 mH.obtainMessage(H.NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED, displayContent.getDisplayId(),
2659 immediate? 1 : 0, new Rect(rectangle)).sendToTarget();
2660 }
2661 }
2662
2663 private void handleNotifyRectangleOnScreenRequested(int displayId, Rect rectangle,
2664 boolean immediate) {
2665 RemoteCallbackList<IDisplayContentChangeListener> callbacks = null;
2666 synchronized (mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07002667 DisplayContent displayContent = getDisplayContentLocked(displayId);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002668 if (displayContent == null) {
2669 return;
2670 }
2671 callbacks = displayContent.mDisplayContentChangeListeners;
2672 if (callbacks == null) {
2673 return;
2674 }
2675 }
2676 final int callbackCount = callbacks.beginBroadcast();
2677 try {
2678 for (int i = 0; i < callbackCount; i++) {
2679 try {
2680 callbacks.getBroadcastItem(i).onRectangleOnScreenRequested(displayId,
2681 rectangle, immediate);
2682 } catch (RemoteException re) {
2683 /* ignore */
2684 }
2685 }
2686 } finally {
2687 callbacks.finishBroadcast();
2688 }
2689 }
2690
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002691 public int relayoutWindow(Session session, IWindow client, int seq,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002692 WindowManager.LayoutParams attrs, int requestedWidth,
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002693 int requestedHeight, int viewVisibility, int flags,
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07002694 Rect outFrame, Rect outContentInsets,
Dianne Hackborn5c58de32012-04-28 19:52:37 -07002695 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07002696 boolean toBeDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002697 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002698 boolean configChanged;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002699 boolean surfaceChanged = false;
Dianne Hackborn12d3a942012-04-27 14:16:30 -07002700 boolean animating;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002701
2702 // if they don't have this permission, mask out the status bar bits
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002703 int systemUiVisibility = 0;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002704 if (attrs != null) {
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002705 systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
2706 if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -07002707 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
2708 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002709 systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
Dianne Hackborna44abeb2011-08-08 19:24:01 -07002710 }
Joe Onoratoac0ee892011-01-30 15:38:30 -08002711 }
2712 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002713 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002714
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002715 synchronized(mWindowMap) {
Craig Mautner48ba1e72012-04-02 13:18:16 -07002716 // TODO(cmautner): synchronize on mAnimator or win.mWinAnimator.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002717 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002718 if (win == null) {
2719 return 0;
2720 }
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002721 WindowStateAnimator winAnimator = win.mWinAnimator;
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08002722 if (win.mRequestedWidth != requestedWidth
2723 || win.mRequestedHeight != requestedHeight) {
2724 win.mLayoutNeeded = true;
2725 win.mRequestedWidth = requestedWidth;
2726 win.mRequestedHeight = requestedHeight;
2727 }
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002728 if (attrs != null && seq == win.mSeq) {
2729 win.mSystemUiVisibility = systemUiVisibility;
2730 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002731
2732 if (attrs != null) {
2733 mPolicy.adjustWindowParamsLw(attrs);
2734 }
Romain Guy06882f82009-06-10 13:36:04 -07002735
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002736 winAnimator.mSurfaceDestroyDeferred =
Jeff Brown98365d72012-08-19 20:30:52 -07002737 (flags&WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002738
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002739 int attrChanges = 0;
2740 int flagChanges = 0;
2741 if (attrs != null) {
Dianne Hackborn0e60db22011-09-01 11:17:57 -07002742 if (win.mAttrs.type != attrs.type) {
2743 throw new IllegalArgumentException(
2744 "Window type can not be changed after the window is added.");
2745 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002746 flagChanges = win.mAttrs.flags ^= attrs.flags;
2747 attrChanges = win.mAttrs.copyFrom(attrs);
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002748 if ((attrChanges & (WindowManager.LayoutParams.LAYOUT_CHANGED
2749 | WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED)) != 0) {
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08002750 win.mLayoutNeeded = true;
2751 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002752 }
2753
Craig Mautnerc36c49e2012-09-29 16:02:43 -07002754 if (DEBUG_LAYOUT
2755 // TODO: Remove once b/7094175 is fixed
2756 || ((String)win.mAttrs.getTitle()).contains("Keyguard")
2757 ) Slog.v(TAG, "Relayout " + win + ": viewVisibility=" + viewVisibility
Craig Mautner812d2ca2012-09-27 15:35:34 -07002758 + " " + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002759
Dianne Hackborn5fd21692011-06-07 14:09:47 -07002760 win.mEnforceSizeCompat = (win.mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0;
2761
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002762 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002763 winAnimator.mAlpha = attrs.alpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002764 }
2765
2766 final boolean scaledWindow =
2767 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2768
2769 if (scaledWindow) {
2770 // requested{Width|Height} Surface's physical size
2771 // attrs.{width|height} Size on screen
2772 win.mHScale = (attrs.width != requestedWidth) ?
2773 (attrs.width / (float)requestedWidth) : 1.0f;
2774 win.mVScale = (attrs.height != requestedHeight) ?
2775 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002776 } else {
2777 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002778 }
2779
Craig Mautner65d11b32012-10-01 13:59:52 -07002780 boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002781
Craig Mautner69b08182012-09-05 13:07:13 -07002782 final boolean isDefaultDisplay = win.isDefaultDisplay();
2783 boolean focusMayChange = isDefaultDisplay && (win.mViewVisibility != viewVisibility
Craig Mautner65d11b32012-10-01 13:59:52 -07002784 || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0)
Craig Mautner69b08182012-09-05 13:07:13 -07002785 || (!win.mRelayoutCalled));
Romain Guy06882f82009-06-10 13:36:04 -07002786
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002787 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2788 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07002789 wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002790
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002791 win.mRelayoutCalled = true;
2792 final int oldVisibility = win.mViewVisibility;
2793 win.mViewVisibility = viewVisibility;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07002794 if (DEBUG_SCREEN_ON) {
2795 RuntimeException stack = new RuntimeException();
2796 stack.fillInStackTrace();
2797 Slog.i(TAG, "Relayout " + win + ": oldVis=" + oldVisibility
2798 + " newVis=" + viewVisibility, stack);
2799 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002800 if (viewVisibility == View.VISIBLE &&
2801 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07002802 toBeDisplayed = !win.isVisibleLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002803 if (win.mExiting) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002804 winAnimator.cancelExitAnimationForNextAnimationLocked();
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002805 win.mExiting = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002806 }
2807 if (win.mDestroying) {
2808 win.mDestroying = false;
2809 mDestroySurface.remove(win);
2810 }
2811 if (oldVisibility == View.GONE) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002812 winAnimator.mEnterAnimationPending = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002813 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002814 if (toBeDisplayed) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07002815 if (win.isDrawnLw() && okToDisplay()) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002816 winAnimator.applyEnterAnimationLocked();
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002817 }
2818 if ((win.mAttrs.flags
2819 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2820 if (DEBUG_VISIBILITY) Slog.v(TAG,
2821 "Relayout window turning screen on: " + win);
2822 win.mTurnOnScreen = true;
2823 }
2824 int diff = 0;
2825 if (win.mConfiguration != mCurConfiguration
2826 && (win.mConfiguration == null
2827 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2828 win.mConfiguration = mCurConfiguration;
2829 if (DEBUG_CONFIGURATION) {
2830 Slog.i(TAG, "Window " + win + " visible with new config: "
2831 + win.mConfiguration + " / 0x"
2832 + Integer.toHexString(diff));
2833 }
2834 outConfig.setTo(mCurConfiguration);
2835 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002836 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002837 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2838 // To change the format, we need to re-build the surface.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002839 winAnimator.destroySurfaceLocked();
Craig Mautnerbf08af32012-05-16 19:43:42 -07002840 toBeDisplayed = true;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002841 surfaceChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002842 }
2843 try {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002844 if (!win.mHasSurface) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002845 surfaceChanged = true;
2846 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002847 Surface surface = winAnimator.createSurfaceLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002848 if (surface != null) {
2849 outSurface.copyFrom(surface);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002850 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002851 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002852 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002853 // For some reason there isn't a surface. Clear the
2854 // caller's object so they see the same state.
2855 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002856 }
2857 } catch (Exception e) {
Jeff Brown2e44b072011-01-24 15:21:56 -08002858 mInputMonitor.updateInputWindowsLw(true /*force*/);
Craig Mautner9e809442012-06-22 17:13:04 -07002859
Joe Onorato8a9b2202010-02-26 18:56:32 -08002860 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002861 + client + " (" + win.mAttrs.getTitle() + ")",
2862 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002863 Binder.restoreCallingIdentity(origId);
2864 return 0;
2865 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002866 if (toBeDisplayed) {
Craig Mautner69b08182012-09-05 13:07:13 -07002867 focusMayChange = isDefaultDisplay;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002868 }
2869 if (win.mAttrs.type == TYPE_INPUT_METHOD
2870 && mInputMethodWindow == null) {
2871 mInputMethodWindow = win;
2872 imMayMove = true;
2873 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002874 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2875 && win.mAppToken != null
2876 && win.mAppToken.startingWindow != null) {
2877 // Special handling of starting window over the base
2878 // window of the app: propagate lock screen flags to it,
2879 // to provide the correct semantics while starting.
2880 final int mask =
2881 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002882 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2883 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002884 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2885 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2886 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002887 } else {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002888 winAnimator.mEnterAnimationPending = false;
2889 if (winAnimator.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002890 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Craig Mautnerbf08af32012-05-16 19:43:42 -07002891 + ": mExiting=" + win.mExiting);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002892 // If we are not currently running the exit animation, we
2893 // need to see about starting one.
Craig Mautnerbf08af32012-05-16 19:43:42 -07002894 if (!win.mExiting) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002895 surfaceChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002896 // Try starting an animation; if there isn't one, we
2897 // can destroy the surface right away.
2898 int transit = WindowManagerPolicy.TRANSIT_EXIT;
Craig Mautnerbb1449b2012-03-23 16:11:14 -07002899 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002900 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2901 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002902 if (win.isWinVisibleLw() &&
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002903 winAnimator.applyAnimationLocked(transit, false)) {
Craig Mautner69b08182012-09-05 13:07:13 -07002904 focusMayChange = isDefaultDisplay;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002905 win.mExiting = true;
Craig Mautnera2c77052012-03-26 12:14:43 -07002906 } else if (win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002907 // Currently in a hide animation... turn this into
2908 // an exit.
2909 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002910 } else if (win == mWallpaperTarget) {
2911 // If the wallpaper is currently behind this
2912 // window, we need to change both of them inside
2913 // of a transaction to avoid artifacts.
2914 win.mExiting = true;
Craig Mautnera2c77052012-03-26 12:14:43 -07002915 win.mWinAnimator.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002916 } else {
2917 if (mInputMethodWindow == win) {
2918 mInputMethodWindow = null;
2919 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002920 winAnimator.destroySurfaceLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002921 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002922 scheduleNotifyWindowTranstionIfNeededLocked(win, transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002923 }
2924 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002925
Craig Mautnerbf08af32012-05-16 19:43:42 -07002926 outSurface.release();
2927 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002928 }
2929
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002930 if (focusMayChange) {
2931 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
Jeff Brown3a22cd92011-01-21 13:59:04 -08002932 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2933 false /*updateInputWindows*/)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002934 imMayMove = false;
2935 }
2936 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2937 }
Romain Guy06882f82009-06-10 13:36:04 -07002938
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002939 // updateFocusedWindowLocked() already assigned layers so we only need to
2940 // reassign them at this point if the IM window state gets shuffled
2941 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002943 if (imMayMove) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07002944 if (moveInputMethodWindowsIfNeededLocked(false) || toBeDisplayed) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002945 // Little hack here -- we -should- be able to rely on the
2946 // function to return true if the IME has moved and needs
2947 // its layer recomputed. However, if the IME was hidden
2948 // and isn't actually moved in the list, its layer may be
2949 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002950 assignLayers = true;
2951 }
2952 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002953 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002954 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002955 assignLayers = true;
2956 }
2957 }
Romain Guy06882f82009-06-10 13:36:04 -07002958
Craig Mautner19d59bc2012-09-04 11:15:56 -07002959 win.mDisplayContent.layoutNeeded = true;
Jeff Brown98365d72012-08-19 20:30:52 -07002960 win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002961 if (assignLayers) {
Craig Mautner59c00972012-07-30 12:10:24 -07002962 assignLayersLocked(win.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002963 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002964 configChanged = updateOrientationFromAppTokensLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002965 performLayoutAndPlaceSurfacesLocked();
Craig Mautnerbf08af32012-05-16 19:43:42 -07002966 if (toBeDisplayed && win.mIsWallpaper) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07002967 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Jeff Brownfa25bf52012-07-23 19:26:30 -07002968 updateWallpaperOffsetLocked(win,
Craig Mautner59c00972012-07-30 12:10:24 -07002969 displayInfo.appWidth, displayInfo.appHeight, false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002970 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002971 if (win.mAppToken != null) {
2972 win.mAppToken.updateReportedVisibilityLocked();
2973 }
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002974 outFrame.set(win.mCompatFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002975 outContentInsets.set(win.mContentInsets);
2976 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002977 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002978 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002979 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002980 + ", requestedHeight=" + requestedHeight
2981 + ", viewVisibility=" + viewVisibility
2982 + "\nRelayout returning frame=" + outFrame
2983 + ", surface=" + outSurface);
2984
Joe Onorato8a9b2202010-02-26 18:56:32 -08002985 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002986 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
2987
2988 inTouchMode = mInTouchMode;
Dianne Hackborn12d3a942012-04-27 14:16:30 -07002989 animating = mAnimator.mAnimating;
2990 if (animating && !mRelayoutWhileAnimating.contains(win)) {
2991 mRelayoutWhileAnimating.add(win);
2992 }
2993
Jeff Brown2e44b072011-01-24 15:21:56 -08002994 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002995 }
2996
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002997 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002998 sendNewConfiguration();
2999 }
Romain Guy06882f82009-06-10 13:36:04 -07003000
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003001 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07003002
Jeff Brown98365d72012-08-19 20:30:52 -07003003 return (inTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0)
3004 | (toBeDisplayed ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0)
3005 | (surfaceChanged ? WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED : 0)
3006 | (animating ? WindowManagerGlobal.RELAYOUT_RES_ANIMATING : 0);
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003007 }
3008
3009 public void performDeferredDestroyWindow(Session session, IWindow client) {
3010 long origId = Binder.clearCallingIdentity();
3011
3012 try {
3013 synchronized(mWindowMap) {
3014 WindowState win = windowForClientLocked(session, client, false);
3015 if (win == null) {
3016 return;
3017 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003018 win.mWinAnimator.destroyDeferredSurfaceLocked();
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003019 }
3020 } finally {
3021 Binder.restoreCallingIdentity(origId);
3022 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003023 }
3024
Dianne Hackborn64825172011-03-02 21:32:58 -08003025 public boolean outOfMemoryWindow(Session session, IWindow client) {
3026 long origId = Binder.clearCallingIdentity();
3027
3028 try {
3029 synchronized(mWindowMap) {
3030 WindowState win = windowForClientLocked(session, client, false);
3031 if (win == null) {
3032 return false;
3033 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003034 return reclaimSomeSurfaceMemoryLocked(win.mWinAnimator, "from-client", false);
Dianne Hackborn64825172011-03-02 21:32:58 -08003035 }
3036 } finally {
3037 Binder.restoreCallingIdentity(origId);
3038 }
3039 }
3040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003041 public void finishDrawingWindow(Session session, IWindow client) {
3042 final long origId = Binder.clearCallingIdentity();
3043 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003044 WindowState win = windowForClientLocked(session, client, false);
Craig Mautnera608b882012-03-30 13:03:49 -07003045 if (win != null && win.mWinAnimator.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07003046 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
3047 adjustWallpaperWindowsLocked();
3048 }
Craig Mautner19d59bc2012-09-04 11:15:56 -07003049 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003050 performLayoutAndPlaceSurfacesLocked();
3051 }
3052 }
3053 Binder.restoreCallingIdentity(origId);
3054 }
3055
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003056 @Override
Svetoslav Ganov7961be72011-06-21 12:31:56 -07003057 public float getWindowCompatibilityScale(IBinder windowToken) {
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07003058 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
3059 "getWindowCompatibilityScale()")) {
3060 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
3061 }
Svetoslav Ganov7961be72011-06-21 12:31:56 -07003062 synchronized (mWindowMap) {
3063 WindowState windowState = mWindowMap.get(windowToken);
3064 return (windowState != null) ? windowState.mGlobalScale : 1.0f;
3065 }
3066 }
3067
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003068 @Override
3069 public WindowInfo getWindowInfo(IBinder token) {
3070 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
3071 "getWindowInfo()")) {
3072 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
3073 }
3074 synchronized (mWindowMap) {
3075 WindowState window = mWindowMap.get(token);
3076 if (window != null) {
3077 return getWindowInfoForWindowStateLocked(window);
3078 }
3079 return null;
3080 }
3081 }
3082
3083 @Override
3084 public void getVisibleWindowsForDisplay(int displayId, List<WindowInfo> outInfos) {
3085 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
3086 "getWindowInfos()")) {
3087 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
3088 }
3089 synchronized (mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003090 DisplayContent displayContent = getDisplayContentLocked(displayId);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003091 if (displayContent == null) {
3092 return;
3093 }
3094 WindowList windows = displayContent.getWindowList();
3095 final int windowCount = windows.size();
3096 for (int i = 0; i < windowCount; i++) {
3097 WindowState window = windows.get(i);
Craig Mautner65d11b32012-10-01 13:59:52 -07003098 if (window.isVisibleLw() || window.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003099 WindowInfo info = getWindowInfoForWindowStateLocked(window);
3100 outInfos.add(info);
3101 }
3102 }
3103 }
3104 }
3105
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003106 @Override
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003107 public void magnifyDisplay(int displayId, float scale, float offsetX, float offsetY) {
3108 if (!checkCallingPermission(
3109 android.Manifest.permission.MAGNIFY_DISPLAY, "magnifyDisplay()")) {
3110 throw new SecurityException("Requires MAGNIFY_DISPLAY permission");
3111 }
3112 synchronized (mWindowMap) {
3113 MagnificationSpec spec = getDisplayMagnificationSpecLocked(displayId);
3114 if (spec != null) {
3115 final boolean scaleChanged = spec.mScale != scale;
3116 final boolean offsetChanged = spec.mOffsetX != offsetX || spec.mOffsetY != offsetY;
3117 if (!scaleChanged && !offsetChanged) {
3118 return;
3119 }
3120 spec.initialize(scale, offsetX, offsetY);
3121 // If the offset has changed we need to re-add the input windows
3122 // since the offsets have to be propagated to the input system.
3123 if (offsetChanged) {
3124 // TODO(multidisplay): Input only occurs on the default display.
3125 if (displayId == Display.DEFAULT_DISPLAY) {
3126 mInputMonitor.updateInputWindowsLw(true);
3127 }
3128 }
3129 scheduleAnimationLocked();
3130 }
3131 }
3132 }
3133
3134 MagnificationSpec getDisplayMagnificationSpecLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003135 DisplayContent displayContent = getDisplayContentLocked(displayId);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003136 if (displayContent != null) {
3137 if (displayContent.mMagnificationSpec == null) {
3138 displayContent.mMagnificationSpec = new MagnificationSpec();
3139 }
3140 return displayContent.mMagnificationSpec;
3141 }
3142 return null;
3143 }
3144
3145 private WindowInfo getWindowInfoForWindowStateLocked(WindowState window) {
3146 WindowInfo info = WindowInfo.obtain();
3147 info.token = window.mToken.token;
3148 info.frame.set(window.mFrame);
3149 info.type = window.mAttrs.type;
3150 info.displayId = window.getDisplayId();
3151 info.compatibilityScale = window.mGlobalScale;
Craig Mautner65d11b32012-10-01 13:59:52 -07003152 info.visible = window.isVisibleLw() || info.type == TYPE_UNIVERSE_BACKGROUND;
Svetoslav Ganov9b4125e2012-09-11 15:36:44 -07003153 info.layer = window.mLayer;
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003154 window.getTouchableRegion(mTempRegion);
3155 mTempRegion.getBounds(info.touchableRegion);
3156 return info;
3157 }
3158
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003159 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Dianne Hackborn08121bc2011-01-17 17:54:31 -08003160 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: layout params pkg="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003161 + (lp != null ? lp.packageName : null)
3162 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
3163 if (lp != null && lp.windowAnimations != 0) {
3164 // If this is a system resource, don't try to load it from the
3165 // application resources. It is nice to avoid loading application
3166 // resources if we can.
3167 String packageName = lp.packageName != null ? lp.packageName : "android";
3168 int resId = lp.windowAnimations;
3169 if ((resId&0xFF000000) == 0x01000000) {
3170 packageName = "android";
3171 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003172 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003173 + packageName);
3174 return AttributeCache.instance().get(packageName, resId,
3175 com.android.internal.R.styleable.WindowAnimation);
3176 }
3177 return null;
3178 }
Romain Guy06882f82009-06-10 13:36:04 -07003179
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003180 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Dianne Hackborn08121bc2011-01-17 17:54:31 -08003181 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003182 + packageName + " resId=0x" + Integer.toHexString(resId));
3183 if (packageName != null) {
3184 if ((resId&0xFF000000) == 0x01000000) {
3185 packageName = "android";
3186 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003187 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003188 + packageName);
3189 return AttributeCache.instance().get(packageName, resId,
3190 com.android.internal.R.styleable.WindowAnimation);
3191 }
3192 return null;
3193 }
3194
Craig Mautnere7ae2502012-03-26 17:11:19 -07003195 Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003196 int anim = 0;
3197 Context context = mContext;
3198 if (animAttr >= 0) {
3199 AttributeCache.Entry ent = getCachedAnimations(lp);
3200 if (ent != null) {
3201 context = ent.context;
3202 anim = ent.array.getResourceId(animAttr, 0);
3203 }
3204 }
3205 if (anim != 0) {
3206 return AnimationUtils.loadAnimation(context, anim);
3207 }
3208 return null;
3209 }
Romain Guy06882f82009-06-10 13:36:04 -07003210
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003211 private Animation loadAnimation(String packageName, int resId) {
3212 int anim = 0;
3213 Context context = mContext;
3214 if (resId >= 0) {
3215 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
3216 if (ent != null) {
3217 context = ent.context;
3218 anim = resId;
3219 }
3220 }
3221 if (anim != 0) {
3222 return AnimationUtils.loadAnimation(context, anim);
3223 }
3224 return null;
3225 }
3226
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003227 private Animation createExitAnimationLocked(int transit, int duration) {
3228 if (transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN ||
3229 transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE) {
3230 // If we are on top of the wallpaper, we need an animation that
3231 // correctly handles the wallpaper staying static behind all of
3232 // the animated elements. To do this, will just have the existing
3233 // element fade out.
3234 Animation a = new AlphaAnimation(1, 0);
3235 a.setDetachWallpaper(true);
3236 a.setDuration(duration);
3237 return a;
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003238 }
Craig Mautner01cd0e72012-06-18 10:19:11 -07003239 // For normal animations, the exiting element just holds in place.
3240 Animation a = new AlphaAnimation(1, 1);
3241 a.setDuration(duration);
3242 return a;
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003243 }
3244
3245 /**
3246 * Compute the pivot point for an animation that is scaling from a small
3247 * rect on screen to a larger rect. The pivot point varies depending on
3248 * the distance between the inner and outer edges on both sides. This
3249 * function computes the pivot point for one dimension.
3250 * @param startPos Offset from left/top edge of outer rectangle to
3251 * left/top edge of inner rectangle.
3252 * @param finalScale The scaling factor between the size of the outer
3253 * and inner rectangles.
3254 */
3255 private static float computePivot(int startPos, float finalScale) {
3256 final float denom = finalScale-1;
3257 if (Math.abs(denom) < .0001f) {
3258 return startPos;
3259 }
3260 return -startPos / denom;
3261 }
3262
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003263 private Animation createScaleUpAnimationLocked(int transit, boolean enter) {
3264 Animation a;
3265 // Pick the desired duration. If this is an inter-activity transition,
3266 // it is the standard duration for that. Otherwise we use the longer
3267 // task transition duration.
3268 int duration;
3269 switch (transit) {
3270 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3271 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3272 duration = mContext.getResources().getInteger(
3273 com.android.internal.R.integer.config_shortAnimTime);
3274 break;
3275 default:
Winson Chungdc6f79b2012-04-17 17:27:31 -07003276 duration = 300;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003277 break;
3278 }
Craig Mautner59c00972012-07-30 12:10:24 -07003279 // TODO(multidisplay): For now assume all app animation is on main display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003280 final DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003281 if (enter) {
3282 // Entering app zooms out from the center of the initial rect.
Craig Mautner59c00972012-07-30 12:10:24 -07003283 float scaleW = mNextAppTransitionStartWidth / (float) displayInfo.appWidth;
3284 float scaleH = mNextAppTransitionStartHeight / (float) displayInfo.appHeight;
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003285 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
3286 computePivot(mNextAppTransitionStartX, scaleW),
3287 computePivot(mNextAppTransitionStartY, scaleH));
3288 scale.setDuration(duration);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003289 AnimationSet set = new AnimationSet(true);
3290 Animation alpha = new AlphaAnimation(0, 1);
3291 scale.setDuration(duration);
3292 set.addAnimation(scale);
3293 alpha.setDuration(duration);
3294 set.addAnimation(alpha);
Craig Mautnera8033712012-06-12 15:50:45 -07003295 set.setDetachWallpaper(true);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003296 a = set;
3297 } else {
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003298 a = createExitAnimationLocked(transit, duration);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003299 }
3300 a.setFillAfter(true);
3301 final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
Winson Chungdc6f79b2012-04-17 17:27:31 -07003302 com.android.internal.R.interpolator.decelerate_cubic);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003303 a.setInterpolator(interpolator);
Craig Mautner59c00972012-07-30 12:10:24 -07003304 a.initialize(displayInfo.appWidth, displayInfo.appHeight,
3305 displayInfo.appWidth, displayInfo.appHeight);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003306 return a;
3307 }
3308
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003309 private Animation createThumbnailAnimationLocked(int transit,
Michael Jurka832cb222012-04-13 09:32:47 -07003310 boolean enter, boolean thumb, boolean scaleUp) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003311 Animation a;
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003312 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
3313 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
3314 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
3315 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003316 // Pick the desired duration. If this is an inter-activity transition,
3317 // it is the standard duration for that. Otherwise we use the longer
3318 // task transition duration.
3319 int duration;
3320 switch (transit) {
3321 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3322 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3323 duration = mContext.getResources().getInteger(
3324 com.android.internal.R.integer.config_shortAnimTime);
3325 break;
3326 default:
Michael Jurka832cb222012-04-13 09:32:47 -07003327 duration = 250;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003328 break;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003329 }
Craig Mautner59c00972012-07-30 12:10:24 -07003330 // TOOD(multidisplay): For now assume all app animation is on the main screen.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003331 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003332 if (thumb) {
3333 // Animation for zooming thumbnail from its initial size to
3334 // filling the screen.
Michael Jurka832cb222012-04-13 09:32:47 -07003335 if (scaleUp) {
3336 float scaleW = displayInfo.appWidth / thumbWidth;
3337 float scaleH = displayInfo.appHeight / thumbHeight;
Michael Jurka21385cd2012-05-03 10:57:31 -07003338
Michael Jurka832cb222012-04-13 09:32:47 -07003339 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
3340 computePivot(mNextAppTransitionStartX, 1 / scaleW),
3341 computePivot(mNextAppTransitionStartY, 1 / scaleH));
3342 AnimationSet set = new AnimationSet(true);
3343 Animation alpha = new AlphaAnimation(1, 0);
3344 scale.setDuration(duration);
3345 scale.setInterpolator(
3346 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
3347 set.addAnimation(scale);
3348 alpha.setDuration(duration);
3349 set.addAnimation(alpha);
3350 set.setFillBefore(true);
3351 a = set;
3352 } else {
3353 float scaleW = displayInfo.appWidth / thumbWidth;
3354 float scaleH = displayInfo.appHeight / thumbHeight;
3355
3356 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
3357 computePivot(mNextAppTransitionStartX, 1 / scaleW),
3358 computePivot(mNextAppTransitionStartY, 1 / scaleH));
3359 AnimationSet set = new AnimationSet(true);
3360 Animation alpha = new AlphaAnimation(1, 1);
3361 scale.setDuration(duration);
3362 scale.setInterpolator(
3363 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
3364 set.addAnimation(scale);
3365 alpha.setDuration(duration);
3366 set.addAnimation(alpha);
3367 set.setFillBefore(true);
3368
3369 a = set;
Michael Jurka21385cd2012-05-03 10:57:31 -07003370 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003371 } else if (enter) {
3372 // Entering app zooms out from the center of the thumbnail.
Michael Jurka832cb222012-04-13 09:32:47 -07003373 if (scaleUp) {
3374 float scaleW = thumbWidth / displayInfo.appWidth;
3375 float scaleH = thumbHeight / displayInfo.appHeight;
3376 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
3377 computePivot(mNextAppTransitionStartX, scaleW),
3378 computePivot(mNextAppTransitionStartY, scaleH));
3379 scale.setDuration(duration);
3380 scale.setInterpolator(
3381 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
3382 scale.setFillBefore(true);
3383 a = scale;
Michael Jurkad5895a72012-05-12 13:24:58 -07003384 } else {
Michael Jurka832cb222012-04-13 09:32:47 -07003385 // noop animation
3386 a = new AlphaAnimation(1, 1);
3387 a.setDuration(duration);
3388 }
3389 } else {
3390 // Exiting app
3391 if (scaleUp) {
3392 // noop animation
Craig Mautner8863cca2012-09-18 15:04:34 -07003393 a = new AlphaAnimation(1, 0);
Michael Jurka832cb222012-04-13 09:32:47 -07003394 a.setDuration(duration);
3395 } else {
3396 float scaleW = thumbWidth / displayInfo.appWidth;
3397 float scaleH = thumbHeight / displayInfo.appHeight;
3398 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
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 AnimationSet set = new AnimationSet(true);
3406 Animation alpha = new AlphaAnimation(1, 0);
3407 set.addAnimation(scale);
3408 alpha.setDuration(duration);
3409 alpha.setInterpolator(new DecelerateInterpolator(
3410 THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
3411 set.addAnimation(alpha);
3412 set.setFillBefore(true);
3413 set.setZAdjustment(Animation.ZORDER_TOP);
3414 a = set;
Michael Jurka21385cd2012-05-03 10:57:31 -07003415 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003416 }
3417 a.setFillAfter(true);
3418 final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003419 com.android.internal.R.interpolator.decelerate_quad);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003420 a.setInterpolator(interpolator);
Craig Mautner59c00972012-07-30 12:10:24 -07003421 a.initialize(displayInfo.appWidth, displayInfo.appHeight,
3422 displayInfo.appWidth, displayInfo.appHeight);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003423 return a;
3424 }
3425
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003426 private boolean applyAnimationLocked(AppWindowToken atoken,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07003427 WindowManager.LayoutParams lp, int transit, boolean enter) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003428 // Only apply an animation if the display isn't frozen. If it is
3429 // frozen, there is no reason to animate and it can cause strange
3430 // artifacts when we unfreeze the display if some different animation
3431 // is running.
Craig Mautner2fb98b12012-03-20 17:24:00 -07003432 if (okToDisplay()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003433 Animation a;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003434 boolean initialized = false;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003435 if (mNextAppTransitionType == ActivityOptions.ANIM_CUSTOM) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003436 a = loadAnimation(mNextAppTransitionPackage, enter ?
3437 mNextAppTransitionEnter : mNextAppTransitionExit);
Daniel Sandlerab886f52012-06-04 14:36:25 -04003438 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003439 "applyAnimation: atoken=" + atoken
Craig Mautner83339b42012-05-01 22:13:23 -07003440 + " anim=" + a + " nextAppTransition=ANIM_CUSTOM"
Craig Mautnerdc5a6382012-09-13 16:34:41 -07003441 + " transit=" + transit + " isEntrance=" + enter
Craig Mautner8863cca2012-09-18 15:04:34 -07003442 + " Callers=" + Debug.getCallers(3));
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003443 } else if (mNextAppTransitionType == ActivityOptions.ANIM_SCALE_UP) {
3444 a = createScaleUpAnimationLocked(transit, enter);
3445 initialized = true;
Daniel Sandlerab886f52012-06-04 14:36:25 -04003446 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003447 "applyAnimation: atoken=" + atoken
Craig Mautner83339b42012-05-01 22:13:23 -07003448 + " anim=" + a + " nextAppTransition=ANIM_SCALE_UP"
Craig Mautnerdc5a6382012-09-13 16:34:41 -07003449 + " transit=" + transit + " isEntrance=" + enter
Craig Mautner8863cca2012-09-18 15:04:34 -07003450 + " Callers=" + Debug.getCallers(3));
Michael Jurka832cb222012-04-13 09:32:47 -07003451 } else if (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_SCALE_UP ||
3452 mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN) {
3453 boolean scaleUp = (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_SCALE_UP);
3454 a = createThumbnailAnimationLocked(transit, enter, false, scaleUp);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003455 initialized = true;
Daniel Sandlerab886f52012-06-04 14:36:25 -04003456 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
Michael Jurka832cb222012-04-13 09:32:47 -07003457 String animName = scaleUp ? "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN";
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003458 Slog.v(TAG, "applyAnimation: atoken=" + atoken
Michael Jurka21385cd2012-05-03 10:57:31 -07003459 + " anim=" + a + " nextAppTransition=" + animName
Craig Mautnerdc5a6382012-09-13 16:34:41 -07003460 + " transit=" + transit + " isEntrance=" + enter
Craig Mautner8863cca2012-09-18 15:04:34 -07003461 + " Callers=" + Debug.getCallers(3));
Michael Jurka21385cd2012-05-03 10:57:31 -07003462 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003463 } else {
3464 int animAttr = 0;
3465 switch (transit) {
3466 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3467 animAttr = enter
3468 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
3469 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
3470 break;
3471 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3472 animAttr = enter
3473 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
3474 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
3475 break;
3476 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
3477 animAttr = enter
3478 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
3479 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
3480 break;
3481 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
3482 animAttr = enter
3483 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
3484 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
3485 break;
3486 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
3487 animAttr = enter
3488 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
3489 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
3490 break;
3491 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
3492 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07003493 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003494 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
3495 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003496 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003497 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003498 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
3499 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003500 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003501 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003502 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003503 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
3504 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
3505 break;
3506 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
3507 animAttr = enter
3508 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
3509 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
3510 break;
3511 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
3512 animAttr = enter
3513 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
3514 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003515 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003516 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003517 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Daniel Sandlerab886f52012-06-04 14:36:25 -04003518 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003519 "applyAnimation: atoken=" + atoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003520 + " anim=" + a
3521 + " animAttr=0x" + Integer.toHexString(animAttr)
Craig Mautnerdc5a6382012-09-13 16:34:41 -07003522 + " transit=" + transit + " isEntrance=" + enter
Craig Mautner8863cca2012-09-18 15:04:34 -07003523 + " Callers=" + Debug.getCallers(3));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003524 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003525 if (a != null) {
3526 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003527 RuntimeException e = null;
3528 if (!HIDE_STACK_CRAWLS) {
3529 e = new RuntimeException();
3530 e.fillInStackTrace();
3531 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003532 Slog.v(TAG, "Loaded animation " + a + " for " + atoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003533 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003534 atoken.mAppAnimator.setAnimation(a, initialized);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003535 }
3536 } else {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003537 atoken.mAppAnimator.clearAnimation();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003538 }
3539
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003540 return atoken.mAppAnimator.animation != null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003541 }
3542
3543 // -------------------------------------------------------------
3544 // Application Window Tokens
3545 // -------------------------------------------------------------
3546
Dianne Hackbornbe707852011-11-11 14:32:10 -08003547 public void validateAppTokens(List<IBinder> tokens) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003548 int v = tokens.size()-1;
3549 int m = mAppTokens.size()-1;
3550 while (v >= 0 && m >= 0) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003551 AppWindowToken atoken = mAppTokens.get(m);
3552 if (atoken.removed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003553 m--;
3554 continue;
3555 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003556 if (tokens.get(v) != atoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003557 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003558 + " @ " + v + ", internal is " + atoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003559 }
3560 v--;
3561 m--;
3562 }
3563 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003564 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003565 v--;
3566 }
3567 while (m >= 0) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003568 AppWindowToken atoken = mAppTokens.get(m);
3569 if (!atoken.removed) {
3570 Slog.w(TAG, "Invalid internal atoken: " + atoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003571 }
3572 m--;
3573 }
3574 }
3575
3576 boolean checkCallingPermission(String permission, String func) {
3577 // Quick check: if the calling permission is me, it's all okay.
3578 if (Binder.getCallingPid() == Process.myPid()) {
3579 return true;
3580 }
Romain Guy06882f82009-06-10 13:36:04 -07003581
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003582 if (mContext.checkCallingPermission(permission)
3583 == PackageManager.PERMISSION_GRANTED) {
3584 return true;
3585 }
3586 String msg = "Permission Denial: " + func + " from pid="
3587 + Binder.getCallingPid()
3588 + ", uid=" + Binder.getCallingUid()
3589 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003590 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003591 return false;
3592 }
Craig Mautner9e809442012-06-22 17:13:04 -07003593
Craig Mautner2fb98b12012-03-20 17:24:00 -07003594 boolean okToDisplay() {
3595 return !mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully();
3596 }
Romain Guy06882f82009-06-10 13:36:04 -07003597
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003598 AppWindowToken findAppWindowToken(IBinder token) {
3599 WindowToken wtoken = mTokenMap.get(token);
3600 if (wtoken == null) {
3601 return null;
3602 }
3603 return wtoken.appWindowToken;
3604 }
Romain Guy06882f82009-06-10 13:36:04 -07003605
Craig Mautnercf8cbbe2012-03-25 21:54:36 -07003606 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003607 public void addWindowToken(IBinder token, int type) {
3608 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3609 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003610 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003611 }
Romain Guy06882f82009-06-10 13:36:04 -07003612
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003613 synchronized(mWindowMap) {
3614 WindowToken wtoken = mTokenMap.get(token);
3615 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003616 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003617 return;
3618 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003619 wtoken = new WindowToken(this, token, type, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003620 mTokenMap.put(token, wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003621 if (type == TYPE_WALLPAPER) {
3622 mWallpaperTokens.add(wtoken);
Craig Mautner918b53b2012-07-09 14:15:54 -07003623 updateLayoutToAnimWallpaperTokens();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003624 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003625 }
3626 }
Romain Guy06882f82009-06-10 13:36:04 -07003627
Craig Mautner9e809442012-06-22 17:13:04 -07003628 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003629 public void removeWindowToken(IBinder token) {
3630 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3631 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003632 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003633 }
3634
3635 final long origId = Binder.clearCallingIdentity();
3636 synchronized(mWindowMap) {
3637 WindowToken wtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003638 if (wtoken != null) {
3639 boolean delayed = false;
3640 if (!wtoken.hidden) {
3641 wtoken.hidden = true;
Romain Guy06882f82009-06-10 13:36:04 -07003642
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003643 final int N = wtoken.windows.size();
3644 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003645
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003646 for (int i=0; i<N; i++) {
3647 WindowState win = wtoken.windows.get(i);
3648
Craig Mautnera2c77052012-03-26 12:14:43 -07003649 if (win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003650 delayed = true;
3651 }
Romain Guy06882f82009-06-10 13:36:04 -07003652
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003653 if (win.isVisibleNow()) {
Craig Mautner59c00972012-07-30 12:10:24 -07003654 win.mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT,
3655 false);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003656 scheduleNotifyWindowTranstionIfNeededLocked(win,
3657 WindowManagerPolicy.TRANSIT_EXIT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003658 changed = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07003659 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003660 }
3661 }
3662
3663 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003664 performLayoutAndPlaceSurfacesLocked();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003665 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
3666 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003667 }
Romain Guy06882f82009-06-10 13:36:04 -07003668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003669 if (delayed) {
3670 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003671 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3672 mWallpaperTokens.remove(wtoken);
Craig Mautner918b53b2012-07-09 14:15:54 -07003673 updateLayoutToAnimWallpaperTokens();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003674 }
3675 }
Romain Guy06882f82009-06-10 13:36:04 -07003676
Jeff Brown2e44b072011-01-24 15:21:56 -08003677 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003678 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003679 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003680 }
3681 }
3682 Binder.restoreCallingIdentity(origId);
3683 }
3684
Craig Mautneref25d7a2012-05-15 23:01:47 -07003685 /**
3686 * Find the location to insert a new AppWindowToken into the window-ordered app token list.
3687 * Note that mAppTokens.size() == mAnimatingAppTokens.size() + 1.
3688 * @param addPos The location the token was inserted into in mAppTokens.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003689 * @param atoken The token to insert.
Craig Mautneref25d7a2012-05-15 23:01:47 -07003690 */
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003691 private void addAppTokenToAnimating(final int addPos, final AppWindowToken atoken) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07003692 if (addPos == 0 || addPos == mAnimatingAppTokens.size()) {
3693 // It was inserted into the beginning or end of mAppTokens. Honor that.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003694 mAnimatingAppTokens.add(addPos, atoken);
Craig Mautneref25d7a2012-05-15 23:01:47 -07003695 return;
3696 }
3697 // Find the item immediately above the mAppTokens insertion point and put the token
3698 // immediately below that one in mAnimatingAppTokens.
3699 final AppWindowToken aboveAnchor = mAppTokens.get(addPos + 1);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003700 mAnimatingAppTokens.add(mAnimatingAppTokens.indexOf(aboveAnchor), atoken);
Craig Mautneref25d7a2012-05-15 23:01:47 -07003701 }
3702
3703 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003704 public void addAppToken(int addPos, IApplicationToken token,
3705 int groupId, int requestedOrientation, boolean fullscreen) {
3706 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3707 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003708 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003709 }
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07003710
Jeff Brown349703e2010-06-22 01:27:15 -07003711 // Get the dispatching timeout here while we are not holding any locks so that it
3712 // can be cached by the AppWindowToken. The timeout value is used later by the
3713 // input dispatcher in code that does hold locks. If we did not cache the value
3714 // here we would run the chance of introducing a deadlock between the window manager
3715 // (which holds locks while updating the input dispatcher state) and the activity manager
3716 // (which holds locks while querying the application token).
3717 long inputDispatchingTimeoutNanos;
3718 try {
3719 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3720 } catch (RemoteException ex) {
3721 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3722 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3723 }
Romain Guy06882f82009-06-10 13:36:04 -07003724
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003725 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003726 AppWindowToken atoken = findAppWindowToken(token.asBinder());
3727 if (atoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003728 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003729 return;
3730 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003731 atoken = new AppWindowToken(this, token);
3732 atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
3733 atoken.groupId = groupId;
3734 atoken.appFullscreen = fullscreen;
3735 atoken.requestedOrientation = requestedOrientation;
3736 if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + atoken
Craig Mautner06a94f72012-05-29 10:46:00 -07003737 + " at " + addPos);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003738 mAppTokens.add(addPos, atoken);
3739 addAppTokenToAnimating(addPos, atoken);
3740 mTokenMap.put(token.asBinder(), atoken);
Romain Guy06882f82009-06-10 13:36:04 -07003741
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003742 // Application tokens start out hidden.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003743 atoken.hidden = true;
3744 atoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003745
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003746 //dump();
3747 }
3748 }
Romain Guy06882f82009-06-10 13:36:04 -07003749
Craig Mautner9e809442012-06-22 17:13:04 -07003750 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003751 public void setAppGroupId(IBinder token, int groupId) {
3752 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner6fbda632012-07-03 09:26:39 -07003753 "setAppGroupId()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003754 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003755 }
3756
3757 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003758 AppWindowToken atoken = findAppWindowToken(token);
3759 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003760 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003761 return;
3762 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003763 atoken.groupId = groupId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003764 }
3765 }
Romain Guy06882f82009-06-10 13:36:04 -07003766
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003767 public int getOrientationFromWindowsLocked() {
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003768 if (mDisplayFrozen || mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
3769 // If the display is frozen, some activities may be in the middle
3770 // of restarting, and thus have removed their old window. If the
3771 // window has the flag to hide the lock screen, then the lock screen
3772 // can re-appear and inflict its own orientation on us. Keep the
3773 // orientation stable until this all settles down.
3774 return mLastWindowForcedOrientation;
3775 }
3776
Craig Mautner59c00972012-07-30 12:10:24 -07003777 // TODO(multidisplay): Change to the correct display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003778 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07003779 int pos = windows.size() - 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003780 while (pos >= 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07003781 WindowState wtoken = windows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003782 pos--;
3783 if (wtoken.mAppToken != null) {
3784 // We hit an application window. so the orientation will be determined by the
3785 // app window. No point in continuing further.
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003786 return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003787 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003788 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003789 continue;
3790 }
3791 int req = wtoken.mAttrs.screenOrientation;
3792 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3793 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3794 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003795 }
Craig Mautner9e809442012-06-22 17:13:04 -07003796
3797 return (mLastWindowForcedOrientation=req);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003798 }
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003799 return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003800 }
Romain Guy06882f82009-06-10 13:36:04 -07003801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003802 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003803 int curGroup = 0;
3804 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3805 boolean findingBehind = false;
3806 boolean haveGroup = false;
3807 boolean lastFullscreen = false;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07003808 for (int pos = mAppTokens.size() - 1; pos >= 0; pos--) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003809 AppWindowToken atoken = mAppTokens.get(pos);
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003810
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003811 if (DEBUG_APP_ORIENTATION) Slog.v(TAG, "Checking app orientation: " + atoken);
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003812
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003813 // if we're about to tear down this window and not seek for
3814 // the behind activity, don't use it for orientation
3815 if (!findingBehind
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003816 && (!atoken.hidden && atoken.hiddenRequested)) {
3817 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003818 + " -- going to hide");
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003819 continue;
3820 }
3821
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003822 if (haveGroup == true && curGroup != atoken.groupId) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003823 // If we have hit a new application group, and the bottom
3824 // of the previous group didn't explicitly say to use
3825 // the orientation behind it, and the last app was
3826 // full screen, then we'll stick with the
3827 // user's orientation.
3828 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3829 && lastFullscreen) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003830 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003831 + " -- end of group, return " + lastOrientation);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003832 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003833 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003834 }
p134510445bc62012-04-18 15:13:26 +09003835
3836 // We ignore any hidden applications on the top.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003837 if (atoken.hiddenRequested || atoken.willBeHidden) {
3838 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
p134510445bc62012-04-18 15:13:26 +09003839 + " -- hidden on top");
3840 continue;
3841 }
3842
3843 if (!haveGroup) {
3844 haveGroup = true;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003845 curGroup = atoken.groupId;
3846 lastOrientation = atoken.requestedOrientation;
Craig Mautner918b53b2012-07-09 14:15:54 -07003847 }
p134510445bc62012-04-18 15:13:26 +09003848
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003849 int or = atoken.requestedOrientation;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003850 // If this application is fullscreen, and didn't explicitly say
3851 // to use the orientation behind it, then just take whatever
3852 // orientation it has and ignores whatever is under it.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003853 lastFullscreen = atoken.appFullscreen;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003854 if (lastFullscreen
3855 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003856 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003857 + " -- full screen, return " + or);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003858 return or;
3859 }
3860 // If this application has requested an explicit orientation,
3861 // then use it.
Dianne Hackborne5439f22010-10-02 16:53:50 -07003862 if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
3863 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003864 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003865 + " -- explicitly set, return " + or);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003866 return or;
3867 }
3868 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3869 }
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003870 if (DEBUG_ORIENTATION) Slog.v(TAG, "No app is requesting an orientation");
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003871 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003872 }
Romain Guy06882f82009-06-10 13:36:04 -07003873
Craig Mautner711f90a2012-07-03 18:43:52 -07003874 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003875 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003876 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003877 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3878 "updateOrientationFromAppTokens()")) {
3879 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3880 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003881
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003882 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003883 long ident = Binder.clearCallingIdentity();
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003884
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003885 synchronized(mWindowMap) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003886 config = updateOrientationFromAppTokensLocked(currentConfig,
3887 freezeThisOneIfNeeded);
3888 }
3889
3890 Binder.restoreCallingIdentity(ident);
3891 return config;
3892 }
3893
3894 private Configuration updateOrientationFromAppTokensLocked(
3895 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
3896 Configuration config = null;
3897
3898 if (updateOrientationFromAppTokensLocked(false)) {
3899 if (freezeThisOneIfNeeded != null) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003900 AppWindowToken atoken = findAppWindowToken(
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003901 freezeThisOneIfNeeded);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003902 if (atoken != null) {
3903 startAppFreezingScreenLocked(atoken,
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003904 ActivityInfo.CONFIG_ORIENTATION);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003905 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003906 }
3907 config = computeNewConfigurationLocked();
3908
3909 } else if (currentConfig != null) {
3910 // No obvious action we need to take, but if our current
3911 // state mismatches the activity manager's, update it,
3912 // disregarding font scale, which should remain set to
3913 // the value of the previous configuration.
3914 mTempConfiguration.setToDefaults();
3915 mTempConfiguration.fontScale = currentConfig.fontScale;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08003916 if (computeScreenConfigurationLocked(mTempConfiguration)) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003917 if (currentConfig.diff(mTempConfiguration) != 0) {
3918 mWaitingForConfig = true;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003919 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07003920 startFreezingDisplayLocked(false, 0, 0);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003921 config = new Configuration(mTempConfiguration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003922 }
3923 }
3924 }
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003925
Dianne Hackborncfaef692009-06-15 14:24:44 -07003926 return config;
3927 }
3928
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003929 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003930 * Determine the new desired orientation of the display, returning
3931 * a non-null new Configuration if it has changed from the current
3932 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3933 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3934 * SCREEN. This will typically be done for you if you call
3935 * sendNewConfiguration().
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003936 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003937 * The orientation is computed from non-application windows first. If none of
3938 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003939 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003940 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3941 * android.os.IBinder)
3942 */
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003943 boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003944 long ident = Binder.clearCallingIdentity();
3945 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003946 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003947
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003948 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003949 mForcedAppOrientation = req;
3950 //send a message to Policy indicating orientation change to take
3951 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003952 mPolicy.setCurrentOrientationLw(req);
Jeff Brown01a98dd2011-09-20 15:08:29 -07003953 if (updateRotationUncheckedLocked(inTransaction)) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003954 // changed
3955 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003956 }
3957 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003958
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003959 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003960 } finally {
3961 Binder.restoreCallingIdentity(ident);
3962 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003963 }
Romain Guy06882f82009-06-10 13:36:04 -07003964
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003965 int computeForcedAppOrientationLocked() {
3966 int req = getOrientationFromWindowsLocked();
3967 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3968 req = getOrientationFromAppTokensLocked();
3969 }
3970 return req;
3971 }
Romain Guy06882f82009-06-10 13:36:04 -07003972
Craig Mautner918b53b2012-07-09 14:15:54 -07003973 @Override
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003974 public void setNewConfiguration(Configuration config) {
3975 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3976 "setNewConfiguration()")) {
3977 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3978 }
3979
3980 synchronized(mWindowMap) {
3981 mCurConfiguration = new Configuration(config);
3982 mWaitingForConfig = false;
3983 performLayoutAndPlaceSurfacesLocked();
3984 }
3985 }
Craig Mautner918b53b2012-07-09 14:15:54 -07003986
3987 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003988 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3989 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3990 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003991 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003992 }
Romain Guy06882f82009-06-10 13:36:04 -07003993
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003994 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003995 AppWindowToken atoken = findAppWindowToken(token.asBinder());
3996 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003997 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003998 return;
3999 }
Romain Guy06882f82009-06-10 13:36:04 -07004000
Craig Mautner5c0e78c2012-09-12 16:45:36 -07004001 atoken.requestedOrientation = requestedOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004002 }
4003 }
Romain Guy06882f82009-06-10 13:36:04 -07004004
Craig Mautner76a71652012-09-03 23:23:58 -07004005 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004006 public int getAppOrientation(IApplicationToken token) {
4007 synchronized(mWindowMap) {
4008 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
4009 if (wtoken == null) {
4010 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4011 }
Romain Guy06882f82009-06-10 13:36:04 -07004012
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004013 return wtoken.requestedOrientation;
4014 }
4015 }
Romain Guy06882f82009-06-10 13:36:04 -07004016
Craig Mautner76a71652012-09-03 23:23:58 -07004017 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004018 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
4019 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4020 "setFocusedApp()")) {
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 }
4023
4024 synchronized(mWindowMap) {
4025 boolean changed = false;
4026 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004027 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004028 changed = mFocusedApp != null;
4029 mFocusedApp = null;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004030 if (changed) {
4031 mInputMonitor.setFocusedAppLw(null);
Jeff Brown349703e2010-06-22 01:27:15 -07004032 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004033 } else {
4034 AppWindowToken newFocus = findAppWindowToken(token);
4035 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004036 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004037 return;
4038 }
4039 changed = mFocusedApp != newFocus;
4040 mFocusedApp = newFocus;
Craig Mautner812d2ca2012-09-27 15:35:34 -07004041 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp
4042 + " moveFocusNow=" + moveFocusNow);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004043 if (changed) {
4044 mInputMonitor.setFocusedAppLw(newFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07004045 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004046 }
4047
4048 if (moveFocusNow && changed) {
4049 final long origId = Binder.clearCallingIdentity();
Jeff Brown3a22cd92011-01-21 13:59:04 -08004050 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004051 Binder.restoreCallingIdentity(origId);
4052 }
4053 }
4054 }
4055
Craig Mautner76a71652012-09-03 23:23:58 -07004056 @Override
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08004057 public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004058 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4059 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004060 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004061 }
Romain Guy06882f82009-06-10 13:36:04 -07004062
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004063 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004064 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004065 TAG, "Prepare app transition: transit=" + transit
Craig Mautner0afddcb2012-05-08 15:38:00 -07004066 + " mNextAppTransition=" + mNextAppTransition
Craig Mautner1d961d42012-05-27 12:02:11 -07004067 + " alwaysKeepCurrent=" + alwaysKeepCurrent
Craig Mautneref25d7a2012-05-15 23:01:47 -07004068 + " Callers=" + Debug.getCallers(3));
Craig Mautner2fb98b12012-03-20 17:24:00 -07004069 if (okToDisplay()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004070 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
4071 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004072 mNextAppTransition = transit;
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08004073 } else if (!alwaysKeepCurrent) {
4074 if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
4075 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
4076 // Opening a new task always supersedes a close for the anim.
4077 mNextAppTransition = transit;
4078 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
4079 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
4080 // Opening a new activity always supersedes a close for the anim.
4081 mNextAppTransition = transit;
4082 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004083 }
4084 mAppTransitionReady = false;
4085 mAppTransitionTimeout = false;
4086 mStartingIconInTransition = false;
4087 mSkipAppTransitionAnimation = false;
4088 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
4089 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
4090 5000);
4091 }
4092 }
4093 }
4094
Craig Mautner5c0e78c2012-09-12 16:45:36 -07004095 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004096 public int getPendingAppTransition() {
4097 return mNextAppTransition;
4098 }
Romain Guy06882f82009-06-10 13:36:04 -07004099
Dianne Hackborn84375872012-06-01 19:03:50 -07004100 private void scheduleAnimationCallback(IRemoteCallback cb) {
4101 if (cb != null) {
4102 mH.sendMessage(mH.obtainMessage(H.DO_ANIMATION_CALLBACK, cb));
4103 }
4104 }
4105
Craig Mautner5c0e78c2012-09-12 16:45:36 -07004106 @Override
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07004107 public void overridePendingAppTransition(String packageName,
Dianne Hackborn84375872012-06-01 19:03:50 -07004108 int enterAnim, int exitAnim, IRemoteCallback startedCallback) {
4109 synchronized(mWindowMap) {
4110 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
4111 mNextAppTransitionType = ActivityOptions.ANIM_CUSTOM;
4112 mNextAppTransitionPackage = packageName;
4113 mNextAppTransitionThumbnail = null;
4114 mNextAppTransitionEnter = enterAnim;
4115 mNextAppTransitionExit = exitAnim;
4116 scheduleAnimationCallback(mNextAppTransitionCallback);
4117 mNextAppTransitionCallback = startedCallback;
4118 } else {
4119 scheduleAnimationCallback(startedCallback);
4120 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07004121 }
4122 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004123
Craig Mautnera91f9e22012-09-14 16:22:08 -07004124 @Override
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07004125 public void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
4126 int startHeight) {
Dianne Hackborn84375872012-06-01 19:03:50 -07004127 synchronized(mWindowMap) {
4128 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
4129 mNextAppTransitionType = ActivityOptions.ANIM_SCALE_UP;
4130 mNextAppTransitionPackage = null;
4131 mNextAppTransitionThumbnail = null;
4132 mNextAppTransitionStartX = startX;
4133 mNextAppTransitionStartY = startY;
4134 mNextAppTransitionStartWidth = startWidth;
4135 mNextAppTransitionStartHeight = startHeight;
4136 scheduleAnimationCallback(mNextAppTransitionCallback);
4137 mNextAppTransitionCallback = null;
4138 }
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07004139 }
4140 }
4141
Craig Mautnera91f9e22012-09-14 16:22:08 -07004142 @Override
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004143 public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX,
Michael Jurka832cb222012-04-13 09:32:47 -07004144 int startY, IRemoteCallback startedCallback, boolean scaleUp) {
Dianne Hackborn84375872012-06-01 19:03:50 -07004145 synchronized(mWindowMap) {
4146 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Michael Jurka832cb222012-04-13 09:32:47 -07004147 mNextAppTransitionType = scaleUp
4148 ? ActivityOptions.ANIM_THUMBNAIL_SCALE_UP : ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN;
Dianne Hackborn84375872012-06-01 19:03:50 -07004149 mNextAppTransitionPackage = null;
4150 mNextAppTransitionThumbnail = srcThumb;
Michael Jurka832cb222012-04-13 09:32:47 -07004151 mNextAppTransitionScaleUp = scaleUp;
Dianne Hackborn84375872012-06-01 19:03:50 -07004152 mNextAppTransitionStartX = startX;
4153 mNextAppTransitionStartY = startY;
4154 scheduleAnimationCallback(mNextAppTransitionCallback);
4155 mNextAppTransitionCallback = startedCallback;
4156 } else {
4157 scheduleAnimationCallback(startedCallback);
4158 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004159 }
4160 }
4161
Craig Mautnera91f9e22012-09-14 16:22:08 -07004162 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004163 public void executeAppTransition() {
4164 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4165 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004166 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004167 }
Romain Guy06882f82009-06-10 13:36:04 -07004168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004169 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07004170 if (DEBUG_APP_TRANSITIONS) {
4171 RuntimeException e = new RuntimeException("here");
4172 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004173 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07004174 + mNextAppTransition, e);
4175 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004176 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004177 mAppTransitionReady = true;
4178 final long origId = Binder.clearCallingIdentity();
4179 performLayoutAndPlaceSurfacesLocked();
4180 Binder.restoreCallingIdentity(origId);
4181 }
4182 }
4183 }
4184
4185 public void setAppStartingWindow(IBinder token, String pkg,
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07004186 int theme, CompatibilityInfo compatInfo,
4187 CharSequence nonLocalizedLabel, int labelRes, int icon,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08004188 int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004189 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner6fbda632012-07-03 09:26:39 -07004190 "setAppStartingWindow()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004191 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004192 }
4193
4194 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004195 if (DEBUG_STARTING_WINDOW) Slog.v(
Craig Mautner8863cca2012-09-18 15:04:34 -07004196 TAG, "setAppStartingWindow: token=" + token + " pkg=" + pkg
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004197 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07004198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004199 AppWindowToken wtoken = findAppWindowToken(token);
4200 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004201 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004202 return;
4203 }
4204
4205 // If the display is frozen, we won't do anything until the
4206 // actual window is displayed so there is no reason to put in
4207 // the starting window.
Craig Mautner2fb98b12012-03-20 17:24:00 -07004208 if (!okToDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004209 return;
4210 }
Romain Guy06882f82009-06-10 13:36:04 -07004211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004212 if (wtoken.startingData != null) {
4213 return;
4214 }
Romain Guy06882f82009-06-10 13:36:04 -07004215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004216 if (transferFrom != null) {
4217 AppWindowToken ttoken = findAppWindowToken(transferFrom);
4218 if (ttoken != null) {
4219 WindowState startingWindow = ttoken.startingWindow;
4220 if (startingWindow != null) {
4221 if (mStartingIconInTransition) {
4222 // In this case, the starting icon has already
4223 // been displayed, so start letting windows get
4224 // shown immediately without any more transitions.
4225 mSkipAppTransitionAnimation = true;
4226 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004227 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
Craig Mautner8863cca2012-09-18 15:04:34 -07004228 "Moving existing starting " + startingWindow + " from " + ttoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004229 + " to " + wtoken);
4230 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07004231
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004232 // Transfer the starting window over to the new
4233 // token.
4234 wtoken.startingData = ttoken.startingData;
4235 wtoken.startingView = ttoken.startingView;
Craig Mautnerf4120952012-06-21 18:25:39 -07004236 wtoken.startingDisplayed = ttoken.startingDisplayed;
Craig Mautner8863cca2012-09-18 15:04:34 -07004237 ttoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004238 wtoken.startingWindow = startingWindow;
Craig Mautnerf4120952012-06-21 18:25:39 -07004239 wtoken.reportedVisible = ttoken.reportedVisible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004240 ttoken.startingData = null;
4241 ttoken.startingView = null;
4242 ttoken.startingWindow = null;
4243 ttoken.startingMoved = true;
4244 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07004245 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004246 startingWindow.mAppToken = wtoken;
Craig Mautner8863cca2012-09-18 15:04:34 -07004247 startingWindow.mWinAnimator.mAppAnimator = wtoken.mAppAnimator;
4248
Craig Mautner6fbda632012-07-03 09:26:39 -07004249 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) {
4250 Slog.v(TAG, "Removing starting window: " + startingWindow);
4251 }
Craig Mautner59c00972012-07-30 12:10:24 -07004252 startingWindow.getWindowList().remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004253 mWindowsChanged = true;
Craig Mautner6fbda632012-07-03 09:26:39 -07004254 if (DEBUG_ADD_REMOVE) Slog.v(TAG,
4255 "Removing starting " + startingWindow + " from " + ttoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004256 ttoken.windows.remove(startingWindow);
4257 ttoken.allAppWindows.remove(startingWindow);
4258 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07004259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004260 // Propagate other interesting state between the
4261 // tokens. If the old token is displayed, we should
4262 // immediately force the new one to be displayed. If
4263 // it is animating, we need to move that animation to
4264 // the new one.
4265 if (ttoken.allDrawn) {
4266 wtoken.allDrawn = true;
4267 }
4268 if (ttoken.firstWindowDrawn) {
4269 wtoken.firstWindowDrawn = true;
4270 }
4271 if (!ttoken.hidden) {
4272 wtoken.hidden = false;
4273 wtoken.hiddenRequested = false;
4274 wtoken.willBeHidden = false;
4275 }
4276 if (wtoken.clientHidden != ttoken.clientHidden) {
4277 wtoken.clientHidden = ttoken.clientHidden;
4278 wtoken.sendAppVisibilityToClients();
4279 }
Craig Mautner59431632012-04-04 11:56:44 -07004280 final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
4281 final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
4282 if (tAppAnimator.animation != null) {
4283 wAppAnimator.animation = tAppAnimator.animation;
4284 wAppAnimator.animating = tAppAnimator.animating;
4285 wAppAnimator.animLayerAdjustment = tAppAnimator.animLayerAdjustment;
4286 tAppAnimator.animation = null;
4287 tAppAnimator.animLayerAdjustment = 0;
4288 wAppAnimator.updateLayers();
4289 tAppAnimator.updateLayers();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004290 }
Romain Guy06882f82009-06-10 13:36:04 -07004291
Jeff Brown3a22cd92011-01-21 13:59:04 -08004292 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4293 true /*updateInputWindows*/);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07004294 getDefaultDisplayContentLocked().layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004295 performLayoutAndPlaceSurfacesLocked();
4296 Binder.restoreCallingIdentity(origId);
4297 return;
4298 } else if (ttoken.startingData != null) {
4299 // The previous app was getting ready to show a
4300 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004301 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004302 "Moving pending starting from " + ttoken
4303 + " to " + wtoken);
4304 wtoken.startingData = ttoken.startingData;
4305 ttoken.startingData = null;
4306 ttoken.startingMoved = true;
4307 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
4308 // Note: we really want to do sendMessageAtFrontOfQueue() because we
4309 // want to process the message ASAP, before any other queued
4310 // messages.
4311 mH.sendMessageAtFrontOfQueue(m);
4312 return;
4313 }
Craig Mautner59431632012-04-04 11:56:44 -07004314 final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
4315 final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
4316 if (tAppAnimator.thumbnail != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004317 // The old token is animating with a thumbnail, transfer
4318 // that to the new token.
Craig Mautner59431632012-04-04 11:56:44 -07004319 if (wAppAnimator.thumbnail != null) {
4320 wAppAnimator.thumbnail.destroy();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004321 }
Craig Mautner59431632012-04-04 11:56:44 -07004322 wAppAnimator.thumbnail = tAppAnimator.thumbnail;
4323 wAppAnimator.thumbnailX = tAppAnimator.thumbnailX;
4324 wAppAnimator.thumbnailY = tAppAnimator.thumbnailY;
4325 wAppAnimator.thumbnailLayer = tAppAnimator.thumbnailLayer;
4326 wAppAnimator.thumbnailAnimation = tAppAnimator.thumbnailAnimation;
4327 tAppAnimator.thumbnail = null;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004328 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004329 }
4330 }
4331
4332 // There is no existing starting window, and the caller doesn't
4333 // want us to create one, so that's it!
4334 if (!createIfNeeded) {
4335 return;
4336 }
Romain Guy06882f82009-06-10 13:36:04 -07004337
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08004338 // If this is a translucent window, then don't
Dianne Hackborn284ac932009-08-28 10:34:25 -07004339 // show a starting window -- the current effect (a full-screen
4340 // opaque starting window that fades away to the real contents
4341 // when it is ready) does not work for this.
Craig Mautner6fbda632012-07-03 09:26:39 -07004342 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Checking theme of starting window: 0x"
4343 + Integer.toHexString(theme));
Dianne Hackborn284ac932009-08-28 10:34:25 -07004344 if (theme != 0) {
4345 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
4346 com.android.internal.R.styleable.Window);
Dianne Hackborn0b800192012-06-21 15:29:36 -07004347 if (ent == null) {
4348 // Whoops! App doesn't exist. Um. Okay. We'll just
4349 // pretend like we didn't see that.
4350 return;
4351 }
Craig Mautner6fbda632012-07-03 09:26:39 -07004352 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Translucent="
4353 + ent.array.getBoolean(
4354 com.android.internal.R.styleable.Window_windowIsTranslucent, false)
4355 + " Floating="
4356 + ent.array.getBoolean(
4357 com.android.internal.R.styleable.Window_windowIsFloating, false)
4358 + " ShowWallpaper="
4359 + ent.array.getBoolean(
4360 com.android.internal.R.styleable.Window_windowShowWallpaper, false));
Dianne Hackborn284ac932009-08-28 10:34:25 -07004361 if (ent.array.getBoolean(
4362 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
4363 return;
4364 }
4365 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07004366 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
4367 return;
4368 }
4369 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07004370 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08004371 if (mWallpaperTarget == null) {
4372 // If this theme is requesting a wallpaper, and the wallpaper
4373 // is not curently visible, then this effectively serves as
4374 // an opaque window and our starting window transition animation
4375 // can still work. We just need to make sure the starting window
4376 // is also showing the wallpaper.
Craig Mautner65d11b32012-10-01 13:59:52 -07004377 windowFlags |= FLAG_SHOW_WALLPAPER;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08004378 } else {
4379 return;
4380 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07004381 }
4382 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004383
Craig Mautner6fbda632012-07-03 09:26:39 -07004384 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Creating StartingData");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004385 mStartingIconInTransition = true;
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07004386 wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08004387 labelRes, icon, windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004388 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
4389 // Note: we really want to do sendMessageAtFrontOfQueue() because we
4390 // want to process the message ASAP, before any other queued
4391 // messages.
Craig Mautner6fbda632012-07-03 09:26:39 -07004392 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Enqueueing ADD_STARTING");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004393 mH.sendMessageAtFrontOfQueue(m);
4394 }
4395 }
4396
4397 public void setAppWillBeHidden(IBinder token) {
4398 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4399 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004400 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004401 }
4402
4403 AppWindowToken wtoken;
4404
4405 synchronized(mWindowMap) {
4406 wtoken = findAppWindowToken(token);
4407 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004408 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 -08004409 return;
4410 }
4411 wtoken.willBeHidden = true;
4412 }
4413 }
Romain Guy06882f82009-06-10 13:36:04 -07004414
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004415 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004416 boolean visible, int transit, boolean performLayout) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004417 boolean delayed = false;
4418
4419 if (wtoken.clientHidden == visible) {
4420 wtoken.clientHidden = !visible;
4421 wtoken.sendAppVisibilityToClients();
4422 }
Romain Guy06882f82009-06-10 13:36:04 -07004423
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004424 wtoken.willBeHidden = false;
4425 if (wtoken.hidden == visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004426 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004427 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004428 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
4429 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07004430
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004431 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07004432
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004433 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
Craig Mautnerfbf378c2012-04-23 17:24:21 -07004434 if (wtoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) {
Craig Mautner59431632012-04-04 11:56:44 -07004435 wtoken.mAppAnimator.animation = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004436 }
Craig Mautnerf20588f2012-04-11 17:06:21 -07004437 if (applyAnimationLocked(wtoken, lp, transit, visible)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004438 delayed = runningAppAnimation = true;
4439 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07004440 WindowState window = wtoken.findMainWindow();
4441 if (window != null) {
4442 scheduleNotifyWindowTranstionIfNeededLocked(window, transit);
4443 }
Craig Mautnerf20588f2012-04-11 17:06:21 -07004444 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004445 }
Romain Guy06882f82009-06-10 13:36:04 -07004446
Craig Mautnerf20588f2012-04-11 17:06:21 -07004447 final int N = wtoken.allAppWindows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004448 for (int i=0; i<N; i++) {
4449 WindowState win = wtoken.allAppWindows.get(i);
4450 if (win == wtoken.startingWindow) {
4451 continue;
4452 }
4453
Joe Onorato8a9b2202010-02-26 18:56:32 -08004454 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004455 //win.dump(" ");
4456 if (visible) {
4457 if (!win.isVisibleNow()) {
4458 if (!runningAppAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07004459 win.mWinAnimator.applyAnimationLocked(
4460 WindowManagerPolicy.TRANSIT_ENTER, true);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07004461 scheduleNotifyWindowTranstionIfNeededLocked(win,
4462 WindowManagerPolicy.TRANSIT_ENTER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004463 }
4464 changed = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07004465 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004466 }
4467 } else if (win.isVisibleNow()) {
4468 if (!runningAppAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07004469 win.mWinAnimator.applyAnimationLocked(
4470 WindowManagerPolicy.TRANSIT_EXIT, false);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07004471 scheduleNotifyWindowTranstionIfNeededLocked(win,
4472 WindowManagerPolicy.TRANSIT_EXIT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004473 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004474 changed = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07004475 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004476 }
4477 }
4478
4479 wtoken.hidden = wtoken.hiddenRequested = !visible;
4480 if (!visible) {
4481 unsetAppFreezingScreenLocked(wtoken, true, true);
4482 } else {
4483 // If we are being set visible, and the starting window is
4484 // not yet displayed, then make sure it doesn't get displayed.
4485 WindowState swin = wtoken.startingWindow;
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07004486 if (swin != null && !swin.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004487 swin.mPolicyVisibility = false;
4488 swin.mPolicyVisibilityAfterAnim = false;
4489 }
4490 }
Romain Guy06882f82009-06-10 13:36:04 -07004491
Joe Onorato8a9b2202010-02-26 18:56:32 -08004492 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004493 + ": hidden=" + wtoken.hidden + " hiddenRequested="
4494 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07004495
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004496 if (changed) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08004497 mInputMonitor.setUpdateInputWindowsNeededLw();
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004498 if (performLayout) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08004499 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4500 false /*updateInputWindows*/);
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004501 performLayoutAndPlaceSurfacesLocked();
4502 }
Jeff Brown2e44b072011-01-24 15:21:56 -08004503 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004504 }
4505 }
4506
Craig Mautner59431632012-04-04 11:56:44 -07004507 if (wtoken.mAppAnimator.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004508 delayed = true;
4509 }
Romain Guy06882f82009-06-10 13:36:04 -07004510
Craig Mautnerf20588f2012-04-11 17:06:21 -07004511 for (int i = wtoken.allAppWindows.size() - 1; i >= 0 && !delayed; i--) {
4512 if (wtoken.allAppWindows.get(i).mWinAnimator.isWindowAnimating()) {
4513 delayed = true;
4514 }
4515 }
4516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004517 return delayed;
4518 }
4519
4520 public void setAppVisibility(IBinder token, boolean visible) {
4521 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4522 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004523 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004524 }
4525
4526 AppWindowToken wtoken;
4527
4528 synchronized(mWindowMap) {
4529 wtoken = findAppWindowToken(token);
4530 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004531 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004532 return;
4533 }
4534
4535 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004536 RuntimeException e = null;
4537 if (!HIDE_STACK_CRAWLS) {
4538 e = new RuntimeException();
4539 e.fillInStackTrace();
4540 }
Craig Mautner0afddcb2012-05-08 15:38:00 -07004541 Slog.v(TAG, "setAppVisibility(" + token + ", visible=" + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004542 + "): mNextAppTransition=" + mNextAppTransition
4543 + " hidden=" + wtoken.hidden
4544 + " hiddenRequested=" + wtoken.hiddenRequested, e);
4545 }
Romain Guy06882f82009-06-10 13:36:04 -07004546
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004547 // If we are preparing an app transition, then delay changing
4548 // the visibility of this token until we execute that transition.
Craig Mautner2fb98b12012-03-20 17:24:00 -07004549 if (okToDisplay() && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004550 // Already in requested state, don't do anything more.
4551 if (wtoken.hiddenRequested != visible) {
4552 return;
4553 }
4554 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07004555
Craig Mautnerf4120952012-06-21 18:25:39 -07004556 if (!wtoken.startingDisplayed) {
Craig Mautner8863cca2012-09-18 15:04:34 -07004557 if (DEBUG_APP_TRANSITIONS) Slog.v(
4558 TAG, "Setting dummy animation on: " + wtoken);
Craig Mautnerf4120952012-06-21 18:25:39 -07004559 wtoken.mAppAnimator.setDummyAnimation();
4560 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004561 mOpeningApps.remove(wtoken);
4562 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004563 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004564 wtoken.inPendingTransaction = true;
4565 if (visible) {
4566 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004567 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004568
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004569 // If the token is currently hidden (should be the
4570 // common case), then we need to set up to wait for
4571 // its windows to be ready.
4572 if (wtoken.hidden) {
4573 wtoken.allDrawn = false;
4574 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004575
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004576 if (wtoken.clientHidden) {
4577 // In the case where we are making an app visible
4578 // but holding off for a transition, we still need
4579 // to tell the client to make its windows visible so
4580 // they get drawn. Otherwise, we will wait on
4581 // performing the transition until all windows have
4582 // been drawn, they never will be, and we are sad.
4583 wtoken.clientHidden = false;
4584 wtoken.sendAppVisibilityToClients();
4585 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004586 }
4587 } else {
4588 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004589
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004590 // If the token is currently visible (should be the
4591 // common case), then set up to wait for it to be hidden.
4592 if (!wtoken.hidden) {
4593 wtoken.waitingToHide = true;
4594 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004595 }
4596 return;
4597 }
Romain Guy06882f82009-06-10 13:36:04 -07004598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004599 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004600 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004601 true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004602 wtoken.updateReportedVisibilityLocked();
4603 Binder.restoreCallingIdentity(origId);
4604 }
4605 }
4606
4607 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
4608 boolean unfreezeSurfaceNow, boolean force) {
Craig Mautner59431632012-04-04 11:56:44 -07004609 if (wtoken.mAppAnimator.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004610 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004611 + " force=" + force);
4612 final int N = wtoken.allAppWindows.size();
4613 boolean unfrozeWindows = false;
4614 for (int i=0; i<N; i++) {
4615 WindowState w = wtoken.allAppWindows.get(i);
4616 if (w.mAppFreezing) {
4617 w.mAppFreezing = false;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07004618 if (w.mHasSurface && !w.mOrientationChanging) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07004619 if (DEBUG_ORIENTATION) Slog.v(TAG, "set mOrientationChanging of " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004620 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07004621 mInnerFields.mOrientationChangeComplete = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004622 }
4623 unfrozeWindows = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07004624 w.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004625 }
4626 }
4627 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004628 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
Craig Mautner59431632012-04-04 11:56:44 -07004629 wtoken.mAppAnimator.freezingScreen = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004630 mAppsFreezingScreen--;
4631 }
4632 if (unfreezeSurfaceNow) {
4633 if (unfrozeWindows) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004634 performLayoutAndPlaceSurfacesLocked();
4635 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004636 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004637 }
4638 }
4639 }
Romain Guy06882f82009-06-10 13:36:04 -07004640
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004641 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
4642 int configChanges) {
4643 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004644 RuntimeException e = null;
4645 if (!HIDE_STACK_CRAWLS) {
4646 e = new RuntimeException();
4647 e.fillInStackTrace();
4648 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004649 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004650 + ": hidden=" + wtoken.hidden + " freezing="
Craig Mautner59431632012-04-04 11:56:44 -07004651 + wtoken.mAppAnimator.freezingScreen, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004652 }
4653 if (!wtoken.hiddenRequested) {
Craig Mautner59431632012-04-04 11:56:44 -07004654 if (!wtoken.mAppAnimator.freezingScreen) {
4655 wtoken.mAppAnimator.freezingScreen = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004656 mAppsFreezingScreen++;
4657 if (mAppsFreezingScreen == 1) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07004658 startFreezingDisplayLocked(false, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004659 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
4660 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
4661 5000);
4662 }
4663 }
4664 final int N = wtoken.allAppWindows.size();
4665 for (int i=0; i<N; i++) {
4666 WindowState w = wtoken.allAppWindows.get(i);
4667 w.mAppFreezing = true;
4668 }
4669 }
4670 }
Romain Guy06882f82009-06-10 13:36:04 -07004671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004672 public void startAppFreezingScreen(IBinder token, int configChanges) {
4673 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4674 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004675 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004676 }
4677
4678 synchronized(mWindowMap) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07004679 if (configChanges == 0 && okToDisplay()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004680 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004681 return;
4682 }
Romain Guy06882f82009-06-10 13:36:04 -07004683
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004684 AppWindowToken wtoken = findAppWindowToken(token);
4685 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004686 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004687 return;
4688 }
4689 final long origId = Binder.clearCallingIdentity();
4690 startAppFreezingScreenLocked(wtoken, configChanges);
4691 Binder.restoreCallingIdentity(origId);
4692 }
4693 }
Romain Guy06882f82009-06-10 13:36:04 -07004694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004695 public void stopAppFreezingScreen(IBinder token, boolean force) {
4696 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4697 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004698 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004699 }
4700
4701 synchronized(mWindowMap) {
4702 AppWindowToken wtoken = findAppWindowToken(token);
4703 if (wtoken == null || wtoken.appToken == null) {
4704 return;
4705 }
4706 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004707 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
Craig Mautner59431632012-04-04 11:56:44 -07004708 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.mAppAnimator.freezingScreen);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004709 unsetAppFreezingScreenLocked(wtoken, true, force);
4710 Binder.restoreCallingIdentity(origId);
4711 }
4712 }
Romain Guy06882f82009-06-10 13:36:04 -07004713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004714 public void removeAppToken(IBinder token) {
4715 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4716 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004717 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004718 }
4719
4720 AppWindowToken wtoken = null;
4721 AppWindowToken startingToken = null;
4722 boolean delayed = false;
4723
4724 final long origId = Binder.clearCallingIdentity();
4725 synchronized(mWindowMap) {
4726 WindowToken basewtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004727 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004728 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004729 delayed = setTokenVisibilityLocked(wtoken, null, false,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004730 WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004731 wtoken.inPendingTransaction = false;
4732 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004733 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004734 if (mClosingApps.contains(wtoken)) {
4735 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004736 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004737 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004738 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004739 delayed = true;
4740 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004741 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004742 TAG, "Removing app " + wtoken + " delayed=" + delayed
Craig Mautner59431632012-04-04 11:56:44 -07004743 + " animation=" + wtoken.mAppAnimator.animation
4744 + " animating=" + wtoken.mAppAnimator.animating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004745 if (delayed) {
4746 // set the token aside because it has an active animation to be finished
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004747 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4748 "removeAppToken make exiting: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004749 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004750 } else {
4751 // Make sure there is no animation running on this token,
4752 // so any windows associated with it will be removed as
4753 // soon as their animations are complete
Craig Mautner59431632012-04-04 11:56:44 -07004754 wtoken.mAppAnimator.clearAnimation();
4755 wtoken.mAppAnimator.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004756 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004757 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4758 "removeAppToken: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004759 mAppTokens.remove(wtoken);
Craig Mautneref25d7a2012-05-15 23:01:47 -07004760 mAnimatingAppTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004761 wtoken.removed = true;
4762 if (wtoken.startingData != null) {
4763 startingToken = wtoken;
4764 }
4765 unsetAppFreezingScreenLocked(wtoken, true, true);
4766 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004767 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004768 mFocusedApp = null;
Jeff Brown3a22cd92011-01-21 13:59:04 -08004769 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004770 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004771 }
4772 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004773 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004774 }
Romain Guy06882f82009-06-10 13:36:04 -07004775
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004776 if (!delayed && wtoken != null) {
4777 wtoken.updateReportedVisibilityLocked();
4778 }
4779 }
4780 Binder.restoreCallingIdentity(origId);
4781
4782 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004783 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004784 + startingToken + ": app token removed");
4785 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
4786 mH.sendMessage(m);
4787 }
4788 }
4789
4790 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
4791 final int NW = token.windows.size();
Craig Mautneref25d7a2012-05-15 23:01:47 -07004792 if (NW > 0) {
4793 mWindowsChanged = true;
4794 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004795 for (int i=0; i<NW; i++) {
4796 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004797 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
Craig Mautner59c00972012-07-30 12:10:24 -07004798 win.getWindowList().remove(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004799 int j = win.mChildWindows.size();
4800 while (j > 0) {
4801 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004802 WindowState cwin = win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004803 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004804 "Tmp removing child window " + cwin);
Craig Mautner59c00972012-07-30 12:10:24 -07004805 cwin.getWindowList().remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004806 }
4807 }
4808 return NW > 0;
4809 }
4810
4811 void dumpAppTokensLocked() {
4812 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004813 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004814 }
4815 }
Romain Guy06882f82009-06-10 13:36:04 -07004816
Craig Mautneref25d7a2012-05-15 23:01:47 -07004817 void dumpAnimatingAppTokensLocked() {
4818 for (int i=mAnimatingAppTokens.size()-1; i>=0; i--) {
4819 Slog.v(TAG, " #" + i + ": " + mAnimatingAppTokens.get(i).token);
4820 }
4821 }
4822
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004823 void dumpWindowsLocked() {
Craig Mautner59c00972012-07-30 12:10:24 -07004824 int i = 0;
4825 final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
4826 while (iterator.hasNext()) {
4827 final WindowState w = iterator.next();
4828 Slog.v(TAG, " #" + i++ + ": " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004829 }
4830 }
Romain Guy06882f82009-06-10 13:36:04 -07004831
Craig Mautner59c00972012-07-30 12:10:24 -07004832 private int findWindowOffsetLocked(WindowList windows, int tokenPos) {
4833 final int NW = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004834
Craig Mautneref25d7a2012-05-15 23:01:47 -07004835 if (tokenPos >= mAnimatingAppTokens.size()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004836 int i = NW;
4837 while (i > 0) {
4838 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07004839 WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004840 if (win.getAppToken() != null) {
4841 return i+1;
4842 }
4843 }
4844 }
4845
4846 while (tokenPos > 0) {
4847 // Find the first app token below the new position that has
4848 // a window displayed.
Craig Mautner59c00972012-07-30 12:10:24 -07004849 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004850 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004851 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004852 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004853 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07004854 "Skipping token -- currently sending to bottom");
4855 tokenPos--;
4856 continue;
4857 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004858 int i = wtoken.windows.size();
4859 while (i > 0) {
4860 i--;
4861 WindowState win = wtoken.windows.get(i);
4862 int j = win.mChildWindows.size();
4863 while (j > 0) {
4864 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004865 WindowState cwin = win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004866 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004867 for (int pos=NW-1; pos>=0; pos--) {
Craig Mautner59c00972012-07-30 12:10:24 -07004868 if (windows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004869 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004870 "Found child win @" + (pos+1));
4871 return pos+1;
4872 }
4873 }
4874 }
4875 }
4876 for (int pos=NW-1; pos>=0; pos--) {
Craig Mautner59c00972012-07-30 12:10:24 -07004877 if (windows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004878 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004879 return pos+1;
4880 }
4881 }
4882 }
4883 tokenPos--;
4884 }
4885
4886 return 0;
4887 }
4888
4889 private final int reAddWindowLocked(int index, WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -07004890 final WindowList windows = win.getWindowList();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004891 final int NCW = win.mChildWindows.size();
4892 boolean added = false;
4893 for (int j=0; j<NCW; j++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004894 WindowState cwin = win.mChildWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004895 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004896 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004897 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004898 win.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004899 windows.add(index, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004900 index++;
4901 added = true;
4902 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004903 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004904 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004905 cwin.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004906 windows.add(index, cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004907 index++;
4908 }
4909 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004910 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004911 + index + ": " + win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004912 win.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004913 windows.add(index, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004914 index++;
4915 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004916 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004917 return index;
4918 }
Romain Guy06882f82009-06-10 13:36:04 -07004919
Craig Mautner59c00972012-07-30 12:10:24 -07004920 private final int reAddAppWindowsLocked(final DisplayContent displayContent, int index,
4921 WindowToken token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004922 final int NW = token.windows.size();
4923 for (int i=0; i<NW; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07004924 final WindowState win = token.windows.get(i);
4925 if (win.mDisplayContent == displayContent) {
Craig Mautner69b08182012-09-05 13:07:13 -07004926 index = reAddWindowLocked(index, win);
Craig Mautner59c00972012-07-30 12:10:24 -07004927 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004928 }
4929 return index;
4930 }
4931
4932 public void moveAppToken(int index, IBinder token) {
4933 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4934 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004935 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004936 }
4937
4938 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004939 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004940 if (DEBUG_REORDER) dumpAppTokensLocked();
4941 final AppWindowToken wtoken = findAppWindowToken(token);
Craig Mautneref25d7a2012-05-15 23:01:47 -07004942 final int oldIndex = mAppTokens.indexOf(wtoken);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004943 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
4944 "Start moving token " + wtoken + " initially at "
Craig Mautneref25d7a2012-05-15 23:01:47 -07004945 + oldIndex);
4946 if (oldIndex > index && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET
4947 && !mAppTransitionRunning) {
4948 // animation towards back has not started, copy old list for duration of animation.
4949 mAnimatingAppTokens.clear();
4950 mAnimatingAppTokens.addAll(mAppTokens);
4951 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004952 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004953 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004954 + token + " (" + wtoken + ")");
4955 return;
4956 }
4957 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004958 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004959 else if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "Moved " + token + " to " + index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004960 if (DEBUG_REORDER) dumpAppTokensLocked();
Craig Mautneref25d7a2012-05-15 23:01:47 -07004961 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET && !mAppTransitionRunning) {
4962 // Not animating, bring animating app list in line with mAppTokens.
4963 mAnimatingAppTokens.clear();
4964 mAnimatingAppTokens.addAll(mAppTokens);
Romain Guy06882f82009-06-10 13:36:04 -07004965
Craig Mautneref25d7a2012-05-15 23:01:47 -07004966 // Bring window ordering, window focus and input window in line with new app token
4967 final long origId = Binder.clearCallingIdentity();
4968 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004969 if (DEBUG_REORDER) dumpWindowsLocked();
Craig Mautneref25d7a2012-05-15 23:01:47 -07004970 if (tmpRemoveAppWindowsLocked(wtoken)) {
4971 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
4972 if (DEBUG_REORDER) dumpWindowsLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07004973 DisplayContentsIterator iterator = new DisplayContentsIterator();
4974 while(iterator.hasNext()) {
4975 final DisplayContent displayContent = iterator.next();
4976 final WindowList windows = displayContent.getWindowList();
4977 final int pos = findWindowOffsetLocked(windows, index);
Craig Mautner19d59bc2012-09-04 11:15:56 -07004978 final int newPos = reAddAppWindowsLocked(displayContent, pos, wtoken);
4979 if (pos != newPos) {
4980 displayContent.layoutNeeded = true;
4981 }
Craig Mautner59c00972012-07-30 12:10:24 -07004982 }
Craig Mautneref25d7a2012-05-15 23:01:47 -07004983 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
4984 if (DEBUG_REORDER) dumpWindowsLocked();
4985 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4986 false /*updateInputWindows*/);
Craig Mautneref25d7a2012-05-15 23:01:47 -07004987 mInputMonitor.setUpdateInputWindowsNeededLw();
4988 performLayoutAndPlaceSurfacesLocked();
4989 mInputMonitor.updateInputWindowsLw(false /*force*/);
4990 }
4991 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004992 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004993 }
4994 }
4995
4996 private void removeAppTokensLocked(List<IBinder> tokens) {
4997 // XXX This should be done more efficiently!
4998 // (take advantage of the fact that both lists should be
4999 // ordered in the same way.)
5000 int N = tokens.size();
5001 for (int i=0; i<N; i++) {
5002 IBinder token = tokens.get(i);
5003 final AppWindowToken wtoken = findAppWindowToken(token);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08005004 if (DEBUG_REORDER || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
5005 "Temporarily removing " + wtoken + " from " + mAppTokens.indexOf(wtoken));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005006 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005007 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005008 + token + " (" + wtoken + ")");
5009 i--;
5010 N--;
5011 }
5012 }
5013 }
5014
Dianne Hackborna8f60182009-09-01 19:01:50 -07005015 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
5016 boolean updateFocusAndLayout) {
5017 // First remove all of the windows from the list.
5018 tmpRemoveAppWindowsLocked(wtoken);
5019
Dianne Hackborna8f60182009-09-01 19:01:50 -07005020 // And now add them back at the correct place.
Craig Mautner59c00972012-07-30 12:10:24 -07005021 DisplayContentsIterator iterator = new DisplayContentsIterator();
5022 while (iterator.hasNext()) {
5023 final DisplayContent displayContent = iterator.next();
5024 final WindowList windows = displayContent.getWindowList();
5025 final int pos = findWindowOffsetLocked(windows, tokenPos);
Craig Mautner19d59bc2012-09-04 11:15:56 -07005026 final int newPos = reAddAppWindowsLocked(displayContent, pos, wtoken);
5027 if (pos != newPos) {
5028 displayContent.layoutNeeded = true;
5029 }
Craig Mautner59c00972012-07-30 12:10:24 -07005030
Craig Mautner4f67ba62012-08-02 11:23:00 -07005031 if (updateFocusAndLayout && !updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
Craig Mautner59c00972012-07-30 12:10:24 -07005032 false /*updateInputWindows*/)) {
5033 assignLayersLocked(windows);
5034 }
5035 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07005036
5037 if (updateFocusAndLayout) {
Jeff Brown2e44b072011-01-24 15:21:56 -08005038 mInputMonitor.setUpdateInputWindowsNeededLw();
Craig Mautner59c00972012-07-30 12:10:24 -07005039
5040 // Note that the above updateFocusedWindowLocked conditional used to sit here.
5041
Craig Mautneref25d7a2012-05-15 23:01:47 -07005042 if (!mInLayout) {
5043 performLayoutAndPlaceSurfacesLocked();
5044 }
Jeff Brown2e44b072011-01-24 15:21:56 -08005045 mInputMonitor.updateInputWindowsLw(false /*force*/);
Dianne Hackborna8f60182009-09-01 19:01:50 -07005046 }
5047 }
5048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005049 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
5050 // First remove all of the windows from the list.
5051 final int N = tokens.size();
5052 int i;
5053 for (i=0; i<N; i++) {
5054 WindowToken token = mTokenMap.get(tokens.get(i));
5055 if (token != null) {
5056 tmpRemoveAppWindowsLocked(token);
5057 }
5058 }
5059
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005060 // And now add them back at the correct place.
Craig Mautner59c00972012-07-30 12:10:24 -07005061 DisplayContentsIterator iterator = new DisplayContentsIterator();
5062 while (iterator.hasNext()) {
5063 final DisplayContent displayContent = iterator.next();
5064 final WindowList windows = displayContent.getWindowList();
5065 // Where to start adding?
5066 int pos = findWindowOffsetLocked(windows, tokenPos);
5067 for (i=0; i<N; i++) {
5068 WindowToken token = mTokenMap.get(tokens.get(i));
5069 if (token != null) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07005070 final int newPos = reAddAppWindowsLocked(displayContent, pos, token);
5071 if (newPos != pos) {
5072 displayContent.layoutNeeded = true;
5073 }
5074 pos = newPos;
Craig Mautner59c00972012-07-30 12:10:24 -07005075 }
5076 }
5077 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
5078 false /*updateInputWindows*/)) {
5079 assignLayersLocked(windows);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005080 }
5081 }
5082
Jeff Brown2e44b072011-01-24 15:21:56 -08005083 mInputMonitor.setUpdateInputWindowsNeededLw();
Craig Mautner59c00972012-07-30 12:10:24 -07005084
Craig Mautner4f67ba62012-08-02 11:23:00 -07005085 // Note that the above updateFocusedWindowLocked used to sit here.
Craig Mautner59c00972012-07-30 12:10:24 -07005086
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005087 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08005088 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005089
5090 //dump();
5091 }
5092
5093 public void moveAppTokensToTop(List<IBinder> tokens) {
5094 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5095 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005096 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005097 }
5098
5099 final long origId = Binder.clearCallingIdentity();
5100 synchronized(mWindowMap) {
5101 removeAppTokensLocked(tokens);
5102 final int N = tokens.size();
5103 for (int i=0; i<N; i++) {
5104 AppWindowToken wt = findAppWindowToken(tokens.get(i));
5105 if (wt != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08005106 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
5107 "Adding next to top: " + wt);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005108 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07005109 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07005110 wt.sendingToBottom = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -07005111 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005112 }
5113 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005114
Craig Mautner06a94f72012-05-29 10:46:00 -07005115 if (!mAppTransitionRunning) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07005116 mAnimatingAppTokens.clear();
5117 mAnimatingAppTokens.addAll(mAppTokens);
Dianne Hackborna8f60182009-09-01 19:01:50 -07005118 moveAppWindowsLocked(tokens, mAppTokens.size());
5119 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005120 }
5121 Binder.restoreCallingIdentity(origId);
5122 }
5123
Craig Mautneref25d7a2012-05-15 23:01:47 -07005124 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005125 public void moveAppTokensToBottom(List<IBinder> tokens) {
5126 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5127 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005128 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005129 }
5130
5131 final long origId = Binder.clearCallingIdentity();
5132 synchronized(mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005133 final int N = tokens.size();
Craig Mautner06a94f72012-05-29 10:46:00 -07005134 if (N > 0 && !mAppTransitionRunning) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07005135 // animating towards back, hang onto old list for duration of animation.
5136 mAnimatingAppTokens.clear();
5137 mAnimatingAppTokens.addAll(mAppTokens);
5138 }
5139 removeAppTokensLocked(tokens);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005140 int pos = 0;
5141 for (int i=0; i<N; i++) {
5142 AppWindowToken wt = findAppWindowToken(tokens.get(i));
5143 if (wt != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08005144 if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
5145 "Adding next to bottom: " + wt + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005146 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07005147 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07005148 wt.sendingToBottom = true;
5149 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005150 pos++;
5151 }
5152 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005153
Craig Mautner06a94f72012-05-29 10:46:00 -07005154 if (!mAppTransitionRunning) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07005155 mAnimatingAppTokens.clear();
5156 mAnimatingAppTokens.addAll(mAppTokens);
Dianne Hackborna8f60182009-09-01 19:01:50 -07005157 moveAppWindowsLocked(tokens, 0);
5158 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005159 }
5160 Binder.restoreCallingIdentity(origId);
5161 }
5162
5163 // -------------------------------------------------------------
5164 // Misc IWindowSession methods
5165 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07005166
Craig Mautner5642a482012-08-23 12:16:53 -07005167 @Override
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07005168 public void startFreezingScreen(int exitAnim, int enterAnim) {
5169 if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
5170 "startFreezingScreen()")) {
5171 throw new SecurityException("Requires FREEZE_SCREEN permission");
5172 }
5173
5174 synchronized(mWindowMap) {
5175 if (!mClientFreezingScreen) {
5176 mClientFreezingScreen = true;
5177 final long origId = Binder.clearCallingIdentity();
5178 try {
5179 startFreezingDisplayLocked(false, exitAnim, enterAnim);
5180 mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
5181 mH.sendMessageDelayed(mH.obtainMessage(H.CLIENT_FREEZE_TIMEOUT),
5182 5000);
5183 } finally {
5184 Binder.restoreCallingIdentity(origId);
5185 }
5186 }
5187 }
5188 }
5189
5190 @Override
5191 public void stopFreezingScreen() {
5192 if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
5193 "stopFreezingScreen()")) {
5194 throw new SecurityException("Requires FREEZE_SCREEN permission");
5195 }
5196
5197 synchronized(mWindowMap) {
5198 if (mClientFreezingScreen) {
5199 mClientFreezingScreen = false;
5200 final long origId = Binder.clearCallingIdentity();
5201 try {
5202 stopFreezingDisplayLocked();
5203 } finally {
5204 Binder.restoreCallingIdentity(origId);
5205 }
5206 }
5207 }
5208 }
5209
5210 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005211 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04005212 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005213 != PackageManager.PERMISSION_GRANTED) {
5214 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5215 }
Jim Millerd6b57052010-06-07 17:52:42 -07005216
Craig Mautner5642a482012-08-23 12:16:53 -07005217 mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage(
5218 KeyguardDisableHandler.KEYGUARD_DISABLE, new Pair<IBinder, String>(token, tag)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005219 }
5220
Craig Mautner5642a482012-08-23 12:16:53 -07005221 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005222 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04005223 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005224 != PackageManager.PERMISSION_GRANTED) {
5225 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5226 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005227
Craig Mautner5642a482012-08-23 12:16:53 -07005228 mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage(
5229 KeyguardDisableHandler.KEYGUARD_REENABLE, token));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005230 }
5231
5232 /**
5233 * @see android.app.KeyguardManager#exitKeyguardSecurely
5234 */
5235 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04005236 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005237 != PackageManager.PERMISSION_GRANTED) {
5238 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5239 }
5240 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
5241 public void onKeyguardExitResult(boolean success) {
5242 try {
5243 callback.onKeyguardExitResult(success);
5244 } catch (RemoteException e) {
5245 // Client has died, we don't care.
5246 }
5247 }
5248 });
5249 }
5250
5251 public boolean inKeyguardRestrictedInputMode() {
5252 return mPolicy.inKeyguardRestrictedKeyInputMode();
5253 }
Romain Guy06882f82009-06-10 13:36:04 -07005254
Mike Lockwood520d8bc2011-02-18 13:23:13 -05005255 public boolean isKeyguardLocked() {
5256 return mPolicy.isKeyguardLocked();
5257 }
5258
5259 public boolean isKeyguardSecure() {
5260 return mPolicy.isKeyguardSecure();
5261 }
5262
Dianne Hackborn90c52de2011-09-23 12:57:44 -07005263 public void dismissKeyguard() {
5264 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
5265 != PackageManager.PERMISSION_GRANTED) {
5266 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5267 }
5268 synchronized(mWindowMap) {
5269 mPolicy.dismissKeyguardLw();
5270 }
5271 }
5272
Dianne Hackbornffa42482009-09-23 22:20:11 -07005273 public void closeSystemDialogs(String reason) {
5274 synchronized(mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -07005275 final AllWindowsIterator iterator = new AllWindowsIterator();
5276 while (iterator.hasNext()) {
5277 final WindowState w = iterator.next();
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07005278 if (w.mHasSurface) {
Dianne Hackbornffa42482009-09-23 22:20:11 -07005279 try {
5280 w.mClient.closeSystemDialogs(reason);
5281 } catch (RemoteException e) {
5282 }
5283 }
5284 }
5285 }
5286 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005288 static float fixScale(float scale) {
5289 if (scale < 0) scale = 0;
5290 else if (scale > 20) scale = 20;
5291 return Math.abs(scale);
5292 }
Romain Guy06882f82009-06-10 13:36:04 -07005293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005294 public void setAnimationScale(int which, float scale) {
5295 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
5296 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005297 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005298 }
5299
5300 if (scale < 0) scale = 0;
5301 else if (scale > 20) scale = 20;
5302 scale = Math.abs(scale);
5303 switch (which) {
5304 case 0: mWindowAnimationScale = fixScale(scale); break;
5305 case 1: mTransitionAnimationScale = fixScale(scale); break;
Chet Haasec38fa1f2012-02-01 16:37:46 -08005306 case 2: mAnimatorDurationScale = fixScale(scale); break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005307 }
Romain Guy06882f82009-06-10 13:36:04 -07005308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005309 // Persist setting
5310 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
5311 }
Romain Guy06882f82009-06-10 13:36:04 -07005312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005313 public void setAnimationScales(float[] scales) {
5314 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
5315 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005316 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005317 }
5318
5319 if (scales != null) {
5320 if (scales.length >= 1) {
5321 mWindowAnimationScale = fixScale(scales[0]);
5322 }
5323 if (scales.length >= 2) {
5324 mTransitionAnimationScale = fixScale(scales[1]);
5325 }
Chet Haasec38fa1f2012-02-01 16:37:46 -08005326 if (scales.length >= 3) {
Jeff Brownff7e6ef2012-08-15 02:05:18 -07005327 setAnimatorDurationScale(fixScale(scales[2]));
Chet Haasec38fa1f2012-02-01 16:37:46 -08005328 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005329 }
Romain Guy06882f82009-06-10 13:36:04 -07005330
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005331 // Persist setting
5332 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
5333 }
Romain Guy06882f82009-06-10 13:36:04 -07005334
Jeff Brownff7e6ef2012-08-15 02:05:18 -07005335 private void setAnimatorDurationScale(float scale) {
5336 mAnimatorDurationScale = scale;
5337 ValueAnimator.setDurationScale(scale);
5338 }
5339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005340 public float getAnimationScale(int which) {
5341 switch (which) {
5342 case 0: return mWindowAnimationScale;
5343 case 1: return mTransitionAnimationScale;
Chet Haasec38fa1f2012-02-01 16:37:46 -08005344 case 2: return mAnimatorDurationScale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005345 }
5346 return 0;
5347 }
Romain Guy06882f82009-06-10 13:36:04 -07005348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005349 public float[] getAnimationScales() {
Chet Haasec38fa1f2012-02-01 16:37:46 -08005350 return new float[] { mWindowAnimationScale, mTransitionAnimationScale,
5351 mAnimatorDurationScale };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005352 }
Romain Guy06882f82009-06-10 13:36:04 -07005353
Jeff Brownac143512012-04-05 18:57:33 -07005354 // Called by window manager policy. Not exposed externally.
5355 @Override
5356 public int getLidState() {
Jeff Brownc458ce92012-04-30 14:58:40 -07005357 int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY,
5358 InputManagerService.SW_LID);
Jeff Brownac143512012-04-05 18:57:33 -07005359 if (sw > 0) {
Jeff Brown27fd3422012-04-09 11:05:16 -07005360 // Switch state: AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL.
Jeff Brownac143512012-04-05 18:57:33 -07005361 return LID_CLOSED;
Jeff Brown27fd3422012-04-09 11:05:16 -07005362 } else if (sw == 0) {
5363 // Switch state: AKEY_STATE_UP.
5364 return LID_OPEN;
Jeff Brownac143512012-04-05 18:57:33 -07005365 } else {
Jeff Brown27fd3422012-04-09 11:05:16 -07005366 // Switch state: AKEY_STATE_UNKNOWN.
Jeff Brownac143512012-04-05 18:57:33 -07005367 return LID_ABSENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005368 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005369 }
Romain Guy06882f82009-06-10 13:36:04 -07005370
Jeff Brownac143512012-04-05 18:57:33 -07005371 // Called by window manager policy. Not exposed externally.
5372 @Override
Jeff Browna41ca772010-08-11 14:46:32 -07005373 public InputChannel monitorInput(String inputChannelName) {
Jeff Browna41ca772010-08-11 14:46:32 -07005374 return mInputManager.monitorInput(inputChannelName);
5375 }
5376
Jeff Brown7304c342012-05-11 18:42:42 -07005377 // Called by window manager policy. Not exposed externally.
5378 @Override
Jeff Browncf39bdf2012-05-18 14:41:19 -07005379 public void switchKeyboardLayout(int deviceId, int direction) {
5380 mInputManager.switchKeyboardLayout(deviceId, direction);
5381 }
5382
5383 // Called by window manager policy. Not exposed externally.
5384 @Override
Jeff Brown9a538ee2012-08-20 14:56:57 -07005385 public void shutdown(boolean confirm) {
5386 ShutdownThread.shutdown(mContext, confirm);
Jeff Brown7304c342012-05-11 18:42:42 -07005387 }
5388
5389 // Called by window manager policy. Not exposed externally.
5390 @Override
Jeff Brown9a538ee2012-08-20 14:56:57 -07005391 public void rebootSafeMode(boolean confirm) {
5392 ShutdownThread.rebootSafeMode(mContext, confirm);
Jeff Brown7304c342012-05-11 18:42:42 -07005393 }
5394
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07005395 public void setInputFilter(IInputFilter filter) {
5396 if (!checkCallingPermission(android.Manifest.permission.FILTER_EVENTS, "setInputFilter()")) {
5397 throw new SecurityException("Requires FILTER_EVENTS permission");
5398 }
Jeff Brown0029c662011-03-30 02:25:18 -07005399 mInputManager.setInputFilter(filter);
5400 }
5401
Craig Mautnerf1b67412012-09-19 13:18:29 -07005402 public void setCurrentUser(final int newUserId) {
5403 synchronized (mWindowMap) {
5404 mCurrentUserId = newUserId;
5405 mPolicy.setCurrentUserLw(newUserId);
5406 }
5407 }
5408
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005409 public void enableScreenAfterBoot() {
5410 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005411 if (DEBUG_BOOT) {
5412 RuntimeException here = new RuntimeException("here");
5413 here.fillInStackTrace();
5414 Slog.i(TAG, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled
5415 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5416 + " mShowingBootMessages=" + mShowingBootMessages
5417 + " mSystemBooted=" + mSystemBooted, here);
5418 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005419 if (mSystemBooted) {
5420 return;
5421 }
5422 mSystemBooted = true;
Dianne Hackborn661cd522011-08-22 00:26:20 -07005423 hideBootMessagesLocked();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005424 // If the screen still doesn't come up after 30 seconds, give
5425 // up and turn it on.
5426 Message msg = mH.obtainMessage(H.BOOT_TIMEOUT);
5427 mH.sendMessageDelayed(msg, 30*1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005428 }
Romain Guy06882f82009-06-10 13:36:04 -07005429
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07005430 mPolicy.systemBooted();
5431
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005432 performEnableScreen();
5433 }
Romain Guy06882f82009-06-10 13:36:04 -07005434
Dianne Hackborn661cd522011-08-22 00:26:20 -07005435 void enableScreenIfNeededLocked() {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005436 if (DEBUG_BOOT) {
5437 RuntimeException here = new RuntimeException("here");
5438 here.fillInStackTrace();
5439 Slog.i(TAG, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled
5440 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5441 + " mShowingBootMessages=" + mShowingBootMessages
5442 + " mSystemBooted=" + mSystemBooted, here);
5443 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005444 if (mDisplayEnabled) {
5445 return;
5446 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005447 if (!mSystemBooted && !mShowingBootMessages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005448 return;
5449 }
5450 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
5451 }
Romain Guy06882f82009-06-10 13:36:04 -07005452
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005453 public void performBootTimeout() {
5454 synchronized(mWindowMap) {
Mike Lockwoodd747dc82011-09-13 16:28:22 -04005455 if (mDisplayEnabled || mHeadless) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005456 return;
5457 }
5458 Slog.w(TAG, "***** BOOT TIMEOUT: forcing display enabled");
5459 mForceDisplayEnabled = true;
5460 }
5461 performEnableScreen();
5462 }
5463
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005464 public void performEnableScreen() {
5465 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005466 if (DEBUG_BOOT) {
5467 RuntimeException here = new RuntimeException("here");
5468 here.fillInStackTrace();
5469 Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
5470 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5471 + " mShowingBootMessages=" + mShowingBootMessages
Jeff Brown780c46f2012-06-24 12:15:38 -07005472 + " mSystemBooted=" + mSystemBooted
5473 + " mOnlyCore=" + mOnlyCore, here);
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005474 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005475 if (mDisplayEnabled) {
5476 return;
5477 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005478 if (!mSystemBooted && !mShowingBootMessages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005479 return;
5480 }
Romain Guy06882f82009-06-10 13:36:04 -07005481
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005482 if (!mForceDisplayEnabled) {
5483 // Don't enable the screen until all existing windows
5484 // have been drawn.
5485 boolean haveBootMsg = false;
5486 boolean haveApp = false;
Justin Mattson4233f262012-04-09 18:23:16 -07005487 // if the wallpaper service is disabled on the device, we're never going to have
5488 // wallpaper, don't bother waiting for it
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005489 boolean haveWallpaper = false;
Justin Mattson4233f262012-04-09 18:23:16 -07005490 boolean wallpaperEnabled = mContext.getResources().getBoolean(
Jeff Brown780c46f2012-06-24 12:15:38 -07005491 com.android.internal.R.bool.config_enableWallpaperService)
5492 && !mOnlyCore;
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005493 boolean haveKeyguard = true;
Craig Mautner59c00972012-07-30 12:10:24 -07005494 // TODO(multidisplay): Expand to all displays?
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005495 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07005496 final int N = windows.size();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005497 for (int i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07005498 WindowState w = windows.get(i);
Craig Mautner65d11b32012-10-01 13:59:52 -07005499 if (w.mAttrs.type == TYPE_KEYGUARD) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005500 // Only if there is a keyguard attached to the window manager
5501 // will we consider ourselves as having a keyguard. If it
5502 // isn't attached, we don't know if it wants to be shown or
5503 // hidden. If it is attached, we will say we have a keyguard
5504 // if the window doesn't want to be visible, because in that
5505 // case it explicitly doesn't want to be shown so we should
5506 // not delay turning the screen on for it.
5507 boolean vis = w.mViewVisibility == View.VISIBLE
5508 && w.mPolicyVisibility;
5509 haveKeyguard = !vis;
5510 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005511 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
5512 return;
5513 }
5514 if (w.isDrawnLw()) {
Craig Mautner65d11b32012-10-01 13:59:52 -07005515 if (w.mAttrs.type == TYPE_BOOT_PROGRESS) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005516 haveBootMsg = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005517 } else if (w.mAttrs.type == TYPE_APPLICATION) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005518 haveApp = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005519 } else if (w.mAttrs.type == TYPE_WALLPAPER) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005520 haveWallpaper = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005521 } else if (w.mAttrs.type == TYPE_KEYGUARD) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005522 haveKeyguard = true;
5523 }
5524 }
5525 }
5526
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005527 if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005528 Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
5529 + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
Justin Mattson4233f262012-04-09 18:23:16 -07005530 + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled
5531 + " haveKeyguard=" + haveKeyguard);
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005532 }
5533
5534 // If we are turning on the screen to show the boot message,
5535 // don't do it until the boot message is actually displayed.
5536 if (!mSystemBooted && !haveBootMsg) {
5537 return;
5538 }
5539
5540 // If we are turning on the screen after the boot is completed
5541 // normally, don't do so until we have the application and
5542 // wallpaper.
Justin Mattson4233f262012-04-09 18:23:16 -07005543 if (mSystemBooted && ((!haveApp && !haveKeyguard) ||
5544 (wallpaperEnabled && !haveWallpaper))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005545 return;
5546 }
5547 }
Romain Guy06882f82009-06-10 13:36:04 -07005548
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005549 mDisplayEnabled = true;
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005550 if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005551 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005552 StringWriter sw = new StringWriter();
5553 PrintWriter pw = new PrintWriter(sw);
5554 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005555 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005556 }
5557 try {
5558 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
5559 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005560 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005561 Parcel data = Parcel.obtain();
5562 data.writeInterfaceToken("android.ui.ISurfaceComposer");
Jeff Brownc042ee22012-05-08 13:03:42 -07005563 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005564 data, null, 0);
5565 data.recycle();
5566 }
5567 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005568 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005569 }
Jeff Brown08a746a2012-06-24 12:14:49 -07005570
5571 // Enable input dispatch.
5572 mInputMonitor.setEventDispatchingLw(mEventDispatchingEnabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005573 }
Romain Guy06882f82009-06-10 13:36:04 -07005574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005575 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07005576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005577 // Make sure the last requested orientation has been applied.
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005578 updateRotationUnchecked(false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005579 }
Romain Guy06882f82009-06-10 13:36:04 -07005580
Dianne Hackborn661cd522011-08-22 00:26:20 -07005581 public void showBootMessage(final CharSequence msg, final boolean always) {
5582 boolean first = false;
5583 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005584 if (DEBUG_BOOT) {
5585 RuntimeException here = new RuntimeException("here");
5586 here.fillInStackTrace();
5587 Slog.i(TAG, "showBootMessage: msg=" + msg + " always=" + always
5588 + " mAllowBootMessages=" + mAllowBootMessages
5589 + " mShowingBootMessages=" + mShowingBootMessages
5590 + " mSystemBooted=" + mSystemBooted, here);
5591 }
Dianne Hackborn58f42a52011-10-10 13:46:34 -07005592 if (!mAllowBootMessages) {
5593 return;
5594 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005595 if (!mShowingBootMessages) {
5596 if (!always) {
5597 return;
5598 }
5599 first = true;
5600 }
5601 if (mSystemBooted) {
5602 return;
5603 }
5604 mShowingBootMessages = true;
5605 mPolicy.showBootMessage(msg, always);
5606 }
5607 if (first) {
5608 performEnableScreen();
5609 }
5610 }
5611
5612 public void hideBootMessagesLocked() {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005613 if (DEBUG_BOOT) {
5614 RuntimeException here = new RuntimeException("here");
5615 here.fillInStackTrace();
5616 Slog.i(TAG, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled
5617 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5618 + " mShowingBootMessages=" + mShowingBootMessages
5619 + " mSystemBooted=" + mSystemBooted, here);
5620 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005621 if (mShowingBootMessages) {
5622 mShowingBootMessages = false;
5623 mPolicy.hideBootMessages();
5624 }
5625 }
5626
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005627 public void setInTouchMode(boolean mode) {
5628 synchronized(mWindowMap) {
5629 mInTouchMode = mode;
5630 }
5631 }
5632
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005633 // TODO: more accounting of which pid(s) turned it on, keep count,
5634 // only allow disables from pids which have count on, etc.
Craig Mautner0447a812012-05-22 16:01:31 -07005635 @Override
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005636 public void showStrictModeViolation(boolean on) {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07005637 if (mHeadless) return;
Craig Mautner0447a812012-05-22 16:01:31 -07005638 mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, on ? 1 : 0, 0));
5639 }
Mike Lockwood3a74bd32011-08-12 13:55:22 -07005640
Craig Mautner0447a812012-05-22 16:01:31 -07005641 private void showStrictModeViolation(int arg) {
5642 final boolean on = arg != 0;
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005643 int pid = Binder.getCallingPid();
5644 synchronized(mWindowMap) {
5645 // Ignoring requests to enable the red border from clients
5646 // which aren't on screen. (e.g. Broadcast Receivers in
5647 // the background..)
5648 if (on) {
5649 boolean isVisible = false;
Craig Mautner59c00972012-07-30 12:10:24 -07005650 final AllWindowsIterator iterator = new AllWindowsIterator();
5651 while (iterator.hasNext()) {
5652 final WindowState ws = iterator.next();
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005653 if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
5654 isVisible = true;
5655 break;
5656 }
5657 }
5658 if (!isVisible) {
5659 return;
5660 }
5661 }
5662
Dianne Hackborn36991742011-10-11 21:35:26 -07005663 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
5664 ">>> OPEN TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005665 Surface.openTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005666 try {
Jeff Browne215f262012-09-10 16:01:14 -07005667 // TODO(multi-display): support multiple displays
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005668 if (mStrictModeFlash == null) {
Jeff Browne215f262012-09-10 16:01:14 -07005669 mStrictModeFlash = new StrictModeFlash(
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005670 getDefaultDisplayContentLocked().getDisplay(), mFxSession);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005671 }
5672 mStrictModeFlash.setVisibility(on);
5673 } finally {
5674 Surface.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -07005675 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
5676 "<<< CLOSE TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005677 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005678 }
5679 }
5680
Brad Fitzpatrickc1a968a2010-11-24 08:56:40 -08005681 public void setStrictModeVisualIndicatorPreference(String value) {
5682 SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
5683 }
5684
Jim Millere70d5062011-03-08 21:38:39 -08005685 /**
5686 * Takes a snapshot of the screen. In landscape mode this grabs the whole screen.
5687 * In portrait mode, it grabs the upper region of the screen based on the vertical dimension
5688 * of the target image.
5689 *
Craig Mautner59c00972012-07-30 12:10:24 -07005690 * @param displayId the Display to take a screenshot of.
Jim Millere70d5062011-03-08 21:38:39 -08005691 * @param width the width of the target bitmap
5692 * @param height the height of the target bitmap
5693 */
Craig Mautner59c00972012-07-30 12:10:24 -07005694 public Bitmap screenshotApplications(IBinder appToken, int displayId, int width, int height) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005695 if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5696 "screenshotApplications()")) {
5697 throw new SecurityException("Requires READ_FRAME_BUFFER permission");
5698 }
5699
5700 Bitmap rawss;
5701
Dianne Hackbornd2835932010-12-13 16:28:46 -08005702 int maxLayer = 0;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005703 final Rect frame = new Rect();
5704
5705 float scale;
Jim Millere70d5062011-03-08 21:38:39 -08005706 int dw, dh;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005707 int rot;
5708
5709 synchronized(mWindowMap) {
5710 long ident = Binder.clearCallingIdentity();
5711
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005712 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner59c00972012-07-30 12:10:24 -07005713 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
5714 dw = displayInfo.logicalWidth;
5715 dh = displayInfo.logicalHeight;
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005716
Craig Mautner65d11b32012-10-01 13:59:52 -07005717 int aboveAppLayer = mPolicy.windowTypeToLayerLw(TYPE_APPLICATION)
5718 * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005719 aboveAppLayer += TYPE_LAYER_MULTIPLIER;
5720
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005721 boolean isImeTarget = mInputMethodTarget != null
5722 && mInputMethodTarget.mAppToken != null
5723 && mInputMethodTarget.mAppToken.appToken != null
5724 && mInputMethodTarget.mAppToken.appToken.asBinder() == appToken;
5725
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005726 // Figure out the part of the screen that is actually the app.
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005727 boolean including = false;
Craig Mautner59c00972012-07-30 12:10:24 -07005728 final WindowList windows = displayContent.getWindowList();
5729 for (int i = windows.size() - 1; i >= 0; i--) {
5730 WindowState ws = windows.get(i);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07005731 if (!ws.mHasSurface) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005732 continue;
5733 }
5734 if (ws.mLayer >= aboveAppLayer) {
Dianne Hackbornd2835932010-12-13 16:28:46 -08005735 continue;
5736 }
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005737 // When we will skip windows: when we are not including
5738 // ones behind a window we didn't skip, and we are actually
5739 // taking a screenshot of a specific app.
5740 if (!including && appToken != null) {
5741 // Also, we can possibly skip this window if it is not
5742 // an IME target or the application for the screenshot
5743 // is not the current IME target.
5744 if (!ws.mIsImWindow || !isImeTarget) {
5745 // And finally, this window is of no interest if it
5746 // is not associated with the screenshot app.
5747 if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
5748 continue;
5749 }
5750 }
5751 }
5752
5753 // We keep on including windows until we go past a full-screen
5754 // window.
5755 including = !ws.mIsImWindow && !ws.isFullscreen(dw, dh);
5756
Craig Mautner88165682012-05-31 14:25:31 -07005757 if (maxLayer < ws.mWinAnimator.mSurfaceLayer) {
5758 maxLayer = ws.mWinAnimator.mSurfaceLayer;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005759 }
Jim Miller2aded182011-03-08 15:32:42 -08005760
5761 // Don't include wallpaper in bounds calculation
5762 if (!ws.mIsWallpaper) {
Dianne Hackbornffb3d932011-05-17 17:44:51 -07005763 final Rect wf = ws.mFrame;
Jim Miller2aded182011-03-08 15:32:42 -08005764 final Rect cr = ws.mContentInsets;
5765 int left = wf.left + cr.left;
5766 int top = wf.top + cr.top;
5767 int right = wf.right - cr.right;
5768 int bottom = wf.bottom - cr.bottom;
5769 frame.union(left, top, right, bottom);
5770 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005771 }
5772 Binder.restoreCallingIdentity(ident);
5773
Dianne Hackborndd962ee2011-02-02 11:11:50 -08005774 // Constrain frame to the screen size.
5775 frame.intersect(0, 0, dw, dh);
Jim Millere70d5062011-03-08 21:38:39 -08005776
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005777 if (frame.isEmpty() || maxLayer == 0) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005778 return null;
5779 }
5780
5781 // The screenshot API does not apply the current screen rotation.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005782 rot = getDefaultDisplayContentLocked().getDisplay().getRotation();
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005783 int fw = frame.width();
5784 int fh = frame.height();
5785
Jim Miller28637ba2011-07-06 19:57:05 -07005786 // Constrain thumbnail to smaller of screen width or height. Assumes aspect
5787 // of thumbnail is the same as the screen (in landscape) or square.
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005788 float targetWidthScale = width / (float) fw;
5789 float targetHeightScale = height / (float) fh;
Jim Miller28637ba2011-07-06 19:57:05 -07005790 if (dw <= dh) {
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005791 scale = targetWidthScale;
5792 // If aspect of thumbnail is the same as the screen (in landscape),
5793 // select the slightly larger value so we fill the entire bitmap
5794 if (targetHeightScale > scale && (int) (targetHeightScale * fw) == width) {
5795 scale = targetHeightScale;
5796 }
Jim Miller28637ba2011-07-06 19:57:05 -07005797 } else {
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005798 scale = targetHeightScale;
5799 // If aspect of thumbnail is the same as the screen (in landscape),
5800 // select the slightly larger value so we fill the entire bitmap
5801 if (targetWidthScale > scale && (int) (targetWidthScale * fh) == height) {
5802 scale = targetWidthScale;
5803 }
Jim Miller28637ba2011-07-06 19:57:05 -07005804 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005805
5806 // The screen shot will contain the entire screen.
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005807 dw = (int)(dw*scale);
5808 dh = (int)(dh*scale);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005809 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
5810 int tmp = dw;
5811 dw = dh;
5812 dh = tmp;
5813 rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
5814 }
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -07005815 if (DEBUG_SCREENSHOT) {
5816 Slog.i(TAG, "Screenshot: " + dw + "x" + dh + " from 0 to " + maxLayer);
Craig Mautner59c00972012-07-30 12:10:24 -07005817 for (int i = 0; i < windows.size(); i++) {
5818 WindowState win = windows.get(i);
5819 Slog.i(TAG, win + ": " + win.mLayer
5820 + " animLayer=" + win.mWinAnimator.mAnimLayer
5821 + " surfaceLayer=" + win.mWinAnimator.mSurfaceLayer);
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -07005822 }
5823 }
Dianne Hackbornd2835932010-12-13 16:28:46 -08005824 rawss = Surface.screenshot(dw, dh, 0, maxLayer);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005825 }
5826
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005827 if (rawss == null) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07005828 Slog.w(TAG, "Failure taking screenshot for (" + dw + "x" + dh
Dianne Hackborn88b03bd2010-12-16 11:15:18 -08005829 + ") to layer " + maxLayer);
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005830 return null;
5831 }
Jim Millere70d5062011-03-08 21:38:39 -08005832
5833 Bitmap bm = Bitmap.createBitmap(width, height, rawss.getConfig());
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005834 Matrix matrix = new Matrix();
5835 ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
Michael Jurka4accb6a2012-03-26 09:18:46 -07005836 matrix.postTranslate(-FloatMath.ceil(frame.left*scale), -FloatMath.ceil(frame.top*scale));
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005837 Canvas canvas = new Canvas(bm);
5838 canvas.drawBitmap(rawss, matrix, null);
Dianne Hackborn6311d0a2011-08-02 16:37:58 -07005839 canvas.setBitmap(null);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005840
5841 rawss.recycle();
5842 return bm;
5843 }
5844
Jeff Brown01a98dd2011-09-20 15:08:29 -07005845 /**
5846 * Freeze rotation changes. (Enable "rotation lock".)
5847 * Persists across reboots.
Jeff Brown4dfce202011-10-05 12:00:10 -07005848 * @param rotation The desired rotation to freeze to, or -1 to use the
5849 * current rotation.
Jeff Brown01a98dd2011-09-20 15:08:29 -07005850 */
Jeff Brown4dfce202011-10-05 12:00:10 -07005851 public void freezeRotation(int rotation) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005852 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005853 "freezeRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005854 throw new SecurityException("Requires SET_ORIENTATION permission");
5855 }
Jeff Brown4dfce202011-10-05 12:00:10 -07005856 if (rotation < -1 || rotation > Surface.ROTATION_270) {
5857 throw new IllegalArgumentException("Rotation argument must be -1 or a valid "
5858 + "rotation constant.");
5859 }
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005860
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005861 if (DEBUG_ORIENTATION) Slog.v(TAG, "freezeRotation: mRotation=" + mRotation);
5862
Jeff Brown4dfce202011-10-05 12:00:10 -07005863 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED,
5864 rotation == -1 ? mRotation : rotation);
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005865 updateRotationUnchecked(false, false);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005866 }
5867
Jeff Brown01a98dd2011-09-20 15:08:29 -07005868 /**
5869 * Thaw rotation changes. (Disable "rotation lock".)
5870 * Persists across reboots.
5871 */
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005872 public void thawRotation() {
5873 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005874 "thawRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005875 throw new SecurityException("Requires SET_ORIENTATION permission");
5876 }
5877
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005878 if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation);
5879
5880 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 777); // rot not used
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005881 updateRotationUnchecked(false, false);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005882 }
5883
Jeff Brown01a98dd2011-09-20 15:08:29 -07005884 /**
5885 * Recalculate the current rotation.
5886 *
5887 * Called by the window manager policy whenever the state of the system changes
5888 * such that the current rotation might need to be updated, such as when the
5889 * device is docked or rotated into a new posture.
5890 */
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005891 public void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
5892 updateRotationUnchecked(alwaysSendConfiguration, forceRelayout);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005893 }
5894
5895 /**
5896 * Temporarily pauses rotation changes until resumed.
5897 *
5898 * This can be used to prevent rotation changes from occurring while the user is
5899 * performing certain operations, such as drag and drop.
5900 *
5901 * This call nests and must be matched by an equal number of calls to {@link #resumeRotation}.
5902 */
5903 void pauseRotationLocked() {
5904 mDeferredRotationPauseCount += 1;
5905 }
5906
5907 /**
5908 * Resumes normal rotation changes after being paused.
5909 */
5910 void resumeRotationLocked() {
5911 if (mDeferredRotationPauseCount > 0) {
5912 mDeferredRotationPauseCount -= 1;
5913 if (mDeferredRotationPauseCount == 0) {
5914 boolean changed = updateRotationUncheckedLocked(false);
5915 if (changed) {
5916 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
5917 }
5918 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005919 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005920 }
Romain Guy06882f82009-06-10 13:36:04 -07005921
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005922 public void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005923 if(DEBUG_ORIENTATION) Slog.v(TAG, "updateRotationUnchecked("
5924 + "alwaysSendConfiguration=" + alwaysSendConfiguration + ")");
Romain Guy06882f82009-06-10 13:36:04 -07005925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005926 long origId = Binder.clearCallingIdentity();
5927 boolean changed;
5928 synchronized(mWindowMap) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005929 changed = updateRotationUncheckedLocked(false);
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005930 if (!changed || forceRelayout) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005931 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005932 performLayoutAndPlaceSurfacesLocked();
5933 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005934 }
Romain Guy06882f82009-06-10 13:36:04 -07005935
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005936 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005937 sendNewConfiguration();
5938 }
Romain Guy06882f82009-06-10 13:36:04 -07005939
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005940 Binder.restoreCallingIdentity(origId);
5941 }
Romain Guy06882f82009-06-10 13:36:04 -07005942
Craig Mautner59c00972012-07-30 12:10:24 -07005943 // TODO(multidisplay): Rotate any display?
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005944 /**
Jeff Brown01a98dd2011-09-20 15:08:29 -07005945 * Updates the current rotation.
5946 *
5947 * Returns true if the rotation has been changed. In this case YOU
5948 * MUST CALL sendNewConfiguration() TO UNFREEZE THE SCREEN.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005949 */
Jeff Brown01a98dd2011-09-20 15:08:29 -07005950 public boolean updateRotationUncheckedLocked(boolean inTransaction) {
5951 if (mDeferredRotationPauseCount > 0) {
5952 // Rotation updates have been paused temporarily. Defer the update until
5953 // updates have been resumed.
5954 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, rotation is paused.");
Christopher Tateccd24de2011-01-12 15:02:55 -08005955 return false;
5956 }
5957
Craig Mautnera91f9e22012-09-14 16:22:08 -07005958 ScreenRotationAnimation screenRotationAnimation =
5959 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
5960 if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005961 // Rotation updates cannot be performed while the previous rotation change
5962 // animation is still in progress. Skip this update. We will try updating
5963 // again after the animation is finished and the display is unfrozen.
5964 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, animation in progress.");
5965 return false;
5966 }
5967
5968 if (!mDisplayEnabled) {
5969 // No point choosing a rotation if the display is not enabled.
5970 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, display is not enabled.");
5971 return false;
5972 }
5973
5974 // TODO: Implement forced rotation changes.
5975 // Set mAltOrientation to indicate that the application is receiving
5976 // an orientation that has different metrics than it expected.
5977 // eg. Portrait instead of Landscape.
5978
5979 int rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, mRotation);
5980 boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
5981 mForcedAppOrientation, rotation);
5982
5983 if (DEBUG_ORIENTATION) {
5984 Slog.v(TAG, "Application requested orientation "
5985 + mForcedAppOrientation + ", got rotation " + rotation
5986 + " which has " + (altOrientation ? "incompatible" : "compatible")
5987 + " metrics");
5988 }
5989
5990 if (mRotation == rotation && mAltOrientation == altOrientation) {
5991 // No change.
5992 return false;
5993 }
5994
5995 if (DEBUG_ORIENTATION) {
5996 Slog.v(TAG,
5997 "Rotation changed to " + rotation + (altOrientation ? " (alt)" : "")
5998 + " from " + mRotation + (mAltOrientation ? " (alt)" : "")
5999 + ", forceApp=" + mForcedAppOrientation);
6000 }
6001
6002 mRotation = rotation;
6003 mAltOrientation = altOrientation;
Jeff Brownc0347aa2011-09-23 17:26:09 -07006004 mPolicy.setRotationLw(mRotation);
Jeff Brown01a98dd2011-09-20 15:08:29 -07006005
6006 mWindowsFreezingScreen = true;
6007 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
6008 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT), 2000);
6009 mWaitingForConfig = true;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006010 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07006011 startFreezingDisplayLocked(inTransaction, 0, 0);
Craig Mautnera91f9e22012-09-14 16:22:08 -07006012 // startFreezingDisplayLocked can reset the ScreenRotationAnimation.
6013 screenRotationAnimation =
6014 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
Jeff Brown01a98dd2011-09-20 15:08:29 -07006015
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006016 // We need to update our screen size information to match the new
6017 // rotation. Note that this is redundant with the later call to
6018 // sendNewConfiguration() that must be called after this function
6019 // returns... however we need to do the screen size part of that
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006020 // before then so we have the correct size to use when initializing
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006021 // the rotation animation for the new rotation.
6022 computeScreenConfigurationLocked(null);
6023
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006024 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07006025 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006026 if (!inTransaction) {
6027 if (SHOW_TRANSACTIONS) {
6028 Slog.i(TAG, ">>> OPEN TRANSACTION setRotationUnchecked");
6029 }
6030 Surface.openTransaction();
6031 }
Jamie Gennise2909e12011-10-10 15:48:06 -07006032 try {
6033 // NOTE: We disable the rotation in the emulator because
6034 // it doesn't support hardware OpenGL emulation yet.
Craig Mautnera91f9e22012-09-14 16:22:08 -07006035 if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
6036 && screenRotationAnimation.hasScreenshot()) {
6037 if (screenRotationAnimation.setRotationInTransaction(
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006038 rotation, mFxSession,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006039 MAX_ANIMATION_DURATION, mTransitionAnimationScale,
Craig Mautner59c00972012-07-30 12:10:24 -07006040 displayInfo.logicalWidth, displayInfo.logicalHeight)) {
Craig Mautner711f90a2012-07-03 18:43:52 -07006041 updateLayoutToAnimationLocked();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006042 }
Jamie Gennise2909e12011-10-10 15:48:06 -07006043 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006044
6045 mDisplayManagerService.performTraversalInTransactionFromWindowManager();
Jamie Gennise2909e12011-10-10 15:48:06 -07006046 } finally {
6047 if (!inTransaction) {
6048 Surface.closeTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006049 if (SHOW_LIGHT_TRANSACTIONS) {
6050 Slog.i(TAG, "<<< CLOSE TRANSACTION setRotationUnchecked");
6051 }
Jamie Gennise2909e12011-10-10 15:48:06 -07006052 }
6053 }
6054
Craig Mautner59c00972012-07-30 12:10:24 -07006055 final WindowList windows = displayContent.getWindowList();
6056 for (int i = windows.size() - 1; i >= 0; i--) {
6057 WindowState w = windows.get(i);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07006058 if (w.mHasSurface) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07006059 if (DEBUG_ORIENTATION) Slog.v(TAG, "Set mOrientationChanging of " + w);
Jeff Brown01a98dd2011-09-20 15:08:29 -07006060 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07006061 mInnerFields.mOrientationChangeComplete = false;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006062 }
6063 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006064
Jeff Brown01a98dd2011-09-20 15:08:29 -07006065 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
6066 try {
6067 mRotationWatchers.get(i).onRotationChanged(rotation);
6068 } catch (RemoteException e) {
6069 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006070 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006071
6072 scheduleNotifyRotationChangedIfNeededLocked(displayContent, rotation);
6073
Jeff Brown01a98dd2011-09-20 15:08:29 -07006074 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006075 }
Romain Guy06882f82009-06-10 13:36:04 -07006076
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006077 public int getRotation() {
6078 return mRotation;
6079 }
6080
6081 public int watchRotation(IRotationWatcher watcher) {
6082 final IBinder watcherBinder = watcher.asBinder();
6083 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
6084 public void binderDied() {
6085 synchronized (mWindowMap) {
6086 for (int i=0; i<mRotationWatchers.size(); i++) {
6087 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07006088 IRotationWatcher removed = mRotationWatchers.remove(i);
6089 if (removed != null) {
6090 removed.asBinder().unlinkToDeath(this, 0);
6091 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006092 i--;
6093 }
6094 }
6095 }
6096 }
6097 };
Romain Guy06882f82009-06-10 13:36:04 -07006098
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006099 synchronized (mWindowMap) {
6100 try {
6101 watcher.asBinder().linkToDeath(dr, 0);
6102 mRotationWatchers.add(watcher);
6103 } catch (RemoteException e) {
6104 // Client died, no cleanup needed.
6105 }
Romain Guy06882f82009-06-10 13:36:04 -07006106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006107 return mRotation;
6108 }
6109 }
6110
6111 /**
Adam Powelldfee59a2011-08-05 20:48:30 -07006112 * Apps that use the compact menu panel (as controlled by the panelMenuIsCompact
6113 * theme attribute) on devices that feature a physical options menu key attempt to position
6114 * their menu panel window along the edge of the screen nearest the physical menu key.
6115 * This lowers the travel distance between invoking the menu panel and selecting
6116 * a menu option.
6117 *
6118 * This method helps control where that menu is placed. Its current implementation makes
6119 * assumptions about the menu key and its relationship to the screen based on whether
6120 * the device's natural orientation is portrait (width < height) or landscape.
6121 *
6122 * The menu key is assumed to be located along the bottom edge of natural-portrait
6123 * devices and along the right edge of natural-landscape devices. If these assumptions
6124 * do not hold for the target device, this method should be changed to reflect that.
6125 *
6126 * @return A {@link Gravity} value for placing the options menu window
6127 */
6128 public int getPreferredOptionsPanelGravity() {
6129 synchronized (mWindowMap) {
6130 final int rotation = getRotation();
6131
Craig Mautner59c00972012-07-30 12:10:24 -07006132 // TODO(multidisplay): Assume that such devices physical keys are on the main screen.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006133 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07006134 if (displayContent.mInitialDisplayWidth < displayContent.mInitialDisplayHeight) {
Adam Powelldfee59a2011-08-05 20:48:30 -07006135 // On devices with a natural orientation of portrait
6136 switch (rotation) {
6137 default:
6138 case Surface.ROTATION_0:
6139 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
6140 case Surface.ROTATION_90:
Adam Powell67ed6c72011-08-28 13:21:56 -07006141 return Gravity.RIGHT | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006142 case Surface.ROTATION_180:
Adam Powell67ed6c72011-08-28 13:21:56 -07006143 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006144 case Surface.ROTATION_270:
Fabrice Di Meglioaac0d4e2012-07-19 19:21:26 -07006145 return Gravity.START | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006146 }
6147 } else {
6148 // On devices with a natural orientation of landscape
6149 switch (rotation) {
6150 default:
6151 case Surface.ROTATION_0:
Adam Powell67ed6c72011-08-28 13:21:56 -07006152 return Gravity.RIGHT | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006153 case Surface.ROTATION_90:
6154 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
6155 case Surface.ROTATION_180:
Fabrice Di Meglioaac0d4e2012-07-19 19:21:26 -07006156 return Gravity.START | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006157 case Surface.ROTATION_270:
Adam Powell67ed6c72011-08-28 13:21:56 -07006158 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006159 }
6160 }
6161 }
6162 }
6163
6164 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006165 * Starts the view server on the specified port.
6166 *
6167 * @param port The port to listener to.
6168 *
6169 * @return True if the server was successfully started, false otherwise.
6170 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08006171 * @see com.android.server.wm.ViewServer
6172 * @see com.android.server.wm.ViewServer#VIEW_SERVER_DEFAULT_PORT
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006173 */
6174 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07006175 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006176 return false;
6177 }
6178
6179 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
6180 return false;
6181 }
6182
6183 if (port < 1024) {
6184 return false;
6185 }
6186
6187 if (mViewServer != null) {
6188 if (!mViewServer.isRunning()) {
6189 try {
6190 return mViewServer.start();
6191 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006192 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006193 }
6194 }
6195 return false;
6196 }
6197
6198 try {
6199 mViewServer = new ViewServer(this, port);
6200 return mViewServer.start();
6201 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006202 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006203 }
6204 return false;
6205 }
6206
Romain Guy06882f82009-06-10 13:36:04 -07006207 private boolean isSystemSecure() {
6208 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
6209 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6210 }
6211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006212 /**
6213 * Stops the view server if it exists.
6214 *
6215 * @return True if the server stopped, false if it wasn't started or
6216 * couldn't be stopped.
6217 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08006218 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006219 */
6220 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07006221 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006222 return false;
6223 }
6224
6225 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
6226 return false;
6227 }
6228
6229 if (mViewServer != null) {
6230 return mViewServer.stop();
6231 }
6232 return false;
6233 }
6234
6235 /**
6236 * Indicates whether the view server is running.
6237 *
6238 * @return True if the server is running, false otherwise.
6239 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08006240 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006241 */
6242 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07006243 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006244 return false;
6245 }
6246
6247 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
6248 return false;
6249 }
6250
6251 return mViewServer != null && mViewServer.isRunning();
6252 }
6253
6254 /**
6255 * Lists all availble windows in the system. The listing is written in the
6256 * specified Socket's output stream with the following syntax:
6257 * windowHashCodeInHexadecimal windowName
6258 * Each line of the ouput represents a different window.
6259 *
6260 * @param client The remote client to send the listing to.
6261 * @return False if an error occured, true otherwise.
6262 */
6263 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07006264 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006265 return false;
6266 }
6267
6268 boolean result = true;
6269
Craig Mautner59c00972012-07-30 12:10:24 -07006270 WindowList windows = new WindowList();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006271 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006272 //noinspection unchecked
Craig Mautner59c00972012-07-30 12:10:24 -07006273 DisplayContentsIterator iterator = new DisplayContentsIterator();
6274 while(iterator.hasNext()) {
6275 windows.addAll(iterator.next().getWindowList());
6276 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006277 }
6278
6279 BufferedWriter out = null;
6280
6281 // Any uncaught exception will crash the system process
6282 try {
6283 OutputStream clientStream = client.getOutputStream();
6284 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
6285
Craig Mautner59c00972012-07-30 12:10:24 -07006286 final int count = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006287 for (int i = 0; i < count; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07006288 final WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006289 out.write(Integer.toHexString(System.identityHashCode(w)));
6290 out.write(' ');
6291 out.append(w.mAttrs.getTitle());
6292 out.write('\n');
6293 }
6294
6295 out.write("DONE.\n");
6296 out.flush();
6297 } catch (Exception e) {
6298 result = false;
6299 } finally {
6300 if (out != null) {
6301 try {
6302 out.close();
6303 } catch (IOException e) {
6304 result = false;
6305 }
6306 }
6307 }
6308
6309 return result;
6310 }
6311
Craig Mautner59c00972012-07-30 12:10:24 -07006312 // TODO(multidisplay): Extend to multiple displays.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006313 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07006314 * Returns the focused window in the following format:
6315 * windowHashCodeInHexadecimal windowName
6316 *
6317 * @param client The remote client to send the listing to.
6318 * @return False if an error occurred, true otherwise.
6319 */
6320 boolean viewServerGetFocusedWindow(Socket client) {
6321 if (isSystemSecure()) {
6322 return false;
6323 }
6324
6325 boolean result = true;
6326
6327 WindowState focusedWindow = getFocusedWindow();
6328
6329 BufferedWriter out = null;
6330
6331 // Any uncaught exception will crash the system process
6332 try {
6333 OutputStream clientStream = client.getOutputStream();
6334 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
6335
6336 if(focusedWindow != null) {
6337 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
6338 out.write(' ');
6339 out.append(focusedWindow.mAttrs.getTitle());
6340 }
6341 out.write('\n');
6342 out.flush();
6343 } catch (Exception e) {
6344 result = false;
6345 } finally {
6346 if (out != null) {
6347 try {
6348 out.close();
6349 } catch (IOException e) {
6350 result = false;
6351 }
6352 }
6353 }
6354
6355 return result;
6356 }
6357
6358 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006359 * Sends a command to a target window. The result of the command, if any, will be
6360 * written in the output stream of the specified socket.
6361 *
6362 * The parameters must follow this syntax:
6363 * windowHashcode extra
6364 *
6365 * Where XX is the length in characeters of the windowTitle.
6366 *
6367 * The first parameter is the target window. The window with the specified hashcode
6368 * will be the target. If no target can be found, nothing happens. The extra parameters
6369 * will be delivered to the target window and as parameters to the command itself.
6370 *
6371 * @param client The remote client to sent the result, if any, to.
6372 * @param command The command to execute.
6373 * @param parameters The command parameters.
6374 *
6375 * @return True if the command was successfully delivered, false otherwise. This does
6376 * not indicate whether the command itself was successful.
6377 */
6378 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07006379 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006380 return false;
6381 }
6382
6383 boolean success = true;
6384 Parcel data = null;
6385 Parcel reply = null;
6386
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006387 BufferedWriter out = null;
6388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006389 // Any uncaught exception will crash the system process
6390 try {
6391 // Find the hashcode of the window
6392 int index = parameters.indexOf(' ');
6393 if (index == -1) {
6394 index = parameters.length();
6395 }
6396 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08006397 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006398
6399 // Extract the command's parameter after the window description
6400 if (index < parameters.length()) {
6401 parameters = parameters.substring(index + 1);
6402 } else {
6403 parameters = "";
6404 }
6405
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006406 final WindowState window = findWindow(hashCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006407 if (window == null) {
6408 return false;
6409 }
6410
6411 data = Parcel.obtain();
6412 data.writeInterfaceToken("android.view.IWindow");
6413 data.writeString(command);
6414 data.writeString(parameters);
6415 data.writeInt(1);
6416 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
6417
6418 reply = Parcel.obtain();
6419
6420 final IBinder binder = window.mClient.asBinder();
6421 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
6422 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
6423
6424 reply.readException();
6425
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006426 if (!client.isOutputShutdown()) {
6427 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
6428 out.write("DONE\n");
6429 out.flush();
6430 }
6431
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006432 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006433 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006434 success = false;
6435 } finally {
6436 if (data != null) {
6437 data.recycle();
6438 }
6439 if (reply != null) {
6440 reply.recycle();
6441 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006442 if (out != null) {
6443 try {
6444 out.close();
6445 } catch (IOException e) {
6446
6447 }
6448 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006449 }
6450
6451 return success;
6452 }
6453
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006454 public void addDisplayContentChangeListener(int displayId,
6455 IDisplayContentChangeListener listener) {
6456 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
6457 "addDisplayContentChangeListener()")) {
6458 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission");
6459 }
6460 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006461 DisplayContent displayContent = getDisplayContentLocked(displayId);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006462 if (displayContent.mDisplayContentChangeListeners == null) {
6463 displayContent.mDisplayContentChangeListeners =
6464 new RemoteCallbackList<IDisplayContentChangeListener>();
6465 displayContent.mDisplayContentChangeListeners.register(listener);
6466 }
6467 }
6468 }
6469
6470 public void removeDisplayContentChangeListener(int displayId,
6471 IDisplayContentChangeListener listener) {
6472 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
6473 "removeDisplayContentChangeListener()")) {
6474 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission");
6475 }
6476 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006477 DisplayContent displayContent = getDisplayContentLocked(displayId);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006478 if (displayContent.mDisplayContentChangeListeners != null) {
6479 displayContent.mDisplayContentChangeListeners.unregister(listener);
6480 if (displayContent.mDisplayContentChangeListeners
6481 .getRegisteredCallbackCount() == 0) {
6482 displayContent.mDisplayContentChangeListeners = null;
6483 }
6484 }
6485 }
6486 }
6487
6488 void scheduleNotifyWindowTranstionIfNeededLocked(WindowState window, int transition) {
6489 DisplayContent displayContent = window.mDisplayContent;
6490 if (displayContent.mDisplayContentChangeListeners != null) {
6491 WindowInfo info = getWindowInfoForWindowStateLocked(window);
6492 mH.obtainMessage(H.NOTIFY_WINDOW_TRANSITION, transition, 0, info).sendToTarget();
6493 }
6494 }
6495
6496 private void handleNotifyWindowTranstion(int transition, WindowInfo info) {
6497 RemoteCallbackList<IDisplayContentChangeListener> callbacks = null;
6498 synchronized (mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006499 DisplayContent displayContent = getDisplayContentLocked(info.displayId);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006500 if (displayContent == null) {
6501 return;
6502 }
6503 callbacks = displayContent.mDisplayContentChangeListeners;
6504 if (callbacks == null) {
6505 return;
6506 }
6507 }
6508 final int callbackCount = callbacks.beginBroadcast();
6509 try {
6510 for (int i = 0; i < callbackCount; i++) {
6511 try {
6512 callbacks.getBroadcastItem(i).onWindowTransition(info.displayId,
6513 transition, info);
6514 } catch (RemoteException re) {
6515 /* ignore */
6516 }
6517 }
6518 } finally {
6519 callbacks.finishBroadcast();
6520 }
6521 }
6522
6523 private void scheduleNotifyRotationChangedIfNeededLocked(DisplayContent displayContent,
6524 int rotation) {
6525 if (displayContent.mDisplayContentChangeListeners != null
6526 && displayContent.mDisplayContentChangeListeners.getRegisteredCallbackCount() > 0) {
6527 mH.obtainMessage(H.NOTIFY_ROTATION_CHANGED, displayContent.getDisplayId(),
6528 rotation).sendToTarget();
6529 }
6530 }
6531
6532 private void handleNotifyRotationChanged(int displayId, int rotation) {
6533 RemoteCallbackList<IDisplayContentChangeListener> callbacks = null;
6534 synchronized (mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006535 DisplayContent displayContent = getDisplayContentLocked(displayId);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006536 if (displayContent == null) {
6537 return;
6538 }
6539 callbacks = displayContent.mDisplayContentChangeListeners;
6540 if (callbacks == null) {
6541 return;
6542 }
6543 }
6544 try {
6545 final int watcherCount = callbacks.beginBroadcast();
6546 for (int i = 0; i < watcherCount; i++) {
6547 try {
6548 callbacks.getBroadcastItem(i).onRotationChanged(rotation);
6549 } catch (RemoteException re) {
6550 /* ignore */
6551 }
6552 }
6553 } finally {
6554 callbacks.finishBroadcast();
6555 }
6556 }
6557
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07006558 public void addWindowChangeListener(WindowChangeListener listener) {
6559 synchronized(mWindowMap) {
6560 mWindowChangeListeners.add(listener);
6561 }
6562 }
6563
6564 public void removeWindowChangeListener(WindowChangeListener listener) {
6565 synchronized(mWindowMap) {
6566 mWindowChangeListeners.remove(listener);
6567 }
6568 }
6569
6570 private void notifyWindowsChanged() {
6571 WindowChangeListener[] windowChangeListeners;
6572 synchronized(mWindowMap) {
6573 if(mWindowChangeListeners.isEmpty()) {
6574 return;
6575 }
6576 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
6577 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
6578 }
6579 int N = windowChangeListeners.length;
6580 for(int i = 0; i < N; i++) {
6581 windowChangeListeners[i].windowsChanged();
6582 }
6583 }
6584
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07006585 private void notifyFocusChanged() {
6586 WindowChangeListener[] windowChangeListeners;
6587 synchronized(mWindowMap) {
6588 if(mWindowChangeListeners.isEmpty()) {
6589 return;
6590 }
6591 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
6592 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
6593 }
6594 int N = windowChangeListeners.length;
6595 for(int i = 0; i < N; i++) {
6596 windowChangeListeners[i].focusChanged();
6597 }
6598 }
6599
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006600 private WindowState findWindow(int hashCode) {
6601 if (hashCode == -1) {
Craig Mautner59c00972012-07-30 12:10:24 -07006602 // TODO(multidisplay): Extend to multiple displays.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006603 return getFocusedWindow();
6604 }
6605
6606 synchronized (mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -07006607 final AllWindowsIterator iterator = new AllWindowsIterator();
6608 while (iterator.hasNext()) {
6609 final WindowState w = iterator.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006610 if (System.identityHashCode(w) == hashCode) {
6611 return w;
6612 }
6613 }
6614 }
6615
6616 return null;
6617 }
6618
6619 /*
6620 * Instruct the Activity Manager to fetch the current configuration and broadcast
6621 * that to config-changed listeners if appropriate.
6622 */
6623 void sendNewConfiguration() {
6624 try {
6625 mActivityManager.updateConfiguration(null);
6626 } catch (RemoteException e) {
6627 }
6628 }
Romain Guy06882f82009-06-10 13:36:04 -07006629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006630 public Configuration computeNewConfiguration() {
6631 synchronized (mWindowMap) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006632 Configuration config = computeNewConfigurationLocked();
6633 if (config == null && mWaitingForConfig) {
6634 // Nothing changed but we are waiting for something... stop that!
6635 mWaitingForConfig = false;
6636 performLayoutAndPlaceSurfacesLocked();
6637 }
6638 return config;
Dianne Hackbornc485a602009-03-24 22:39:49 -07006639 }
6640 }
Romain Guy06882f82009-06-10 13:36:04 -07006641
Dianne Hackbornc485a602009-03-24 22:39:49 -07006642 Configuration computeNewConfigurationLocked() {
6643 Configuration config = new Configuration();
Dianne Hackborn09e5b9d2011-10-04 16:32:01 -07006644 config.fontScale = 0;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006645 if (!computeScreenConfigurationLocked(config)) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07006646 return null;
6647 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07006648 return config;
6649 }
Romain Guy06882f82009-06-10 13:36:04 -07006650
Craig Mautner59c00972012-07-30 12:10:24 -07006651 private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation, int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006652 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006653 final int width = mPolicy.getConfigDisplayWidth(dw, dh, rotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006654 if (width < displayInfo.smallestNominalAppWidth) {
6655 displayInfo.smallestNominalAppWidth = width;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006656 }
Craig Mautner59c00972012-07-30 12:10:24 -07006657 if (width > displayInfo.largestNominalAppWidth) {
6658 displayInfo.largestNominalAppWidth = width;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006659 }
6660 final int height = mPolicy.getConfigDisplayHeight(dw, dh, rotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006661 if (height < displayInfo.smallestNominalAppHeight) {
6662 displayInfo.smallestNominalAppHeight = height;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006663 }
Craig Mautner59c00972012-07-30 12:10:24 -07006664 if (height > displayInfo.largestNominalAppHeight) {
6665 displayInfo.largestNominalAppHeight = height;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006666 }
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006667 }
6668
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006669 private int reduceConfigLayout(int curLayout, int rotation, float density,
6670 int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006671 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006672 // Get the app screen size at this rotation.
6673 int w = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
6674 int h = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
6675
6676 // Compute the screen layout size class for this rotation.
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006677 int longSize = w;
6678 int shortSize = h;
6679 if (longSize < shortSize) {
6680 int tmp = longSize;
6681 longSize = shortSize;
6682 shortSize = tmp;
6683 }
6684 longSize = (int)(longSize/density);
6685 shortSize = (int)(shortSize/density);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006686 return Configuration.reduceScreenLayout(curLayout, longSize, shortSize);
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006687 }
6688
Craig Mautner59c00972012-07-30 12:10:24 -07006689 private void computeSizeRangesAndScreenLayout(DisplayInfo displayInfo, boolean rotated,
6690 int dw, int dh, float density, Configuration outConfig) {
Craig Mautner69b08182012-09-05 13:07:13 -07006691 // TODO: Multidisplay: for now only use with default display.
6692
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006693 // We need to determine the smallest width that will occur under normal
6694 // operation. To this, start with the base screen size and compute the
6695 // width under the different possible rotations. We need to un-rotate
6696 // the current screen dimensions before doing this.
6697 int unrotDw, unrotDh;
6698 if (rotated) {
6699 unrotDw = dh;
6700 unrotDh = dw;
6701 } else {
6702 unrotDw = dw;
6703 unrotDh = dh;
6704 }
Craig Mautner59c00972012-07-30 12:10:24 -07006705 displayInfo.smallestNominalAppWidth = 1<<30;
6706 displayInfo.smallestNominalAppHeight = 1<<30;
6707 displayInfo.largestNominalAppWidth = 0;
6708 displayInfo.largestNominalAppHeight = 0;
6709 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, unrotDw, unrotDh);
6710 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, unrotDh, unrotDw);
6711 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, unrotDw, unrotDh);
6712 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, unrotDh, unrotDw);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006713 int sl = Configuration.resetScreenLayout(outConfig.screenLayout);
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006714 sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh);
6715 sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw);
6716 sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh);
6717 sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw);
Craig Mautner59c00972012-07-30 12:10:24 -07006718 outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006719 outConfig.screenLayout = sl;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006720 }
6721
Dianne Hackborn48a76512011-06-08 21:51:44 -07006722 private int reduceCompatConfigWidthSize(int curSize, int rotation, DisplayMetrics dm,
6723 int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006724 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn1f903c32011-09-13 19:18:06 -07006725 dm.noncompatWidthPixels = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
6726 dm.noncompatHeightPixels = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006727 float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
Dianne Hackborn2b31d532011-06-23 11:58:50 -07006728 int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006729 if (curSize == 0 || size < curSize) {
6730 curSize = size;
6731 }
6732 return curSize;
6733 }
6734
6735 private int computeCompatSmallestWidth(boolean rotated, DisplayMetrics dm, int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006736 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn48a76512011-06-08 21:51:44 -07006737 mTmpDisplayMetrics.setTo(dm);
Craig Mautner69b08182012-09-05 13:07:13 -07006738 final DisplayMetrics tmpDm = mTmpDisplayMetrics;
6739 final int unrotDw, unrotDh;
Dianne Hackborn48a76512011-06-08 21:51:44 -07006740 if (rotated) {
6741 unrotDw = dh;
6742 unrotDh = dw;
6743 } else {
6744 unrotDw = dw;
6745 unrotDh = dh;
6746 }
Craig Mautner69b08182012-09-05 13:07:13 -07006747 int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, tmpDm, unrotDw, unrotDh);
6748 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, tmpDm, unrotDh, unrotDw);
6749 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, tmpDm, unrotDw, unrotDh);
6750 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, tmpDm, unrotDh, unrotDw);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006751 return sw;
6752 }
6753
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006754 boolean computeScreenConfigurationLocked(Configuration config) {
Jeff Browne215f262012-09-10 16:01:14 -07006755 if (!mDisplayReady) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07006756 return false;
6757 }
Christopher Tateb696aee2010-04-02 19:08:30 -07006758
Craig Mautner59c00972012-07-30 12:10:24 -07006759 // TODO(multidisplay): For now, apply Configuration to main screen only.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006760 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07006761
Christopher Tateb696aee2010-04-02 19:08:30 -07006762 // Use the effective "visual" dimensions based on current rotation
6763 final boolean rotated = (mRotation == Surface.ROTATION_90
6764 || mRotation == Surface.ROTATION_270);
Craig Mautner59c00972012-07-30 12:10:24 -07006765 final int realdw = rotated ?
6766 displayContent.mBaseDisplayHeight : displayContent.mBaseDisplayWidth;
6767 final int realdh = rotated ?
6768 displayContent.mBaseDisplayWidth : displayContent.mBaseDisplayHeight;
Jeff Brownfa25bf52012-07-23 19:26:30 -07006769 int dw = realdw;
6770 int dh = realdh;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006771
Jeff Brownfa25bf52012-07-23 19:26:30 -07006772 if (mAltOrientation) {
6773 if (realdw > realdh) {
6774 // Turn landscape into portrait.
6775 int maxw = (int)(realdh/1.3f);
6776 if (maxw < realdw) {
6777 dw = maxw;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006778 }
6779 } else {
Jeff Brownfa25bf52012-07-23 19:26:30 -07006780 // Turn portrait into landscape.
6781 int maxh = (int)(realdw/1.3f);
6782 if (maxh < realdh) {
6783 dh = maxh;
6784 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006785 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006786 }
6787
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006788 if (config != null) {
Jeff Browne215f262012-09-10 16:01:14 -07006789 config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
6790 Configuration.ORIENTATION_LANDSCAPE;
Dianne Hackbornc485a602009-03-24 22:39:49 -07006791 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006792
Jeff Brownbc68a592011-07-25 12:58:12 -07006793 // Update application display metrics.
Dianne Hackborn1fbee792011-11-30 11:29:58 -08006794 final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation);
6795 final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006796 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
6797 synchronized(displayContent.mDisplaySizeLock) {
6798 displayInfo.rotation = mRotation;
6799 displayInfo.logicalWidth = dw;
6800 displayInfo.logicalHeight = dh;
Dianne Hackborndde331c2012-08-03 14:01:57 -07006801 displayInfo.logicalDensityDpi = displayContent.mBaseDisplayDensity;
Craig Mautner59c00972012-07-30 12:10:24 -07006802 displayInfo.appWidth = appWidth;
6803 displayInfo.appHeight = appHeight;
6804 displayInfo.getLogicalMetrics(mRealDisplayMetrics, null);
6805 displayInfo.getAppMetrics(mDisplayMetrics, null);
Jeff Brownbd6e1502012-08-28 03:27:37 -07006806 mDisplayManagerService.setDisplayInfoOverrideFromWindowManager(
6807 displayContent.getDisplayId(), displayInfo);
Jeff Brownfa25bf52012-07-23 19:26:30 -07006808
6809 mAnimator.setDisplayDimensions(dw, dh, appWidth, appHeight);
Dianne Hackborn1fbee792011-11-30 11:29:58 -08006810 }
Dianne Hackborn36991742011-10-11 21:35:26 -07006811 if (false) {
Jeff Brownfa25bf52012-07-23 19:26:30 -07006812 Slog.i(TAG, "Set app display size: " + appWidth + " x " + appHeight);
Dianne Hackborn36991742011-10-11 21:35:26 -07006813 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006814
Jeff Brownfa25bf52012-07-23 19:26:30 -07006815 final DisplayMetrics dm = mDisplayMetrics;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006816 mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm,
6817 mCompatDisplayMetrics);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006818
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006819 if (config != null) {
6820 config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation)
6821 / dm.density);
6822 config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation)
6823 / dm.density);
Craig Mautner59c00972012-07-30 12:10:24 -07006824 computeSizeRangesAndScreenLayout(displayInfo, rotated, dw, dh, dm.density, config);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006825
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006826 config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
6827 config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
6828 config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dm, dw, dh);
Dianne Hackborndde331c2012-08-03 14:01:57 -07006829 config.densityDpi = displayContent.mBaseDisplayDensity;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006830
Jeff Browndaa37532012-05-01 15:54:03 -07006831 // Update the configuration based on available input devices, lid switch,
6832 // and platform configuration.
6833 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
6834 config.keyboard = Configuration.KEYBOARD_NOKEYS;
6835 config.navigation = Configuration.NAVIGATION_NONAV;
6836
6837 int keyboardPresence = 0;
6838 int navigationPresence = 0;
Craig Mautner1d961d42012-05-27 12:02:11 -07006839 final InputDevice[] devices = mInputManager.getInputDevices();
6840 final int len = devices.length;
6841 for (int i = 0; i < len; i++) {
6842 InputDevice device = devices[i];
Jeff Browndaa37532012-05-01 15:54:03 -07006843 if (!device.isVirtual()) {
6844 final int sources = device.getSources();
6845 final int presenceFlag = device.isExternal() ?
6846 WindowManagerPolicy.PRESENCE_EXTERNAL :
6847 WindowManagerPolicy.PRESENCE_INTERNAL;
6848
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -07006849 if (mIsTouchDevice) {
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006850 if ((sources & InputDevice.SOURCE_TOUCHSCREEN) ==
6851 InputDevice.SOURCE_TOUCHSCREEN) {
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -07006852 config.touchscreen = Configuration.TOUCHSCREEN_FINGER;
6853 }
6854 } else {
6855 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
Jeff Browndaa37532012-05-01 15:54:03 -07006856 }
6857
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006858 if ((sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) {
Jeff Browndaa37532012-05-01 15:54:03 -07006859 config.navigation = Configuration.NAVIGATION_TRACKBALL;
6860 navigationPresence |= presenceFlag;
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006861 } else if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD
Jeff Browndaa37532012-05-01 15:54:03 -07006862 && config.navigation == Configuration.NAVIGATION_NONAV) {
6863 config.navigation = Configuration.NAVIGATION_DPAD;
6864 navigationPresence |= presenceFlag;
6865 }
6866
6867 if (device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) {
6868 config.keyboard = Configuration.KEYBOARD_QWERTY;
6869 keyboardPresence |= presenceFlag;
6870 }
6871 }
6872 }
6873
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006874 // Determine whether a hard keyboard is available and enabled.
6875 boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
6876 if (hardKeyboardAvailable != mHardKeyboardAvailable) {
6877 mHardKeyboardAvailable = hardKeyboardAvailable;
6878 mHardKeyboardEnabled = hardKeyboardAvailable;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006879 mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
6880 mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
6881 }
6882 if (!mHardKeyboardEnabled) {
6883 config.keyboard = Configuration.KEYBOARD_NOKEYS;
6884 }
6885
Jeff Browndaa37532012-05-01 15:54:03 -07006886 // Let the policy update hidden states.
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006887 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
6888 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
6889 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO;
Jeff Browndaa37532012-05-01 15:54:03 -07006890 mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence);
Jeff Brown2992ea72011-01-28 22:04:14 -08006891 }
Jeff Brown597eec82011-01-31 17:12:25 -08006892
Dianne Hackbornc485a602009-03-24 22:39:49 -07006893 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006894 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006895
Jeff Brown2992ea72011-01-28 22:04:14 -08006896 public boolean isHardKeyboardAvailable() {
6897 synchronized (mWindowMap) {
6898 return mHardKeyboardAvailable;
6899 }
6900 }
6901
6902 public boolean isHardKeyboardEnabled() {
6903 synchronized (mWindowMap) {
6904 return mHardKeyboardEnabled;
6905 }
6906 }
6907
6908 public void setHardKeyboardEnabled(boolean enabled) {
6909 synchronized (mWindowMap) {
6910 if (mHardKeyboardEnabled != enabled) {
6911 mHardKeyboardEnabled = enabled;
6912 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
6913 }
6914 }
6915 }
6916
6917 public void setOnHardKeyboardStatusChangeListener(
6918 OnHardKeyboardStatusChangeListener listener) {
6919 synchronized (mWindowMap) {
6920 mHardKeyboardStatusChangeListener = listener;
6921 }
6922 }
6923
6924 void notifyHardKeyboardStatusChange() {
6925 final boolean available, enabled;
6926 final OnHardKeyboardStatusChangeListener listener;
6927 synchronized (mWindowMap) {
6928 listener = mHardKeyboardStatusChangeListener;
6929 available = mHardKeyboardAvailable;
6930 enabled = mHardKeyboardEnabled;
6931 }
6932 if (listener != null) {
6933 listener.onHardKeyboardStatusChange(available, enabled);
6934 }
6935 }
6936
Christopher Tatea53146c2010-09-07 11:57:52 -07006937 // -------------------------------------------------------------
6938 // Drag and drop
6939 // -------------------------------------------------------------
6940
6941 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006942 int flags, int width, int height, Surface outSurface) {
Christopher Tatea53146c2010-09-07 11:57:52 -07006943 if (DEBUG_DRAG) {
6944 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006945 + " flags=" + Integer.toHexString(flags) + " win=" + window
Christopher Tatea53146c2010-09-07 11:57:52 -07006946 + " asbinder=" + window.asBinder());
6947 }
6948
6949 final int callerPid = Binder.getCallingPid();
6950 final long origId = Binder.clearCallingIdentity();
6951 IBinder token = null;
6952
6953 try {
6954 synchronized (mWindowMap) {
6955 try {
Christopher Tatea53146c2010-09-07 11:57:52 -07006956 if (mDragState == null) {
Jeff Browne215f262012-09-10 16:01:14 -07006957 // TODO(multi-display): support other displays
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006958 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07006959 final Display display = displayContent.getDisplay();
Jeff Brown64a55af2012-08-26 02:47:39 -07006960 Surface surface = new Surface(session, "drag surface",
Christopher Tatea53146c2010-09-07 11:57:52 -07006961 width, height, PixelFormat.TRANSLUCENT, Surface.HIDDEN);
Jeff Browne215f262012-09-10 16:01:14 -07006962 surface.setLayerStack(display.getLayerStack());
Dianne Hackbornac1471a2011-02-03 13:46:06 -08006963 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DRAG "
6964 + surface + ": CREATE");
Christopher Tatea53146c2010-09-07 11:57:52 -07006965 outSurface.copyFrom(surface);
Chris Tate7b362e42010-11-04 16:02:52 -07006966 final IBinder winBinder = window.asBinder();
Christopher Tatea53146c2010-09-07 11:57:52 -07006967 token = new Binder();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006968 mDragState = new DragState(this, token, surface, /*flags*/ 0, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07006969 token = mDragState.mToken = new Binder();
6970
6971 // 5 second timeout for this window to actually begin the drag
Chris Tate7b362e42010-11-04 16:02:52 -07006972 mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
6973 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07006974 mH.sendMessageDelayed(msg, 5000);
6975 } else {
6976 Slog.w(TAG, "Drag already in progress");
6977 }
6978 } catch (Surface.OutOfResourcesException e) {
6979 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
6980 if (mDragState != null) {
6981 mDragState.reset();
6982 mDragState = null;
6983 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006984 }
6985 }
6986 } finally {
6987 Binder.restoreCallingIdentity(origId);
6988 }
6989
6990 return token;
6991 }
6992
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006993 // -------------------------------------------------------------
6994 // Input Events and Focus Management
6995 // -------------------------------------------------------------
Jeff Brown46b9ac02010-04-22 18:58:52 -07006996
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006997 final InputMonitor mInputMonitor = new InputMonitor(this);
Jeff Brown08a746a2012-06-24 12:14:49 -07006998 private boolean mEventDispatchingEnabled;
6999
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007000 public void pauseKeyDispatching(IBinder _token) {
7001 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
7002 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07007003 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007004 }
7005
7006 synchronized (mWindowMap) {
7007 WindowToken token = mTokenMap.get(_token);
7008 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07007009 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007010 }
7011 }
7012 }
7013
7014 public void resumeKeyDispatching(IBinder _token) {
7015 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
7016 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07007017 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007018 }
7019
7020 synchronized (mWindowMap) {
7021 WindowToken token = mTokenMap.get(_token);
7022 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07007023 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007024 }
7025 }
7026 }
7027
7028 public void setEventDispatching(boolean enabled) {
7029 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner3d7b7d52012-05-24 11:28:26 -07007030 "setEventDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07007031 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007032 }
7033
7034 synchronized (mWindowMap) {
Jeff Brown08a746a2012-06-24 12:14:49 -07007035 mEventDispatchingEnabled = enabled;
7036 if (mDisplayEnabled) {
7037 mInputMonitor.setEventDispatchingLw(enabled);
7038 }
Craig Mautner3d7b7d52012-05-24 11:28:26 -07007039 sendScreenStatusToClientsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007040 }
7041 }
Romain Guy06882f82009-06-10 13:36:04 -07007042
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07007043 public IBinder getFocusedWindowToken() {
7044 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
7045 "getFocusedWindowToken()")) {
7046 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
7047 }
Svetoslav Ganove15ccb92012-05-16 15:48:55 -07007048 synchronized (mWindowMap) {
7049 WindowState windowState = getFocusedWindowLocked();
7050 if (windowState != null) {
7051 return windowState.mClient.asBinder();
7052 }
7053 return null;
7054 }
7055 }
7056
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007057 private WindowState getFocusedWindow() {
7058 synchronized (mWindowMap) {
7059 return getFocusedWindowLocked();
7060 }
7061 }
7062
7063 private WindowState getFocusedWindowLocked() {
7064 return mCurrentFocus;
7065 }
Romain Guy06882f82009-06-10 13:36:04 -07007066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007067 public boolean detectSafeMode() {
Jeff Brownb09abc12011-01-13 21:08:27 -08007068 if (!mInputMonitor.waitForInputDevicesReady(
7069 INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
7070 Slog.w(TAG, "Devices still not ready after waiting "
Jeff Brownac143512012-04-05 18:57:33 -07007071 + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
7072 + " milliseconds before attempting to detect safe mode.");
Jeff Brownb09abc12011-01-13 21:08:27 -08007073 }
7074
Jeff Brownac143512012-04-05 18:57:33 -07007075 int menuState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
7076 KeyEvent.KEYCODE_MENU);
7077 int sState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, KeyEvent.KEYCODE_S);
7078 int dpadState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD,
7079 KeyEvent.KEYCODE_DPAD_CENTER);
7080 int trackballState = mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL,
Jeff Brownc458ce92012-04-30 14:58:40 -07007081 InputManagerService.BTN_MOUSE);
Jeff Brownac143512012-04-05 18:57:33 -07007082 int volumeDownState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
7083 KeyEvent.KEYCODE_VOLUME_DOWN);
7084 mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
7085 || volumeDownState > 0;
Dianne Hackborn19caadc2012-04-20 17:49:10 -07007086 try {
7087 if (SystemProperties.getInt(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, 0) != 0) {
7088 mSafeMode = true;
7089 SystemProperties.set(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, "");
7090 }
7091 } catch (IllegalArgumentException e) {
7092 }
Jeff Brownac143512012-04-05 18:57:33 -07007093 if (mSafeMode) {
7094 Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
7095 + " dpad=" + dpadState + " trackball=" + trackballState + ")");
7096 } else {
7097 Log.i(TAG, "SAFE MODE not enabled");
7098 }
7099 mPolicy.setSafeMode(mSafeMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007100 return mSafeMode;
7101 }
Romain Guy06882f82009-06-10 13:36:04 -07007102
Dianne Hackborn661cd522011-08-22 00:26:20 -07007103 public void displayReady() {
Jeff Browne215f262012-09-10 16:01:14 -07007104 displayReady(Display.DEFAULT_DISPLAY);
Craig Mautner4f67ba62012-08-02 11:23:00 -07007105
7106 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007107 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07007108 final Display display = displayContent.getDisplay();
7109 readForcedDisplaySizeAndDensityLocked(displayContent);
Dianne Hackborn5a052a42012-08-15 18:49:23 -07007110
Jeff Browne215f262012-09-10 16:01:14 -07007111 mDisplayReady = true;
Craig Mautner4f67ba62012-08-02 11:23:00 -07007112 mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
Jeff Browne215f262012-09-10 16:01:14 -07007113 PackageManager.FEATURE_TOUCHSCREEN);
Craig Mautner4f67ba62012-08-02 11:23:00 -07007114
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007115 final DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Jeff Browne215f262012-09-10 16:01:14 -07007116 mAnimator.setDisplayDimensions(
7117 displayInfo.logicalWidth, displayInfo.logicalHeight,
7118 displayInfo.appWidth, displayInfo.appHeight);
Craig Mautner4f67ba62012-08-02 11:23:00 -07007119
Jeff Browne215f262012-09-10 16:01:14 -07007120 mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
7121 displayContent.mInitialDisplayWidth,
7122 displayContent.mInitialDisplayHeight,
7123 displayContent.mInitialDisplayDensity);
Craig Mautner4f67ba62012-08-02 11:23:00 -07007124 }
Dianne Hackborn5a052a42012-08-15 18:49:23 -07007125
7126 try {
7127 mActivityManager.updateConfiguration(null);
7128 } catch (RemoteException e) {
7129 }
Craig Mautner59c00972012-07-30 12:10:24 -07007130 }
7131
7132 public void displayReady(int displayId) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07007133 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007134 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner4f67ba62012-08-02 11:23:00 -07007135 final DisplayInfo displayInfo;
Craig Mautnera91f9e22012-09-14 16:22:08 -07007136 mAnimator.addDisplayLocked(displayId);
Craig Mautner59c00972012-07-30 12:10:24 -07007137 synchronized(displayContent.mDisplaySizeLock) {
Jeff Brownfa25bf52012-07-23 19:26:30 -07007138 // Bootstrap the default logical display from the display manager.
Craig Mautner4f67ba62012-08-02 11:23:00 -07007139 displayInfo = displayContent.getDisplayInfo();
Jeff Brownbd6e1502012-08-28 03:27:37 -07007140 DisplayInfo newDisplayInfo = mDisplayManagerService.getDisplayInfo(displayId);
7141 if (newDisplayInfo != null) {
7142 displayInfo.copyFrom(newDisplayInfo);
7143 }
Craig Mautner59c00972012-07-30 12:10:24 -07007144 displayContent.mInitialDisplayWidth = displayInfo.logicalWidth;
7145 displayContent.mInitialDisplayHeight = displayInfo.logicalHeight;
Dianne Hackborndde331c2012-08-03 14:01:57 -07007146 displayContent.mInitialDisplayDensity = displayInfo.logicalDensityDpi;
Craig Mautner59c00972012-07-30 12:10:24 -07007147 displayContent.mBaseDisplayWidth = displayContent.mInitialDisplayWidth;
7148 displayContent.mBaseDisplayHeight = displayContent.mInitialDisplayHeight;
Dianne Hackborndde331c2012-08-03 14:01:57 -07007149 displayContent.mBaseDisplayDensity = displayContent.mInitialDisplayDensity;
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007150 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07007151 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07007152 }
7153
Dianne Hackborn661cd522011-08-22 00:26:20 -07007154 public void systemReady() {
7155 mPolicy.systemReady();
7156 }
7157
Craig Mautner59c00972012-07-30 12:10:24 -07007158 // TODO(multidisplay): Call isScreenOn for each display.
Craig Mautner3d7b7d52012-05-24 11:28:26 -07007159 private void sendScreenStatusToClientsLocked() {
Craig Mautner59c00972012-07-30 12:10:24 -07007160 final boolean on = mPowerManager.isScreenOn();
7161 final AllWindowsIterator iterator = new AllWindowsIterator();
7162 while (iterator.hasNext()) {
Romain Guy7e4e5612012-03-05 14:37:29 -08007163 try {
Craig Mautner59c00972012-07-30 12:10:24 -07007164 iterator.next().mClient.dispatchScreenState(on);
Romain Guy7e4e5612012-03-05 14:37:29 -08007165 } catch (RemoteException e) {
7166 // Ignored
7167 }
7168 }
7169 }
7170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007171 // -------------------------------------------------------------
7172 // Async Handler
7173 // -------------------------------------------------------------
7174
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08007175 final class H extends Handler {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007176 public static final int REPORT_FOCUS_CHANGE = 2;
7177 public static final int REPORT_LOSING_FOCUS = 3;
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08007178 public static final int DO_TRAVERSAL = 4;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007179 public static final int ADD_STARTING = 5;
7180 public static final int REMOVE_STARTING = 6;
7181 public static final int FINISHED_STARTING = 7;
7182 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07007183 public static final int REPORT_APPLICATION_TOKEN_DRAWN = 9;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007184 public static final int WINDOW_FREEZE_TIMEOUT = 11;
Craig Mautner259328c2012-08-21 19:30:58 -07007185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007186 public static final int APP_TRANSITION_TIMEOUT = 13;
7187 public static final int PERSIST_ANIMATION_SCALE = 14;
7188 public static final int FORCE_GC = 15;
7189 public static final int ENABLE_SCREEN = 16;
7190 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007191 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07007192 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07007193 public static final int DRAG_START_TIMEOUT = 20;
Chris Tated4533f12010-10-19 15:15:08 -07007194 public static final int DRAG_END_TIMEOUT = 21;
Jeff Brown2992ea72011-01-28 22:04:14 -08007195 public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07007196 public static final int BOOT_TIMEOUT = 23;
Dianne Hackborn38e29a62011-09-18 14:43:08 -07007197 public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
Craig Mautner01cd0e72012-06-18 10:19:11 -07007198 public static final int UPDATE_ANIM_PARAMETERS = 25;
Craig Mautner0447a812012-05-22 16:01:31 -07007199 public static final int SHOW_STRICT_MODE_VIOLATION = 26;
Dianne Hackborn84375872012-06-01 19:03:50 -07007200 public static final int DO_ANIMATION_CALLBACK = 27;
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07007201 public static final int NOTIFY_ROTATION_CHANGED = 28;
7202 public static final int NOTIFY_WINDOW_TRANSITION = 29;
7203 public static final int NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED = 30;
Romain Guy06882f82009-06-10 13:36:04 -07007204
Craig Mautner722285e2012-09-07 13:55:58 -07007205 public static final int DO_DISPLAY_ADDED = 31;
7206 public static final int DO_DISPLAY_REMOVED = 32;
7207 public static final int DO_DISPLAY_CHANGED = 33;
7208
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007209 public static final int CLIENT_FREEZE_TIMEOUT = 34;
7210
Craig Mautner48ba1e72012-04-02 13:18:16 -07007211 public static final int ANIMATOR_WHAT_OFFSET = 100000;
7212 public static final int SET_TRANSPARENT_REGION = ANIMATOR_WHAT_OFFSET + 1;
Craig Mautner12670b52012-07-03 19:15:35 -07007213 public static final int CLEAR_PENDING_ACTIONS = ANIMATOR_WHAT_OFFSET + 2;
Craig Mautner48ba1e72012-04-02 13:18:16 -07007214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007215 public H() {
7216 }
Romain Guy06882f82009-06-10 13:36:04 -07007217
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007218 @Override
7219 public void handleMessage(Message msg) {
Craig Mautner7d8df392012-04-06 15:26:23 -07007220 if (DEBUG_WINDOW_TRACE) {
7221 Slog.v(TAG, "handleMessage: entry what=" + msg.what);
7222 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007223 switch (msg.what) {
7224 case REPORT_FOCUS_CHANGE: {
7225 WindowState lastFocus;
7226 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07007227
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007228 synchronized(mWindowMap) {
7229 lastFocus = mLastFocus;
7230 newFocus = mCurrentFocus;
7231 if (lastFocus == newFocus) {
7232 // Focus is not changing, so nothing to do.
7233 return;
7234 }
7235 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007236 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007237 // + " to " + newFocus);
7238 if (newFocus != null && lastFocus != null
7239 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007240 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007241 mLosingFocus.add(lastFocus);
7242 lastFocus = null;
7243 }
7244 }
7245
7246 if (lastFocus != newFocus) {
7247 //System.out.println("Changing focus from " + lastFocus
7248 // + " to " + newFocus);
7249 if (newFocus != null) {
7250 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007251 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007252 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
7253 } catch (RemoteException e) {
7254 // Ignore if process has died.
7255 }
Konstantin Lopyrev5e7833a2010-08-09 17:01:11 -07007256 notifyFocusChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007257 }
7258
7259 if (lastFocus != null) {
7260 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007261 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007262 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
7263 } catch (RemoteException e) {
7264 // Ignore if process has died.
7265 }
7266 }
7267 }
7268 } break;
7269
7270 case REPORT_LOSING_FOCUS: {
7271 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07007272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007273 synchronized(mWindowMap) {
7274 losers = mLosingFocus;
7275 mLosingFocus = new ArrayList<WindowState>();
7276 }
7277
7278 final int N = losers.size();
7279 for (int i=0; i<N; i++) {
7280 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007281 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007282 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
7283 } catch (RemoteException e) {
7284 // Ignore if process has died.
7285 }
7286 }
7287 } break;
7288
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08007289 case DO_TRAVERSAL: {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007290 synchronized(mWindowMap) {
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08007291 mTraversalScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007292 performLayoutAndPlaceSurfacesLocked();
7293 }
7294 } break;
7295
7296 case ADD_STARTING: {
7297 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7298 final StartingData sd = wtoken.startingData;
7299
7300 if (sd == null) {
7301 // Animation has been canceled... do nothing.
7302 return;
7303 }
Romain Guy06882f82009-06-10 13:36:04 -07007304
Joe Onorato8a9b2202010-02-26 18:56:32 -08007305 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007306 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07007307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007308 View view = null;
7309 try {
7310 view = mPolicy.addStartingWindow(
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07007311 wtoken.token, sd.pkg, sd.theme, sd.compatInfo,
7312 sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007313 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007314 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007315 }
7316
7317 if (view != null) {
7318 boolean abort = false;
7319
7320 synchronized(mWindowMap) {
7321 if (wtoken.removed || wtoken.startingData == null) {
7322 // If the window was successfully added, then
7323 // we need to remove it.
7324 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007325 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007326 "Aborted starting " + wtoken
7327 + ": removed=" + wtoken.removed
7328 + " startingData=" + wtoken.startingData);
7329 wtoken.startingWindow = null;
7330 wtoken.startingData = null;
7331 abort = true;
7332 }
7333 } else {
7334 wtoken.startingView = view;
7335 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007336 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007337 "Added starting " + wtoken
7338 + ": startingWindow="
7339 + wtoken.startingWindow + " startingView="
7340 + wtoken.startingView);
7341 }
7342
7343 if (abort) {
7344 try {
7345 mPolicy.removeStartingWindow(wtoken.token, view);
7346 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007347 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007348 }
7349 }
7350 }
7351 } break;
7352
7353 case REMOVE_STARTING: {
7354 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7355 IBinder token = null;
7356 View view = null;
7357 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007358 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007359 + wtoken + ": startingWindow="
7360 + wtoken.startingWindow + " startingView="
7361 + wtoken.startingView);
7362 if (wtoken.startingWindow != null) {
7363 view = wtoken.startingView;
7364 token = wtoken.token;
7365 wtoken.startingData = null;
7366 wtoken.startingView = null;
7367 wtoken.startingWindow = null;
Craig Mautner38b24782012-07-02 16:21:28 -07007368 wtoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007369 }
7370 }
7371 if (view != null) {
7372 try {
7373 mPolicy.removeStartingWindow(token, view);
7374 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007375 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007376 }
7377 }
7378 } break;
7379
7380 case FINISHED_STARTING: {
7381 IBinder token = null;
7382 View view = null;
7383 while (true) {
7384 synchronized (mWindowMap) {
7385 final int N = mFinishedStarting.size();
7386 if (N <= 0) {
7387 break;
7388 }
7389 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
7390
Joe Onorato8a9b2202010-02-26 18:56:32 -08007391 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007392 "Finished starting " + wtoken
7393 + ": startingWindow=" + wtoken.startingWindow
7394 + " startingView=" + wtoken.startingView);
7395
7396 if (wtoken.startingWindow == null) {
7397 continue;
7398 }
7399
7400 view = wtoken.startingView;
7401 token = wtoken.token;
7402 wtoken.startingData = null;
7403 wtoken.startingView = null;
7404 wtoken.startingWindow = null;
Craig Mautner38b24782012-07-02 16:21:28 -07007405 wtoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007406 }
7407
7408 try {
7409 mPolicy.removeStartingWindow(token, view);
7410 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007411 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007412 }
7413 }
7414 } break;
7415
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07007416 case REPORT_APPLICATION_TOKEN_DRAWN: {
7417 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7418
7419 try {
7420 if (DEBUG_VISIBILITY) Slog.v(
7421 TAG, "Reporting drawn in " + wtoken);
7422 wtoken.appToken.windowsDrawn();
7423 } catch (RemoteException ex) {
7424 }
7425 } break;
7426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007427 case REPORT_APPLICATION_TOKEN_WINDOWS: {
7428 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7429
7430 boolean nowVisible = msg.arg1 != 0;
7431 boolean nowGone = msg.arg2 != 0;
7432
7433 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007434 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007435 TAG, "Reporting visible in " + wtoken
7436 + " visible=" + nowVisible
7437 + " gone=" + nowGone);
7438 if (nowVisible) {
7439 wtoken.appToken.windowsVisible();
7440 } else {
7441 wtoken.appToken.windowsGone();
7442 }
7443 } catch (RemoteException ex) {
7444 }
7445 } break;
Romain Guy06882f82009-06-10 13:36:04 -07007446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007447 case WINDOW_FREEZE_TIMEOUT: {
Craig Mautner59c00972012-07-30 12:10:24 -07007448 // TODO(multidisplay): Can non-default displays rotate?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007449 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007450 Slog.w(TAG, "Window freeze timeout expired.");
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007451 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07007452 int i = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007453 while (i > 0) {
7454 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07007455 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007456 if (w.mOrientationChanging) {
7457 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007458 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007459 }
7460 }
7461 performLayoutAndPlaceSurfacesLocked();
7462 }
7463 break;
7464 }
Romain Guy06882f82009-06-10 13:36:04 -07007465
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007466 case APP_TRANSITION_TIMEOUT: {
7467 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07007468 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007469 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007470 "*** APP TRANSITION TIMEOUT");
7471 mAppTransitionReady = true;
7472 mAppTransitionTimeout = true;
Craig Mautneref25d7a2012-05-15 23:01:47 -07007473 mAnimatingAppTokens.clear();
7474 mAnimatingAppTokens.addAll(mAppTokens);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007475 performLayoutAndPlaceSurfacesLocked();
7476 }
7477 }
7478 break;
7479 }
Romain Guy06882f82009-06-10 13:36:04 -07007480
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007481 case PERSIST_ANIMATION_SCALE: {
7482 Settings.System.putFloat(mContext.getContentResolver(),
7483 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
7484 Settings.System.putFloat(mContext.getContentResolver(),
7485 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Chet Haasec38fa1f2012-02-01 16:37:46 -08007486 Settings.System.putFloat(mContext.getContentResolver(),
7487 Settings.System.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007488 break;
7489 }
Romain Guy06882f82009-06-10 13:36:04 -07007490
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007491 case FORCE_GC: {
Craig Mautner1caa3992012-06-22 09:46:48 -07007492 synchronized (mWindowMap) {
7493 synchronized (mAnimator) {
7494 // Since we're holding both mWindowMap and mAnimator we don't need to
7495 // hold mAnimator.mLayoutToAnim.
Craig Mautner711f90a2012-07-03 18:43:52 -07007496 if (mAnimator.mAnimating || mLayoutToAnim.mAnimationScheduled) {
Craig Mautner1caa3992012-06-22 09:46:48 -07007497 // If we are animating, don't do the gc now but
7498 // delay a bit so we don't interrupt the animation.
7499 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
7500 2000);
7501 return;
7502 }
7503 // If we are currently rotating the display, it will
7504 // schedule a new message when done.
7505 if (mDisplayFrozen) {
7506 return;
7507 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007508 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007509 }
7510 Runtime.getRuntime().gc();
7511 break;
7512 }
Romain Guy06882f82009-06-10 13:36:04 -07007513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007514 case ENABLE_SCREEN: {
7515 performEnableScreen();
7516 break;
7517 }
Romain Guy06882f82009-06-10 13:36:04 -07007518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007519 case APP_FREEZE_TIMEOUT: {
7520 synchronized (mWindowMap) {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07007521 synchronized (mAnimator) {
7522 Slog.w(TAG, "App freeze timeout expired.");
7523 int i = mAppTokens.size();
7524 while (i > 0) {
7525 i--;
7526 AppWindowToken tok = mAppTokens.get(i);
Craig Mautner59431632012-04-04 11:56:44 -07007527 if (tok.mAppAnimator.freezingScreen) {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07007528 Slog.w(TAG, "Force clearing freeze: " + tok);
7529 unsetAppFreezingScreenLocked(tok, true, true);
7530 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007531 }
7532 }
7533 }
7534 break;
7535 }
Romain Guy06882f82009-06-10 13:36:04 -07007536
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007537 case CLIENT_FREEZE_TIMEOUT: {
7538 synchronized (mWindowMap) {
7539 if (mClientFreezingScreen) {
7540 mClientFreezingScreen = false;
7541 stopFreezingDisplayLocked();
7542 }
7543 }
7544 break;
7545 }
7546
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007547 case SEND_NEW_CONFIGURATION: {
7548 removeMessages(SEND_NEW_CONFIGURATION);
7549 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07007550 break;
7551 }
Romain Guy06882f82009-06-10 13:36:04 -07007552
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07007553 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007554 if (mWindowsChanged) {
7555 synchronized (mWindowMap) {
7556 mWindowsChanged = false;
7557 }
7558 notifyWindowsChanged();
7559 }
7560 break;
7561 }
7562
Christopher Tatea53146c2010-09-07 11:57:52 -07007563 case DRAG_START_TIMEOUT: {
7564 IBinder win = (IBinder)msg.obj;
7565 if (DEBUG_DRAG) {
7566 Slog.w(TAG, "Timeout starting drag by win " + win);
7567 }
7568 synchronized (mWindowMap) {
7569 // !!! TODO: ANR the app that has failed to start the drag in time
7570 if (mDragState != null) {
Chris Tated4533f12010-10-19 15:15:08 -07007571 mDragState.unregister();
Jeff Brown2e44b072011-01-24 15:21:56 -08007572 mInputMonitor.updateInputWindowsLw(true /*force*/);
Christopher Tatea53146c2010-09-07 11:57:52 -07007573 mDragState.reset();
7574 mDragState = null;
7575 }
7576 }
Chris Tated4533f12010-10-19 15:15:08 -07007577 break;
Christopher Tatea53146c2010-09-07 11:57:52 -07007578 }
7579
Chris Tated4533f12010-10-19 15:15:08 -07007580 case DRAG_END_TIMEOUT: {
7581 IBinder win = (IBinder)msg.obj;
7582 if (DEBUG_DRAG) {
7583 Slog.w(TAG, "Timeout ending drag to win " + win);
7584 }
7585 synchronized (mWindowMap) {
7586 // !!! TODO: ANR the drag-receiving app
Christopher Tated9be36c2011-08-16 16:09:33 -07007587 if (mDragState != null) {
7588 mDragState.mDragResult = false;
7589 mDragState.endDragLw();
7590 }
Chris Tated4533f12010-10-19 15:15:08 -07007591 }
7592 break;
7593 }
Jeff Brown2992ea72011-01-28 22:04:14 -08007594
7595 case REPORT_HARD_KEYBOARD_STATUS_CHANGE: {
7596 notifyHardKeyboardStatusChange();
7597 break;
7598 }
Dianne Hackborn38e29a62011-09-18 14:43:08 -07007599
7600 case BOOT_TIMEOUT: {
7601 performBootTimeout();
7602 break;
7603 }
7604
7605 case WAITING_FOR_DRAWN_TIMEOUT: {
7606 Pair<WindowState, IRemoteCallback> pair;
7607 synchronized (mWindowMap) {
7608 pair = (Pair<WindowState, IRemoteCallback>)msg.obj;
7609 Slog.w(TAG, "Timeout waiting for drawn: " + pair.first);
7610 if (!mWaitingForDrawn.remove(pair)) {
7611 return;
7612 }
7613 }
7614 try {
7615 pair.second.sendResult(null);
7616 } catch (RemoteException e) {
7617 }
7618 break;
7619 }
Craig Mautnera608b882012-03-30 13:03:49 -07007620
Craig Mautner01cd0e72012-06-18 10:19:11 -07007621 case UPDATE_ANIM_PARAMETERS: {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07007622 // Used to send multiple changes from the animation side to the layout side.
Craig Mautnera608b882012-03-30 13:03:49 -07007623 synchronized (mWindowMap) {
Craig Mautner322e4032012-07-13 13:35:20 -07007624 if (copyAnimToLayoutParamsLocked()) {
7625 mH.sendEmptyMessage(CLEAR_PENDING_ACTIONS);
7626 performLayoutAndPlaceSurfacesLocked();
Craig Mautner73850cb2012-04-10 12:56:27 -07007627 }
Craig Mautnera608b882012-03-30 13:03:49 -07007628 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07007629 break;
7630 }
7631
Craig Mautner0447a812012-05-22 16:01:31 -07007632 case SHOW_STRICT_MODE_VIOLATION: {
7633 showStrictModeViolation(msg.arg1);
7634 break;
7635 }
7636
Craig Mautner48ba1e72012-04-02 13:18:16 -07007637 // Animation messages. Move to Window{State}Animator
7638 case SET_TRANSPARENT_REGION: {
Craig Mautnerbec53f72012-04-05 11:49:05 -07007639 Pair<WindowStateAnimator, Region> pair =
Craig Mautner48ba1e72012-04-02 13:18:16 -07007640 (Pair<WindowStateAnimator, Region>) msg.obj;
Craig Mautnerbec53f72012-04-05 11:49:05 -07007641 final WindowStateAnimator winAnimator = pair.first;
7642 winAnimator.setTransparentRegionHint(pair.second);
Craig Mautner48ba1e72012-04-02 13:18:16 -07007643 break;
7644 }
7645
Craig Mautner4d7349b2012-04-20 14:52:47 -07007646 case CLEAR_PENDING_ACTIONS: {
7647 mAnimator.clearPendingActions();
7648 break;
7649 }
Dianne Hackborn84375872012-06-01 19:03:50 -07007650
7651 case DO_ANIMATION_CALLBACK: {
7652 try {
7653 ((IRemoteCallback)msg.obj).sendResult(null);
7654 } catch (RemoteException e) {
7655 }
7656 break;
7657 }
Craig Mautner722285e2012-09-07 13:55:58 -07007658
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07007659 case NOTIFY_ROTATION_CHANGED: {
7660 final int displayId = msg.arg1;
7661 final int rotation = msg.arg2;
7662 handleNotifyRotationChanged(displayId, rotation);
7663 break;
7664 }
Craig Mautner722285e2012-09-07 13:55:58 -07007665
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07007666 case NOTIFY_WINDOW_TRANSITION: {
7667 final int transition = msg.arg1;
7668 WindowInfo info = (WindowInfo) msg.obj;
7669 handleNotifyWindowTranstion(transition, info);
7670 break;
7671 }
Craig Mautner722285e2012-09-07 13:55:58 -07007672
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07007673 case NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED: {
7674 final int displayId = msg.arg1;
7675 final boolean immediate = (msg.arg2 == 1);
7676 Rect rectangle = (Rect) msg.obj;
7677 handleNotifyRectangleOnScreenRequested(displayId, rectangle, immediate);
7678 break;
7679 }
Craig Mautner722285e2012-09-07 13:55:58 -07007680
7681 case DO_DISPLAY_ADDED:
7682 synchronized (mWindowMap) {
7683 handleDisplayAddedLocked(msg.arg1);
7684 }
7685 break;
7686
7687 case DO_DISPLAY_REMOVED:
7688 synchronized (mWindowMap) {
7689 handleDisplayRemovedLocked(msg.arg1);
7690 }
7691 break;
7692
7693 case DO_DISPLAY_CHANGED:
7694 synchronized (mWindowMap) {
7695 handleDisplayChangedLocked(msg.arg1);
7696 }
7697 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007698 }
Craig Mautner7d8df392012-04-06 15:26:23 -07007699 if (DEBUG_WINDOW_TRACE) {
7700 Slog.v(TAG, "handleMessage: exit");
7701 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007702 }
7703 }
7704
7705 // -------------------------------------------------------------
7706 // IWindowManager API
7707 // -------------------------------------------------------------
7708
Craig Mautner7d8df392012-04-06 15:26:23 -07007709 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007710 public IWindowSession openSession(IInputMethodClient client,
7711 IInputContext inputContext) {
7712 if (client == null) throw new IllegalArgumentException("null client");
7713 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08007714 Session session = new Session(this, client, inputContext);
Jeff Brown46b9ac02010-04-22 18:58:52 -07007715 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007716 }
7717
Craig Mautner7d8df392012-04-06 15:26:23 -07007718 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007719 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
7720 synchronized (mWindowMap) {
7721 // The focus for the client is the window immediately below
7722 // where we would place the input method window.
7723 int idx = findDesiredInputMethodWindowIndexLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007724 if (idx > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07007725 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007726 WindowState imFocus = getDefaultWindowListLocked().get(idx-1);
Dianne Hackbornac920872012-05-22 11:49:49 -07007727 if (DEBUG_INPUT_METHOD) {
7728 Slog.i(TAG, "Desired input method target: " + imFocus);
Craig Mautner59c00972012-07-30 12:10:24 -07007729 Slog.i(TAG, "Current focus: " + mCurrentFocus);
7730 Slog.i(TAG, "Last focus: " + mLastFocus);
Dianne Hackbornac920872012-05-22 11:49:49 -07007731 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007732 if (imFocus != null) {
Dianne Hackborne75d8722011-01-27 19:37:40 -08007733 // This may be a starting window, in which case we still want
7734 // to count it as okay.
7735 if (imFocus.mAttrs.type == LayoutParams.TYPE_APPLICATION_STARTING
7736 && imFocus.mAppToken != null) {
7737 // The client has definitely started, so it really should
7738 // have a window in this app token. Let's look for it.
7739 for (int i=0; i<imFocus.mAppToken.windows.size(); i++) {
7740 WindowState w = imFocus.mAppToken.windows.get(i);
7741 if (w != imFocus) {
Dianne Hackbornac920872012-05-22 11:49:49 -07007742 Log.i(TAG, "Switching to real app window: " + w);
Dianne Hackborne75d8722011-01-27 19:37:40 -08007743 imFocus = w;
7744 break;
7745 }
7746 }
7747 }
Dianne Hackbornac920872012-05-22 11:49:49 -07007748 if (DEBUG_INPUT_METHOD) {
7749 Slog.i(TAG, "IM target client: " + imFocus.mSession.mClient);
7750 if (imFocus.mSession.mClient != null) {
7751 Slog.i(TAG, "IM target client binder: "
7752 + imFocus.mSession.mClient.asBinder());
7753 Slog.i(TAG, "Requesting client binder: " + client.asBinder());
7754 }
7755 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007756 if (imFocus.mSession.mClient != null &&
7757 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
7758 return true;
7759 }
7760 }
7761 }
Craig Mautner59c00972012-07-30 12:10:24 -07007762
7763 // Okay, how about this... what is the current focus?
7764 // It seems in some cases we may not have moved the IM
7765 // target window, such as when it was in a pop-up window,
7766 // so let's also look at the current focus. (An example:
7767 // go to Gmail, start searching so the keyboard goes up,
7768 // press home. Sometimes the IME won't go down.)
7769 // Would be nice to fix this more correctly, but it's
7770 // way at the end of a release, and this should be good enough.
7771 if (mCurrentFocus != null && mCurrentFocus.mSession.mClient != null
7772 && mCurrentFocus.mSession.mClient.asBinder() == client.asBinder()) {
7773 return true;
7774 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007775 }
7776 return false;
7777 }
Romain Guy06882f82009-06-10 13:36:04 -07007778
Craig Mautner59c00972012-07-30 12:10:24 -07007779 public void getInitialDisplaySize(int displayId, Point size) {
7780 // TODO(cmautner): Access to DisplayContent should be locked on mWindowMap. Doing that
7781 // could lead to deadlock since this is called from ActivityManager.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007782 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner59c00972012-07-30 12:10:24 -07007783 synchronized(displayContent.mDisplaySizeLock) {
7784 size.x = displayContent.mInitialDisplayWidth;
7785 size.y = displayContent.mInitialDisplayHeight;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007786 }
7787 }
7788
Jeff Brown43aa1592012-09-10 17:36:31 -07007789 public void setForcedDisplaySize(int displayId, int width, int height) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007790 synchronized(mWindowMap) {
Jeff Brown43aa1592012-09-10 17:36:31 -07007791 // Set some sort of reasonable bounds on the size of the display that we
7792 // will try to emulate.
7793 final int MIN_WIDTH = 200;
7794 final int MIN_HEIGHT = 200;
7795 final int MAX_SCALE = 2;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007796 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Jeff Brown43aa1592012-09-10 17:36:31 -07007797
7798 width = Math.min(Math.max(width, MIN_WIDTH),
7799 displayContent.mInitialDisplayWidth * MAX_SCALE);
7800 height = Math.min(Math.max(height, MIN_HEIGHT),
7801 displayContent.mInitialDisplayHeight * MAX_SCALE);
Craig Mautner59c00972012-07-30 12:10:24 -07007802 setForcedDisplaySizeLocked(displayContent, width, height);
Jeff Brown43aa1592012-09-10 17:36:31 -07007803 Settings.Global.putString(mContext.getContentResolver(),
7804 Settings.Global.DISPLAY_SIZE_FORCED, width + "," + height);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007805 }
7806 }
7807
Dianne Hackborndde331c2012-08-03 14:01:57 -07007808 private void readForcedDisplaySizeAndDensityLocked(final DisplayContent displayContent) {
Jeff Brown43aa1592012-09-10 17:36:31 -07007809 final String sizeStr = Settings.Global.getString(mContext.getContentResolver(),
7810 Settings.Global.DISPLAY_SIZE_FORCED);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007811 if (sizeStr != null && sizeStr.length() > 0) {
7812 final int pos = sizeStr.indexOf(',');
7813 if (pos > 0 && sizeStr.lastIndexOf(',') == pos) {
7814 int width, height;
7815 try {
7816 width = Integer.parseInt(sizeStr.substring(0, pos));
7817 height = Integer.parseInt(sizeStr.substring(pos+1));
7818 synchronized(displayContent.mDisplaySizeLock) {
7819 if (displayContent.mBaseDisplayWidth != width
7820 || displayContent.mBaseDisplayHeight != height) {
Dianne Hackborndde331c2012-08-03 14:01:57 -07007821 Slog.i(TAG, "FORCED DISPLAY SIZE: " + width + "x" + height);
7822 displayContent.mBaseDisplayWidth = width;
7823 displayContent.mBaseDisplayHeight = height;
7824 }
7825 }
7826 } catch (NumberFormatException ex) {
7827 }
7828 }
Joe Onorato571ae902011-05-24 13:48:43 -07007829 }
Jeff Brown43aa1592012-09-10 17:36:31 -07007830 final String densityStr = Settings.Global.getString(mContext.getContentResolver(),
7831 Settings.Global.DISPLAY_DENSITY_FORCED);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007832 if (densityStr != null && densityStr.length() > 0) {
7833 int density;
7834 try {
7835 density = Integer.parseInt(densityStr);
7836 synchronized(displayContent.mDisplaySizeLock) {
7837 if (displayContent.mBaseDisplayDensity != density) {
Dianne Hackborndde331c2012-08-03 14:01:57 -07007838 Slog.i(TAG, "FORCED DISPLAY DENSITY: " + density);
7839 displayContent.mBaseDisplayDensity = density;
7840 }
7841 }
7842 } catch (NumberFormatException ex) {
7843 }
Joe Onorato571ae902011-05-24 13:48:43 -07007844 }
Joe Onorato571ae902011-05-24 13:48:43 -07007845 }
7846
Craig Mautner59c00972012-07-30 12:10:24 -07007847 private void setForcedDisplaySizeLocked(DisplayContent displayContent, int width, int height) {
Joe Onorato571ae902011-05-24 13:48:43 -07007848 Slog.i(TAG, "Using new display size: " + width + "x" + height);
7849
Craig Mautner59c00972012-07-30 12:10:24 -07007850 synchronized(displayContent.mDisplaySizeLock) {
7851 displayContent.mBaseDisplayWidth = width;
7852 displayContent.mBaseDisplayHeight = height;
Dianne Hackborn1fbee792011-11-30 11:29:58 -08007853 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007854 reconfigureDisplayLocked(displayContent);
7855 }
7856
7857 public void clearForcedDisplaySize(int displayId) {
7858 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007859 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007860 setForcedDisplaySizeLocked(displayContent, displayContent.mInitialDisplayWidth,
7861 displayContent.mInitialDisplayHeight);
Jeff Brown43aa1592012-09-10 17:36:31 -07007862 Settings.Global.putString(mContext.getContentResolver(),
7863 Settings.Global.DISPLAY_SIZE_FORCED, "");
Dianne Hackborndde331c2012-08-03 14:01:57 -07007864 }
7865 }
7866
7867 public void setForcedDisplayDensity(int displayId, int density) {
7868 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007869 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007870 setForcedDisplayDensityLocked(displayContent, density);
Jeff Brown43aa1592012-09-10 17:36:31 -07007871 Settings.Global.putString(mContext.getContentResolver(),
7872 Settings.Global.DISPLAY_DENSITY_FORCED, Integer.toString(density));
Dianne Hackborndde331c2012-08-03 14:01:57 -07007873 }
7874 }
7875
7876 private void setForcedDisplayDensityLocked(DisplayContent displayContent, int density) {
7877 Slog.i(TAG, "Using new display density: " + density);
7878
7879 synchronized(displayContent.mDisplaySizeLock) {
7880 displayContent.mBaseDisplayDensity = density;
7881 }
7882 reconfigureDisplayLocked(displayContent);
7883 }
7884
7885 public void clearForcedDisplayDensity(int displayId) {
7886 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007887 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007888 setForcedDisplayDensityLocked(displayContent, displayContent.mInitialDisplayDensity);
Jeff Brownbf6f6f92012-09-25 15:03:20 -07007889 Settings.Global.putString(mContext.getContentResolver(),
7890 Settings.Global.DISPLAY_DENSITY_FORCED, "");
Dianne Hackborndde331c2012-08-03 14:01:57 -07007891 }
7892 }
7893
7894 private void reconfigureDisplayLocked(DisplayContent displayContent) {
Craig Mautner69b08182012-09-05 13:07:13 -07007895 // TODO: Multidisplay: for now only use with default display.
Jeff Browne215f262012-09-10 16:01:14 -07007896 mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
7897 displayContent.mBaseDisplayWidth,
7898 displayContent.mBaseDisplayHeight,
7899 displayContent.mBaseDisplayDensity);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007900
Craig Mautner19d59bc2012-09-04 11:15:56 -07007901 displayContent.layoutNeeded = true;
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007902
7903 boolean configChanged = updateOrientationFromAppTokensLocked(false);
7904 mTempConfiguration.setToDefaults();
7905 mTempConfiguration.fontScale = mCurConfiguration.fontScale;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08007906 if (computeScreenConfigurationLocked(mTempConfiguration)) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007907 if (mCurConfiguration.diff(mTempConfiguration) != 0) {
7908 configChanged = true;
7909 }
7910 }
7911
7912 if (configChanged) {
7913 mWaitingForConfig = true;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007914 startFreezingDisplayLocked(false, 0, 0);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007915 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
7916 }
7917
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007918 performLayoutAndPlaceSurfacesLocked();
7919 }
7920
Dianne Hackbornf87d1962012-04-04 12:48:24 -07007921 public boolean hasSystemNavBar() {
7922 return mPolicy.hasSystemNavBar();
Dianne Hackborn81e56d52011-05-26 00:55:58 -07007923 }
7924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007925 // -------------------------------------------------------------
7926 // Internals
7927 // -------------------------------------------------------------
7928
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007929 final WindowState windowForClientLocked(Session session, IWindow client,
7930 boolean throwOnError) {
7931 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007932 }
Romain Guy06882f82009-06-10 13:36:04 -07007933
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007934 final WindowState windowForClientLocked(Session session, IBinder client,
7935 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007936 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007937 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007938 TAG, "Looking up client " + client + ": " + win);
7939 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007940 RuntimeException ex = new IllegalArgumentException(
7941 "Requested window " + client + " does not exist");
7942 if (throwOnError) {
7943 throw ex;
7944 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007945 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007946 return null;
7947 }
7948 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007949 RuntimeException ex = new IllegalArgumentException(
7950 "Requested window " + client + " is in session " +
7951 win.mSession + ", not " + session);
7952 if (throwOnError) {
7953 throw ex;
7954 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007955 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007956 return null;
7957 }
7958
7959 return win;
7960 }
7961
Dianne Hackborna8f60182009-09-01 19:01:50 -07007962 final void rebuildAppWindowListLocked() {
Craig Mautner59c00972012-07-30 12:10:24 -07007963 DisplayContentsIterator iterator = new DisplayContentsIterator();
7964 while (iterator.hasNext()) {
7965 rebuildAppWindowListLocked(iterator.next());
7966 }
7967 }
7968
7969 private void rebuildAppWindowListLocked(final DisplayContent displayContent) {
7970 final WindowList windows = displayContent.getWindowList();
7971 int NW = windows.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07007972 int i;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007973 int lastBelow = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007974 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007975
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007976 if (mRebuildTmp.length < NW) {
7977 mRebuildTmp = new WindowState[NW+10];
7978 }
7979
Dianne Hackborna8f60182009-09-01 19:01:50 -07007980 // First remove all existing app windows.
7981 i=0;
7982 while (i < NW) {
Craig Mautner59c00972012-07-30 12:10:24 -07007983 WindowState w = windows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007984 if (w.mAppToken != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07007985 WindowState win = windows.remove(i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007986 win.mRebuilding = true;
7987 mRebuildTmp[numRemoved] = win;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007988 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007989 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007990 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07007991 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007992 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07007993 continue;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007994 } else if (lastBelow == i-1) {
Craig Mautner65d11b32012-10-01 13:59:52 -07007995 if (w.mAttrs.type == TYPE_WALLPAPER || w.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007996 lastBelow = i;
7997 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07007998 }
7999 i++;
8000 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008001
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008002 // Keep whatever windows were below the app windows still below,
8003 // by skipping them.
8004 lastBelow++;
8005 i = lastBelow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008006
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008007 // First add all of the exiting app tokens... these are no longer
8008 // in the main app list, but still have windows shown. We put them
8009 // in the back because now that the animation is over we no longer
8010 // will care about them.
8011 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07008012 for (int j=0; j<NT; j++) {
Craig Mautner59c00972012-07-30 12:10:24 -07008013 i = reAddAppWindowsLocked(displayContent, i, mExitingAppTokens.get(j));
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008014 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008015
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008016 // And add in the still active app tokens in Z order.
Craig Mautneref25d7a2012-05-15 23:01:47 -07008017 NT = mAnimatingAppTokens.size();
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008018 for (int j=0; j<NT; j++) {
Craig Mautner59c00972012-07-30 12:10:24 -07008019 i = reAddAppWindowsLocked(displayContent, i, mAnimatingAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07008020 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008021
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008022 i -= lastBelow;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008023 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008024 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008025 + " windows but added " + i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008026 for (i=0; i<numRemoved; i++) {
8027 WindowState ws = mRebuildTmp[i];
8028 if (ws.mRebuilding) {
8029 StringWriter sw = new StringWriter();
8030 PrintWriter pw = new PrintWriter(sw);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07008031 ws.dump(pw, "", true);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008032 pw.flush();
8033 Slog.w(TAG, "This window was lost: " + ws);
8034 Slog.w(TAG, sw.toString());
Craig Mautnerf20588f2012-04-11 17:06:21 -07008035 ws.mWinAnimator.destroySurfaceLocked();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008036 }
8037 }
8038 Slog.w(TAG, "Current app token list:");
Craig Mautneref25d7a2012-05-15 23:01:47 -07008039 dumpAnimatingAppTokensLocked();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008040 Slog.w(TAG, "Final window list:");
8041 dumpWindowsLocked();
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008042 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07008043 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008044
Craig Mautner59c00972012-07-30 12:10:24 -07008045 private final void assignLayersLocked(WindowList windows) {
8046 int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008047 int curBaseLayer = 0;
8048 int curLayer = 0;
8049 int i;
Romain Guy06882f82009-06-10 13:36:04 -07008050
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08008051 if (DEBUG_LAYERS) {
8052 RuntimeException here = new RuntimeException("here");
8053 here.fillInStackTrace();
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008054 Slog.v(TAG, "Assigning layers", here);
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08008055 }
8056
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008057 for (i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07008058 final WindowState w = windows.get(i);
Craig Mautneracafd192012-05-10 10:41:02 -07008059 final WindowStateAnimator winAnimator = w.mWinAnimator;
8060 boolean layerChanged = false;
8061 int oldLayer = w.mLayer;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008062 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
8063 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008064 curLayer += WINDOW_LAYER_MULTIPLIER;
8065 w.mLayer = curLayer;
8066 } else {
8067 curBaseLayer = curLayer = w.mBaseLayer;
8068 w.mLayer = curLayer;
8069 }
Craig Mautneracafd192012-05-10 10:41:02 -07008070 if (w.mLayer != oldLayer) {
8071 layerChanged = true;
8072 }
8073 oldLayer = winAnimator.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008074 if (w.mTargetAppToken != null) {
Craig Mautneracafd192012-05-10 10:41:02 -07008075 winAnimator.mAnimLayer =
Craig Mautner59431632012-04-04 11:56:44 -07008076 w.mLayer + w.mTargetAppToken.mAppAnimator.animLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008077 } else if (w.mAppToken != null) {
Craig Mautneracafd192012-05-10 10:41:02 -07008078 winAnimator.mAnimLayer =
Craig Mautner59431632012-04-04 11:56:44 -07008079 w.mLayer + w.mAppToken.mAppAnimator.animLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008080 } else {
Craig Mautneracafd192012-05-10 10:41:02 -07008081 winAnimator.mAnimLayer = w.mLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008082 }
8083 if (w.mIsImWindow) {
Craig Mautneracafd192012-05-10 10:41:02 -07008084 winAnimator.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008085 } else if (w.mIsWallpaper) {
Craig Mautneracafd192012-05-10 10:41:02 -07008086 winAnimator.mAnimLayer += mWallpaperAnimLayerAdjustment;
8087 }
8088 if (winAnimator.mAnimLayer != oldLayer) {
8089 layerChanged = true;
8090 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07008091 if (layerChanged && mAnimator.isDimmingLocked(winAnimator)) {
Craig Mautneracafd192012-05-10 10:41:02 -07008092 // Force an animation pass just to update the mDimAnimator layer.
Craig Mautner711f90a2012-07-03 18:43:52 -07008093 updateLayoutToAnimationLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008094 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008095 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
Craig Mautner8863cca2012-09-18 15:04:34 -07008096 + "mBase=" + w.mBaseLayer
8097 + " mLayer=" + w.mLayer
8098 + (w.mAppToken == null ?
8099 "" : " mAppLayer=" + w.mAppToken.mAppAnimator.animLayerAdjustment)
8100 + " =mAnimLayer=" + winAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008101 //System.out.println(
8102 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
8103 }
8104 }
8105
8106 private boolean mInLayout = false;
8107 private final void performLayoutAndPlaceSurfacesLocked() {
8108 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07008109 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008110 throw new RuntimeException("Recursive call!");
8111 }
Craig Mautneref25d7a2012-05-15 23:01:47 -07008112 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
8113 + Debug.getCallers(3));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008114 return;
8115 }
8116
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008117 if (mWaitingForConfig) {
8118 // Our configuration has changed (most likely rotation), but we
8119 // don't yet have the complete configuration to report to
8120 // applications. Don't do any window layout until we have it.
8121 return;
8122 }
8123
Jeff Browne215f262012-09-10 16:01:14 -07008124 if (!mDisplayReady) {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008125 // Not yet initialized, nothing to do.
8126 return;
8127 }
8128
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07008129 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008130 mInLayout = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008131 boolean recoveringMemory = false;
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008132
8133 try {
8134 if (mForceRemoves != null) {
8135 recoveringMemory = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008136 // Wait a little bit for things to settle down, and off we go.
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008137 for (int i=0; i<mForceRemoves.size(); i++) {
8138 WindowState ws = mForceRemoves.get(i);
8139 Slog.i(TAG, "Force removing: " + ws);
8140 removeWindowInnerLocked(ws.mSession, ws);
8141 }
8142 mForceRemoves = null;
8143 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
8144 Object tmp = new Object();
8145 synchronized (tmp) {
8146 try {
8147 tmp.wait(250);
8148 } catch (InterruptedException e) {
8149 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008150 }
8151 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008152 } catch (RuntimeException e) {
Dianne Hackborn89620282011-09-11 12:47:45 -07008153 Log.wtf(TAG, "Unhandled exception while force removing for memory", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008154 }
Craig Mautner59c00972012-07-30 12:10:24 -07008155
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008156 try {
Craig Mautner76a71652012-09-03 23:23:58 -07008157 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Craig Mautnerbb1449b2012-03-23 16:11:14 -07008158
Craig Mautner59c00972012-07-30 12:10:24 -07008159 mInLayout = false;
8160
Craig Mautner19d59bc2012-09-04 11:15:56 -07008161 if (needsLayout()) {
Craig Mautnerbb1449b2012-03-23 16:11:14 -07008162 if (++mLayoutRepeatCount < 6) {
8163 requestTraversalLocked();
8164 } else {
8165 Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
8166 mLayoutRepeatCount = 0;
8167 }
8168 } else {
8169 mLayoutRepeatCount = 0;
8170 }
Craig Mautnerbb1449b2012-03-23 16:11:14 -07008171
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008172 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008173 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
8174 mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008175 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008176 } catch (RuntimeException e) {
8177 mInLayout = false;
Dianne Hackborn89620282011-09-11 12:47:45 -07008178 Log.wtf(TAG, "Unhandled exception while laying out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008179 }
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07008180
8181 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008182 }
8183
Craig Mautner59c00972012-07-30 12:10:24 -07008184 private final void performLayoutLockedInner(final DisplayContent displayContent,
8185 boolean initial, boolean updateInputWindows) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07008186 if (!displayContent.layoutNeeded) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008187 return;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008188 }
Craig Mautner19d59bc2012-09-04 11:15:56 -07008189 displayContent.layoutNeeded = false;
Craig Mautner59c00972012-07-30 12:10:24 -07008190 WindowList windows = displayContent.getWindowList();
Craig Mautner69b08182012-09-05 13:07:13 -07008191 boolean isDefaultDisplay = displayContent.isDefaultDisplay;
Craig Mautner59c00972012-07-30 12:10:24 -07008192
8193 DisplayInfo displayInfo = displayContent.getDisplayInfo();
8194 final int dw = displayInfo.logicalWidth;
8195 final int dh = displayInfo.logicalHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008196
Dianne Hackborndf89e652011-10-06 22:35:11 -07008197 final int NFW = mFakeWindows.size();
8198 for (int i=0; i<NFW; i++) {
8199 mFakeWindows.get(i).layout(dw, dh);
8200 }
8201
Craig Mautner59c00972012-07-30 12:10:24 -07008202 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008203 int i;
8204
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008205 if (DEBUG_LAYOUT) {
8206 Slog.v(TAG, "-------------------------------------");
8207 Slog.v(TAG, "performLayout: needed="
Craig Mautner19d59bc2012-09-04 11:15:56 -07008208 + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008209 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008210
8211 WindowStateAnimator universeBackground = null;
8212
Craig Mautner69b08182012-09-05 13:07:13 -07008213 mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mRotation);
8214 if (isDefaultDisplay) {
8215 // Not needed on non-default displays.
8216 mSystemDecorLayer = mPolicy.getSystemDecorRectLw(mSystemDecorRect);
8217 mScreenRect.set(0, 0, dw, dh);
8218 }
Romain Guy06882f82009-06-10 13:36:04 -07008219
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008220 int seq = mLayoutSeq+1;
8221 if (seq < 0) seq = 0;
8222 mLayoutSeq = seq;
8223
8224 // First perform layout of any root windows (not attached
8225 // to another window).
8226 int topAttached = -1;
8227 for (i = N-1; i >= 0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07008228 final WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008229
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008230 // Don't do layout of a window if it is not visible, or
8231 // soon won't be visible, to avoid wasting time and funky
8232 // changes while a window is animating away.
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008233 final boolean gone = win.isGoneForLayoutLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008234
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008235 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008236 Slog.v(TAG, "1ST PASS " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008237 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
Craig Mautner812d2ca2012-09-27 15:35:34 -07008238 + " mLayoutAttached=" + win.mLayoutAttached
8239 + " screen changed=" + win.isConfigDiff(ActivityInfo.CONFIG_SCREEN_SIZE));
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008240 final AppWindowToken atoken = win.mAppToken;
8241 if (gone) Slog.v(TAG, " GONE: mViewVisibility="
8242 + win.mViewVisibility + " mRelayoutCalled="
8243 + win.mRelayoutCalled + " hidden="
8244 + win.mRootToken.hidden + " hiddenRequested="
8245 + (atoken != null && atoken.hiddenRequested)
8246 + " mAttachedHidden=" + win.mAttachedHidden);
8247 else Slog.v(TAG, " VIS: mViewVisibility="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008248 + win.mViewVisibility + " mRelayoutCalled="
8249 + win.mRelayoutCalled + " hidden="
8250 + win.mRootToken.hidden + " hiddenRequested="
8251 + (atoken != null && atoken.hiddenRequested)
8252 + " mAttachedHidden=" + win.mAttachedHidden);
8253 }
Craig Mautner69b08182012-09-05 13:07:13 -07008254
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008255 // If this view is GONE, then skip it -- keep the current
8256 // frame, and let the caller know so they can ignore it
8257 // if they want. (We do the normal layout for INVISIBLE
8258 // windows, since that means "perform layout as normal,
8259 // just don't display").
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008260 if (!gone || !win.mHaveFrame || win.mLayoutNeeded
Craig Mautner812d2ca2012-09-27 15:35:34 -07008261 || win.isConfigDiff(ActivityInfo.CONFIG_SCREEN_SIZE)
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008262 || win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008263 if (!win.mLayoutAttached) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008264 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08008265 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008266 win.mContentChanged = false;
8267 }
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008268 win.mLayoutNeeded = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008269 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008270 mPolicy.layoutWindowLw(win, win.mAttrs, null);
8271 win.mLayoutSeq = seq;
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008272 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008273 + win.mFrame + " mContainingFrame="
8274 + win.mContainingFrame + " mDisplayFrame="
8275 + win.mDisplayFrame);
8276 } else {
8277 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008278 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07008279 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008280 if (win.mViewVisibility == View.VISIBLE
8281 && win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND
8282 && universeBackground == null) {
8283 universeBackground = win.mWinAnimator;
8284 }
8285 }
8286
8287 if (mAnimator.mUniverseBackground != universeBackground) {
8288 mFocusMayChange = true;
8289 mAnimator.mUniverseBackground = universeBackground;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008290 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008291
8292 // Now perform layout of attached windows, which usually
8293 // depend on the position of the window they are attached to.
8294 // XXX does not deal with windows that are attached to windows
8295 // that are themselves attached.
8296 for (i = topAttached; i >= 0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07008297 final WindowState win = windows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008298
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008299 if (win.mLayoutAttached) {
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008300 if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008301 + " mHaveFrame=" + win.mHaveFrame
8302 + " mViewVisibility=" + win.mViewVisibility
8303 + " mRelayoutCalled=" + win.mRelayoutCalled);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008304 // If this view is GONE, then skip it -- keep the current
8305 // frame, and let the caller know so they can ignore it
8306 // if they want. (We do the normal layout for INVISIBLE
8307 // windows, since that means "perform layout as normal,
8308 // just don't display").
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008309 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008310 || !win.mHaveFrame || win.mLayoutNeeded) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008311 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08008312 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008313 win.mContentChanged = false;
8314 }
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008315 win.mLayoutNeeded = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008316 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008317 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
8318 win.mLayoutSeq = seq;
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008319 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008320 + win.mFrame + " mContainingFrame="
8321 + win.mContainingFrame + " mDisplayFrame="
8322 + win.mDisplayFrame);
8323 }
8324 }
8325 }
Jeff Brown349703e2010-06-22 01:27:15 -07008326
8327 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown3a22cd92011-01-21 13:59:04 -08008328 mInputMonitor.setUpdateInputWindowsNeededLw();
8329 if (updateInputWindows) {
Jeff Brown2e44b072011-01-24 15:21:56 -08008330 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08008331 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008332
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008333 mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008334 }
Romain Guy06882f82009-06-10 13:36:04 -07008335
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008336 void makeWindowFreezingScreenIfNeededLocked(WindowState w) {
8337 // If the screen is currently frozen or off, then keep
8338 // it frozen/off until this window draws at its new
8339 // orientation.
Craig Mautner2fb98b12012-03-20 17:24:00 -07008340 if (!okToDisplay()) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008341 if (DEBUG_ORIENTATION) Slog.v(TAG,
8342 "Changing surface while display frozen: " + w);
8343 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07008344 mInnerFields.mOrientationChangeComplete = false;
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008345 if (!mWindowsFreezingScreen) {
8346 mWindowsFreezingScreen = true;
8347 // XXX should probably keep timeout from
8348 // when we first froze the display.
8349 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
8350 mH.sendMessageDelayed(mH.obtainMessage(
8351 H.WINDOW_FREEZE_TIMEOUT), 2000);
8352 }
8353 }
8354 }
8355
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008356 /**
8357 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
Craig Mautner19d59bc2012-09-04 11:15:56 -07008358 * @param windows List of windows on default display.
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008359 * @return bitmap indicating if another pass through layout must be made.
8360 */
Craig Mautner59c00972012-07-30 12:10:24 -07008361 public int handleAppTransitionReadyLocked(WindowList windows) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008362 int changes = 0;
8363 int i;
8364 int NN = mOpeningApps.size();
8365 boolean goodToGo = true;
8366 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8367 "Checking " + NN + " opening apps (frozen="
8368 + mDisplayFrozen + " timeout="
8369 + mAppTransitionTimeout + ")...");
8370 if (!mDisplayFrozen && !mAppTransitionTimeout) {
8371 // If the display isn't frozen, wait to do anything until
8372 // all of the apps are ready. Otherwise just go because
8373 // we'll unfreeze the display when everyone is ready.
8374 for (i=0; i<NN && goodToGo; i++) {
8375 AppWindowToken wtoken = mOpeningApps.get(i);
8376 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Craig Mautner1d961d42012-05-27 12:02:11 -07008377 "Check opening app=" + wtoken + ": allDrawn="
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008378 + wtoken.allDrawn + " startingDisplayed="
Craig Mautner7358fbf2012-04-12 21:06:33 -07008379 + wtoken.startingDisplayed + " startingMoved="
8380 + wtoken.startingMoved);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008381 if (!wtoken.allDrawn && !wtoken.startingDisplayed
8382 && !wtoken.startingMoved) {
8383 goodToGo = false;
8384 }
8385 }
8386 }
8387 if (goodToGo) {
8388 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
8389 int transit = mNextAppTransition;
8390 if (mSkipAppTransitionAnimation) {
8391 transit = WindowManagerPolicy.TRANSIT_UNSET;
8392 }
8393 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
8394 mAppTransitionReady = false;
8395 mAppTransitionRunning = true;
8396 mAppTransitionTimeout = false;
8397 mStartingIconInTransition = false;
8398 mSkipAppTransitionAnimation = false;
8399
8400 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
8401
Craig Mautneref25d7a2012-05-15 23:01:47 -07008402 rebuildAppWindowListLocked();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008403
Craig Mautner0afddcb2012-05-08 15:38:00 -07008404 // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
Craig Mautner83339b42012-05-01 22:13:23 -07008405 WindowState oldWallpaper =
8406 mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
Craig Mautner0afddcb2012-05-08 15:38:00 -07008407 && !mWallpaperTarget.mWinAnimator.isDummyAnimation()
Craig Mautner83339b42012-05-01 22:13:23 -07008408 ? null : mWallpaperTarget;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008409
8410 adjustWallpaperWindowsLocked();
8411 mInnerFields.mWallpaperMayChange = false;
8412
8413 // The top-most window will supply the layout params,
8414 // and we will determine it below.
8415 LayoutParams animLp = null;
8416 int bestAnimLayer = -1;
8417 boolean fullscreenAnim = false;
8418
8419 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8420 "New wallpaper target=" + mWallpaperTarget
Daniel Sandlerab886f52012-06-04 14:36:25 -04008421 + ", oldWallpaper=" + oldWallpaper
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008422 + ", lower target=" + mLowerWallpaperTarget
8423 + ", upper target=" + mUpperWallpaperTarget);
8424 int foundWallpapers = 0;
8425 // Do a first pass through the tokens for two
8426 // things:
8427 // (1) Determine if both the closing and opening
8428 // app token sets are wallpaper targets, in which
8429 // case special animations are needed
8430 // (since the wallpaper needs to stay static
8431 // behind them).
8432 // (2) Find the layout params of the top-most
8433 // application window in the tokens, which is
8434 // what will control the animation theme.
8435 final int NC = mClosingApps.size();
8436 NN = NC + mOpeningApps.size();
8437 for (i=0; i<NN; i++) {
8438 AppWindowToken wtoken;
8439 int mode;
8440 if (i < NC) {
8441 wtoken = mClosingApps.get(i);
8442 mode = 1;
8443 } else {
8444 wtoken = mOpeningApps.get(i-NC);
8445 mode = 2;
8446 }
8447 if (mLowerWallpaperTarget != null) {
8448 if (mLowerWallpaperTarget.mAppToken == wtoken
8449 || mUpperWallpaperTarget.mAppToken == wtoken) {
8450 foundWallpapers |= mode;
8451 }
8452 }
8453 if (wtoken.appFullscreen) {
8454 WindowState ws = wtoken.findMainWindow();
8455 if (ws != null) {
8456 animLp = ws.mAttrs;
8457 bestAnimLayer = ws.mLayer;
8458 fullscreenAnim = true;
8459 }
8460 } else if (!fullscreenAnim) {
8461 WindowState ws = wtoken.findMainWindow();
8462 if (ws != null) {
8463 if (ws.mLayer > bestAnimLayer) {
8464 animLp = ws.mAttrs;
8465 bestAnimLayer = ws.mLayer;
8466 }
8467 }
8468 }
8469 }
8470
8471 if (foundWallpapers == 3) {
8472 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8473 "Wallpaper animation!");
8474 switch (transit) {
8475 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
8476 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
8477 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
8478 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
8479 break;
8480 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
8481 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
8482 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
8483 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
8484 break;
8485 }
8486 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8487 "New transit: " + transit);
Daniel Sandlerab886f52012-06-04 14:36:25 -04008488 } else if ((oldWallpaper != null) && !mOpeningApps.contains(oldWallpaper.mAppToken)) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008489 // We are transitioning from an activity with
8490 // a wallpaper to one without.
8491 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
8492 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8493 "New transit away from wallpaper: " + transit);
Craig Mautner8863cca2012-09-18 15:04:34 -07008494 } else if (mWallpaperTarget != null && mWallpaperTarget.isVisibleLw()) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008495 // We are transitioning from an activity without
8496 // a wallpaper to now showing the wallpaper
8497 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
8498 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8499 "New transit into wallpaper: " + transit);
8500 }
8501
8502 // If all closing windows are obscured, then there is
8503 // no need to do an animation. This is the case, for
8504 // example, when this transition is being done behind
8505 // the lock screen.
8506 if (!mPolicy.allowAppAnimationsLw()) {
8507 animLp = null;
8508 }
8509
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008510 AppWindowToken topOpeningApp = null;
8511 int topOpeningLayer = 0;
8512
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008513 NN = mOpeningApps.size();
8514 for (i=0; i<NN; i++) {
8515 AppWindowToken wtoken = mOpeningApps.get(i);
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008516 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Craig Mautnerbec53f72012-04-05 11:49:05 -07008517 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008518 appAnimator.clearThumbnail();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008519 wtoken.reportedVisible = false;
8520 wtoken.inPendingTransaction = false;
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008521 appAnimator.animation = null;
Craig Mautnerbec53f72012-04-05 11:49:05 -07008522 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008523 wtoken.updateReportedVisibilityLocked();
8524 wtoken.waitingToShow = false;
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008525
8526 appAnimator.mAllAppWinAnimators.clear();
8527 final int N = wtoken.allAppWindows.size();
8528 for (int j = 0; j < N; j++) {
8529 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
8530 }
8531 mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
8532
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008533 if (animLp != null) {
8534 int layer = -1;
8535 for (int j=0; j<wtoken.windows.size(); j++) {
8536 WindowState win = wtoken.windows.get(j);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07008537 if (win.mWinAnimator.mAnimLayer > layer) {
8538 layer = win.mWinAnimator.mAnimLayer;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008539 }
8540 }
8541 if (topOpeningApp == null || layer > topOpeningLayer) {
8542 topOpeningApp = wtoken;
8543 topOpeningLayer = layer;
8544 }
8545 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008546 }
8547 NN = mClosingApps.size();
8548 for (i=0; i<NN; i++) {
8549 AppWindowToken wtoken = mClosingApps.get(i);
8550 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Craig Mautner8863cca2012-09-18 15:04:34 -07008551 "Now closing app " + wtoken);
Craig Mautner59431632012-04-04 11:56:44 -07008552 wtoken.mAppAnimator.clearThumbnail();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008553 wtoken.inPendingTransaction = false;
Craig Mautner59431632012-04-04 11:56:44 -07008554 wtoken.mAppAnimator.animation = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008555 setTokenVisibilityLocked(wtoken, animLp, false,
8556 transit, false);
8557 wtoken.updateReportedVisibilityLocked();
8558 wtoken.waitingToHide = false;
8559 // Force the allDrawn flag, because we want to start
8560 // this guy's animations regardless of whether it's
8561 // gotten drawn.
8562 wtoken.allDrawn = true;
8563 }
8564
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008565 if (mNextAppTransitionThumbnail != null && topOpeningApp != null
Craig Mautner59431632012-04-04 11:56:44 -07008566 && topOpeningApp.mAppAnimator.animation != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008567 // This thumbnail animation is very special, we need to have
8568 // an extra surface with the thumbnail included with the animation.
8569 Rect dirty = new Rect(0, 0, mNextAppTransitionThumbnail.getWidth(),
8570 mNextAppTransitionThumbnail.getHeight());
8571 try {
Jeff Browne215f262012-09-10 16:01:14 -07008572 // TODO(multi-display): support other displays
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008573 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07008574 final Display display = displayContent.getDisplay();
Jeff Brown64a55af2012-08-26 02:47:39 -07008575 Surface surface = new Surface(mFxSession,
8576 "thumbnail anim",
Craig Mautner6881a102012-07-27 13:04:51 -07008577 dirty.width(), dirty.height(),
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008578 PixelFormat.TRANSLUCENT, Surface.HIDDEN);
Jeff Browne215f262012-09-10 16:01:14 -07008579 surface.setLayerStack(display.getLayerStack());
Craig Mautner59431632012-04-04 11:56:44 -07008580 topOpeningApp.mAppAnimator.thumbnail = surface;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008581 if (SHOW_TRANSACTIONS) Slog.i(TAG, " THUMBNAIL "
8582 + surface + ": CREATE");
8583 Surface drawSurface = new Surface();
8584 drawSurface.copyFrom(surface);
8585 Canvas c = drawSurface.lockCanvas(dirty);
8586 c.drawBitmap(mNextAppTransitionThumbnail, 0, 0, null);
8587 drawSurface.unlockCanvasAndPost(c);
8588 drawSurface.release();
Craig Mautner59431632012-04-04 11:56:44 -07008589 topOpeningApp.mAppAnimator.thumbnailLayer = topOpeningLayer;
Michael Jurka21385cd2012-05-03 10:57:31 -07008590 Animation anim = createThumbnailAnimationLocked(
Michael Jurka832cb222012-04-13 09:32:47 -07008591 transit, true, true, mNextAppTransitionScaleUp);
Craig Mautner59431632012-04-04 11:56:44 -07008592 topOpeningApp.mAppAnimator.thumbnailAnimation = anim;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008593 anim.restrictDuration(MAX_ANIMATION_DURATION);
8594 anim.scaleCurrentDuration(mTransitionAnimationScale);
Craig Mautner59431632012-04-04 11:56:44 -07008595 topOpeningApp.mAppAnimator.thumbnailX = mNextAppTransitionStartX;
8596 topOpeningApp.mAppAnimator.thumbnailY = mNextAppTransitionStartY;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008597 } catch (Surface.OutOfResourcesException e) {
8598 Slog.e(TAG, "Can't allocate thumbnail surface w=" + dirty.width()
8599 + " h=" + dirty.height(), e);
Craig Mautner59431632012-04-04 11:56:44 -07008600 topOpeningApp.mAppAnimator.clearThumbnail();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008601 }
8602 }
8603
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07008604 mNextAppTransitionType = ActivityOptions.ANIM_NONE;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008605 mNextAppTransitionPackage = null;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008606 mNextAppTransitionThumbnail = null;
Dianne Hackborn84375872012-06-01 19:03:50 -07008607 scheduleAnimationCallback(mNextAppTransitionCallback);
8608 mNextAppTransitionCallback = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008609
8610 mOpeningApps.clear();
8611 mClosingApps.clear();
8612
8613 // This has changed the visibility of windows, so perform
8614 // a new layout to get them all up-to-date.
Craig Mautner39834192012-09-02 07:47:24 -07008615 changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008616 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008617 getDefaultDisplayContentLocked().layoutNeeded = true;
Craig Mautner59c00972012-07-30 12:10:24 -07008618
8619 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008620 if (windows == getDefaultWindowListLocked()
8621 && !moveInputMethodWindowsIfNeededLocked(true)) {
Craig Mautner59c00972012-07-30 12:10:24 -07008622 assignLayersLocked(windows);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008623 }
Craig Mautner59c00972012-07-30 12:10:24 -07008624 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, false /*updateInputWindows*/);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008625 mFocusMayChange = false;
8626 }
8627
8628 return changes;
8629 }
8630
8631 /**
8632 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008633 * @return bitmap indicating if another pass through layout must be made.
8634 */
Craig Mautner2f995a72012-02-21 09:53:21 -08008635 private int handleAnimatingStoppedAndTransitionLocked() {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008636 int changes = 0;
8637
8638 mAppTransitionRunning = false;
Craig Mautneref25d7a2012-05-15 23:01:47 -07008639 // Restore window app tokens to the ActivityManager views
Craig Mautner3f99fde2012-06-19 14:10:01 -07008640 for (int i = mAnimatingAppTokens.size() - 1; i >= 0; i--) {
8641 mAnimatingAppTokens.get(i).sendingToBottom = false;
8642 }
Craig Mautneref25d7a2012-05-15 23:01:47 -07008643 mAnimatingAppTokens.clear();
8644 mAnimatingAppTokens.addAll(mAppTokens);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008645 rebuildAppWindowListLocked();
Craig Mautneref25d7a2012-05-15 23:01:47 -07008646
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008647 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
8648 mInnerFields.mAdjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Craig Mautneref25d7a2012-05-15 23:01:47 -07008649 moveInputMethodWindowsIfNeededLocked(true);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008650 mInnerFields.mWallpaperMayChange = true;
8651 // Since the window list has been rebuilt, focus might
8652 // have to be recomputed since the actual order of windows
8653 // might have changed again.
8654 mFocusMayChange = true;
8655
8656 return changes;
8657 }
8658
8659 /**
8660 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
8661 *
8662 * @return bitmap indicating if another pass through layout must be made.
8663 */
8664 private int animateAwayWallpaperLocked() {
8665 int changes = 0;
8666 WindowState oldWallpaper = mWallpaperTarget;
8667 if (mLowerWallpaperTarget != null
8668 && mLowerWallpaperTarget.mAppToken != null) {
8669 if (DEBUG_WALLPAPER) Slog.v(TAG,
8670 "wallpaperForceHiding changed with lower="
8671 + mLowerWallpaperTarget);
8672 if (DEBUG_WALLPAPER) Slog.v(TAG,
8673 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
8674 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
8675 if (mLowerWallpaperTarget.mAppToken.hidden) {
8676 // The lower target has become hidden before we
8677 // actually started the animation... let's completely
8678 // re-evaluate everything.
8679 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
8680 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
8681 }
8682 }
8683 mInnerFields.mAdjResult |= adjustWallpaperWindowsLocked();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008684 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
8685 + " NEW: " + mWallpaperTarget
8686 + " LOWER: " + mLowerWallpaperTarget);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008687 return changes;
8688 }
8689
Craig Mautnere32c3072012-03-12 15:25:35 -07008690 private void updateResizingWindows(final WindowState w) {
Craig Mautnera608b882012-03-30 13:03:49 -07008691 final WindowStateAnimator winAnimator = w.mWinAnimator;
Craig Mautner1efacf72012-04-27 12:58:21 -07008692 if (w.mHasSurface && !w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
Craig Mautnere32c3072012-03-12 15:25:35 -07008693 w.mContentInsetsChanged |=
Dianne Hackborn5c58de32012-04-28 19:52:37 -07008694 !w.mLastContentInsets.equals(w.mContentInsets);
Craig Mautnere32c3072012-03-12 15:25:35 -07008695 w.mVisibleInsetsChanged |=
Dianne Hackborn5c58de32012-04-28 19:52:37 -07008696 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Craig Mautner812d2ca2012-09-27 15:35:34 -07008697 boolean configChanged = w.isConfigChanged();
Craig Mautnere32c3072012-03-12 15:25:35 -07008698 if (DEBUG_CONFIGURATION && configChanged) {
8699 Slog.v(TAG, "Win " + w + " config changed: "
8700 + mCurConfiguration);
8701 }
8702 if (localLOGV) Slog.v(TAG, "Resizing " + w
8703 + ": configChanged=" + configChanged
8704 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
8705 w.mLastFrame.set(w.mFrame);
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07008706 if (w.mContentInsetsChanged
Craig Mautnere32c3072012-03-12 15:25:35 -07008707 || w.mVisibleInsetsChanged
Craig Mautnera608b882012-03-30 13:03:49 -07008708 || winAnimator.mSurfaceResized
Craig Mautnere32c3072012-03-12 15:25:35 -07008709 || configChanged) {
8710 if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
8711 Slog.v(TAG, "Resize reasons: "
8712 + " contentInsetsChanged=" + w.mContentInsetsChanged
8713 + " visibleInsetsChanged=" + w.mVisibleInsetsChanged
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008714 + " surfaceResized=" + winAnimator.mSurfaceResized
Craig Mautnere32c3072012-03-12 15:25:35 -07008715 + " configChanged=" + configChanged);
8716 }
8717
8718 w.mLastContentInsets.set(w.mContentInsets);
8719 w.mLastVisibleInsets.set(w.mVisibleInsets);
8720 makeWindowFreezingScreenIfNeededLocked(w);
8721 // If the orientation is changing, then we need to
8722 // hold off on unfreezing the display until this
8723 // window has been redrawn; to do that, we need
8724 // to go through the process of getting informed
8725 // by the application when it has finished drawing.
8726 if (w.mOrientationChanging) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07008727 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautner83339b42012-05-01 22:13:23 -07008728 "Orientation start waiting for draw mDrawState=DRAW_PENDING in "
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008729 + w + ", surface " + winAnimator.mSurface);
Craig Mautner749a7bb2012-04-02 13:49:53 -07008730 winAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
Craig Mautnere32c3072012-03-12 15:25:35 -07008731 if (w.mAppToken != null) {
8732 w.mAppToken.allDrawn = false;
8733 }
8734 }
8735 if (!mResizingWindows.contains(w)) {
8736 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008737 "Resizing window " + w + " to " + winAnimator.mSurfaceW
8738 + "x" + winAnimator.mSurfaceH);
Craig Mautnere32c3072012-03-12 15:25:35 -07008739 mResizingWindows.add(w);
8740 }
8741 } else if (w.mOrientationChanging) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07008742 if (w.isDrawnLw()) {
Craig Mautnere32c3072012-03-12 15:25:35 -07008743 if (DEBUG_ORIENTATION) Slog.v(TAG,
8744 "Orientation not waiting for draw in "
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008745 + w + ", surface " + winAnimator.mSurface);
Craig Mautnere32c3072012-03-12 15:25:35 -07008746 w.mOrientationChanging = false;
8747 }
8748 }
8749 }
8750 }
8751
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008752 /**
8753 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
8754 *
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008755 * @param w WindowState this method is applied to.
8756 * @param currentTime The time which animations use for calculating transitions.
8757 * @param innerDw Width of app window.
8758 * @param innerDh Height of app window.
8759 */
8760 private void handleNotObscuredLocked(final WindowState w, final long currentTime,
8761 final int innerDw, final int innerDh) {
8762 final WindowManager.LayoutParams attrs = w.mAttrs;
8763 final int attrFlags = attrs.flags;
8764 final boolean canBeSeen = w.isDisplayedLw();
8765
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07008766 if (w.mHasSurface) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008767 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
8768 mInnerFields.mHoldScreen = w.mSession;
8769 }
8770 if (!mInnerFields.mSyswin && w.mAttrs.screenBrightness >= 0
8771 && mInnerFields.mScreenBrightness < 0) {
8772 mInnerFields.mScreenBrightness = w.mAttrs.screenBrightness;
8773 }
8774 if (!mInnerFields.mSyswin && w.mAttrs.buttonBrightness >= 0
8775 && mInnerFields.mButtonBrightness < 0) {
8776 mInnerFields.mButtonBrightness = w.mAttrs.buttonBrightness;
8777 }
Craig Mautner65d11b32012-10-01 13:59:52 -07008778 final int type = attrs.type;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008779 if (canBeSeen
Craig Mautner65d11b32012-10-01 13:59:52 -07008780 && (type == TYPE_SYSTEM_DIALOG
8781 || type == TYPE_KEYGUARD
8782 || type == TYPE_SYSTEM_ERROR)) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008783 mInnerFields.mSyswin = true;
8784 }
Craig Mautner65d11b32012-10-01 13:59:52 -07008785
8786 if (canBeSeen) {
8787 if (type == TYPE_DREAM || type == TYPE_KEYGUARD) {
8788 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_MIRROR;
8789 } else if (mInnerFields.mDisplayHasContent
8790 == LayoutFields.DISPLAY_CONTENT_UNKNOWN) {
8791 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNIQUE;
8792 }
8793 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008794 }
8795
8796 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
8797 if (opaqueDrawn && w.isFullscreen(innerDw, innerDh)) {
8798 // This window completely covers everything behind it,
Craig Mautner2fb98b12012-03-20 17:24:00 -07008799 // so we want to leave all of them as undimmed (for
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008800 // performance reasons).
8801 mInnerFields.mObscured = true;
Craig Mautner35af2ff2012-04-24 14:30:15 -07008802 } else if (canBeSeen && (attrFlags & FLAG_DIM_BEHIND) != 0
Craig Mautner236a35b2012-06-08 09:54:59 -07008803 && !(w.mAppToken != null && w.mAppToken.hiddenRequested)
8804 && !w.mExiting) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07008805 if (localLOGV) Slog.v(TAG, "Win " + w + " obscured=" + mInnerFields.mObscured);
8806 if (!mInnerFields.mDimming) {
8807 //Slog.i(TAG, "DIM BEHIND: " + w);
8808 mInnerFields.mDimming = true;
Craig Mautneracafd192012-05-10 10:41:02 -07008809 final WindowStateAnimator winAnimator = w.mWinAnimator;
Craig Mautnera91f9e22012-09-14 16:22:08 -07008810 if (!mAnimator.isDimmingLocked(winAnimator)) {
Craig Mautnerf8d4fbb2012-04-11 09:25:53 -07008811 final int width, height;
Craig Mautner65d11b32012-10-01 13:59:52 -07008812 if (attrs.type == TYPE_BOOT_PROGRESS) {
Craig Mautner59c00972012-07-30 12:10:24 -07008813 final DisplayInfo displayInfo = w.mDisplayContent.getDisplayInfo();
8814 width = displayInfo.logicalWidth;
8815 height = displayInfo.logicalHeight;
Craig Mautnerf8d4fbb2012-04-11 09:25:53 -07008816 } else {
8817 width = innerDw;
8818 height = innerDh;
8819 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07008820 startDimmingLocked(
8821 winAnimator, w.mExiting ? 0 : w.mAttrs.dimAmount, width, height);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008822 }
8823 }
8824 }
8825 }
8826
Craig Mautner6fbda632012-07-03 09:26:39 -07008827 private void updateAllDrawnLocked() {
8828 // See if any windows have been drawn, so they (and others
8829 // associated with them) can now be shown.
8830 final ArrayList<AppWindowToken> appTokens = mAnimatingAppTokens;
8831 final int NT = appTokens.size();
8832 for (int i=0; i<NT; i++) {
8833 AppWindowToken wtoken = appTokens.get(i);
8834 if (!wtoken.allDrawn) {
8835 int numInteresting = wtoken.numInterestingWindows;
8836 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
8837 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
8838 "allDrawn: " + wtoken
8839 + " interesting=" + numInteresting
8840 + " drawn=" + wtoken.numDrawnWindows);
8841 wtoken.allDrawn = true;
8842 }
8843 }
8844 }
8845 }
8846
Brad Fitzpatrick68044332010-11-22 18:19:48 -08008847 // "Something has changed! Let's make it correct now."
Craig Mautner76a71652012-09-03 23:23:58 -07008848 private final void performLayoutAndPlaceSurfacesLockedInner(boolean recoveringMemory) {
Craig Mautner7d8df392012-04-06 15:26:23 -07008849 if (DEBUG_WINDOW_TRACE) {
Craig Mautner3255a282012-04-16 15:42:47 -07008850 Slog.v(TAG, "performLayoutAndPlaceSurfacesLockedInner: entry. Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -07008851 + Debug.getCallers(3));
Craig Mautner7d8df392012-04-06 15:26:23 -07008852 }
Joe Onorato34bcebc2010-07-07 18:05:01 -04008853
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008854 final long currentTime = SystemClock.uptimeMillis();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008855
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008856 int i;
8857
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008858 if (mFocusMayChange) {
8859 mFocusMayChange = false;
Jeff Brown3a22cd92011-01-21 13:59:04 -08008860 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
8861 false /*updateInputWindows*/);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008862 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008863
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008864 // Initialize state of exiting tokens.
8865 for (i=mExitingTokens.size()-1; i>=0; i--) {
8866 mExitingTokens.get(i).hasVisible = false;
8867 }
8868
8869 // Initialize state of exiting applications.
8870 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
8871 mExitingAppTokens.get(i).hasVisible = false;
8872 }
8873
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008874 mInnerFields.mHoldScreen = null;
8875 mInnerFields.mScreenBrightness = -1;
8876 mInnerFields.mButtonBrightness = -1;
Craig Mautner65d11b32012-10-01 13:59:52 -07008877 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNKNOWN;
Craig Mautner6fbda632012-07-03 09:26:39 -07008878 mTransactionSequence++;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07008879
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008880 final DisplayContent defaultDisplay = getDefaultDisplayContentLocked();
Craig Mautner76a71652012-09-03 23:23:58 -07008881 final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
8882 final int defaultDw = defaultInfo.logicalWidth;
8883 final int defaultDh = defaultInfo.logicalHeight;
Craig Mautner76a71652012-09-03 23:23:58 -07008884
Dianne Hackborn36991742011-10-11 21:35:26 -07008885 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
8886 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008887 Surface.openTransaction();
8888 try {
Craig Mautner76a71652012-09-03 23:23:58 -07008889
Jeff Brown4ed8fe72012-08-30 18:18:29 -07008890 if (mWatermark != null) {
Craig Mautner76a71652012-09-03 23:23:58 -07008891 mWatermark.positionSurface(defaultDw, defaultDh);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07008892 }
8893 if (mStrictModeFlash != null) {
Craig Mautner76a71652012-09-03 23:23:58 -07008894 mStrictModeFlash.positionSurface(defaultDw, defaultDh);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07008895 }
8896
Craig Mautner7358fbf2012-04-12 21:06:33 -07008897 boolean focusDisplayed = false;
Craig Mautner6fbda632012-07-03 09:26:39 -07008898 boolean updateAllDrawn = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008899
Craig Mautner76a71652012-09-03 23:23:58 -07008900 DisplayContentsIterator iterator = new DisplayContentsIterator();
8901 while (iterator.hasNext()) {
8902 final DisplayContent displayContent = iterator.next();
8903 WindowList windows = displayContent.getWindowList();
8904 DisplayInfo displayInfo = displayContent.getDisplayInfo();
Craig Mautner19d59bc2012-09-04 11:15:56 -07008905 final int displayId = displayContent.getDisplayId();
Craig Mautner76a71652012-09-03 23:23:58 -07008906 final int dw = displayInfo.logicalWidth;
8907 final int dh = displayInfo.logicalHeight;
8908 final int innerDw = displayInfo.appWidth;
8909 final int innerDh = displayInfo.appHeight;
Craig Mautner19d59bc2012-09-04 11:15:56 -07008910 final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008911
Craig Mautner65d11b32012-10-01 13:59:52 -07008912 // Reset for each display unless we are forcing mirroring.
8913 if (mInnerFields.mDisplayHasContent != LayoutFields.DISPLAY_CONTENT_MIRROR) {
8914 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNKNOWN;
8915 }
8916
Craig Mautner76a71652012-09-03 23:23:58 -07008917 int repeats = 0;
8918 do {
8919 repeats++;
8920 if (repeats > 6) {
8921 Slog.w(TAG, "Animation repeat aborted after too many iterations");
Craig Mautner76a71652012-09-03 23:23:58 -07008922 displayContent.layoutNeeded = false;
8923 break;
Craig Mautner5702d4d2012-06-30 14:10:16 -07008924 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008925
Craig Mautner76a71652012-09-03 23:23:58 -07008926 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("On entry to LockedInner",
8927 displayContent.pendingLayoutChanges);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008928
Craig Mautner76a71652012-09-03 23:23:58 -07008929 if (isDefaultDisplay && ((displayContent.pendingLayoutChanges
8930 & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0)
8931 && ((adjustWallpaperWindowsLocked()
8932 & ADJUST_WALLPAPER_LAYERS_CHANGED) != 0)) {
8933 assignLayersLocked(windows);
Craig Mautner76a71652012-09-03 23:23:58 -07008934 displayContent.layoutNeeded = true;
8935 }
8936
8937 if (isDefaultDisplay && (displayContent.pendingLayoutChanges
8938 & WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
8939 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
8940 if (updateOrientationFromAppTokensLocked(true)) {
Craig Mautner76a71652012-09-03 23:23:58 -07008941 displayContent.layoutNeeded = true;
8942 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008943 }
8944 }
8945
Craig Mautner76a71652012-09-03 23:23:58 -07008946 if ((displayContent.pendingLayoutChanges
8947 & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
Craig Mautner76a71652012-09-03 23:23:58 -07008948 displayContent.layoutNeeded = true;
Craig Mautner6fbda632012-07-03 09:26:39 -07008949 }
Craig Mautner76a71652012-09-03 23:23:58 -07008950
8951 // FIRST LOOP: Perform a layout, if needed.
8952 if (repeats < 4) {
8953 performLayoutLockedInner(displayContent, repeats == 1,
8954 false /*updateInputWindows*/);
8955 } else {
8956 Slog.w(TAG, "Layout repeat skipped after too many iterations");
8957 }
8958
8959 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
8960 // it is animating.
8961 displayContent.pendingLayoutChanges = 0;
8962
8963 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("loop number "
8964 + mLayoutRepeatCount, displayContent.pendingLayoutChanges);
8965
Craig Mautner69b08182012-09-05 13:07:13 -07008966 if (isDefaultDisplay) {
8967 mPolicy.beginPostLayoutPolicyLw(dw, dh);
8968 for (i = windows.size() - 1; i >= 0; i--) {
8969 WindowState w = windows.get(i);
8970 if (w.mHasSurface) {
8971 mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs);
8972 }
Craig Mautner6fbda632012-07-03 09:26:39 -07008973 }
Craig Mautner69b08182012-09-05 13:07:13 -07008974 displayContent.pendingLayoutChanges |= mPolicy.finishPostLayoutPolicyLw();
8975 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
8976 "after finishPostLayoutPolicyLw", displayContent.pendingLayoutChanges);
Craig Mautner76a71652012-09-03 23:23:58 -07008977 }
Craig Mautner76a71652012-09-03 23:23:58 -07008978 } while (displayContent.pendingLayoutChanges != 0);
8979
8980 mInnerFields.mObscured = false;
8981 mInnerFields.mDimming = false;
8982 mInnerFields.mSyswin = false;
8983
8984 // Only used if default window
8985 final boolean someoneLosingFocus = !mLosingFocus.isEmpty();
8986
8987 final int N = windows.size();
8988 for (i=N-1; i>=0; i--) {
8989 WindowState w = windows.get(i);
8990
8991 final boolean obscuredChanged = w.mObscured != mInnerFields.mObscured;
8992
8993 // Update effect.
8994 w.mObscured = mInnerFields.mObscured;
8995 if (!mInnerFields.mObscured) {
8996 handleNotObscuredLocked(w, currentTime, innerDw, innerDh);
8997 }
8998
8999 if (isDefaultDisplay && obscuredChanged && (mWallpaperTarget == w)
9000 && w.isVisibleLw()) {
9001 // This is the wallpaper target and its obscured state
9002 // changed... make sure the current wallaper's visibility
9003 // has been updated accordingly.
9004 updateWallpaperVisibilityLocked();
9005 }
9006
9007 final WindowStateAnimator winAnimator = w.mWinAnimator;
9008
9009 // If the window has moved due to its containing
9010 // content frame changing, then we'd like to animate
9011 // it.
9012 if (w.mHasSurface && w.shouldAnimateMove()) {
9013 // Frame has moved, containing content frame
9014 // has also moved, and we're not currently animating...
9015 // let's do something.
9016 Animation a = AnimationUtils.loadAnimation(mContext,
9017 com.android.internal.R.anim.window_move_from_decor);
9018 winAnimator.setAnimation(a);
9019 winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
9020 winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
9021 try {
9022 w.mClient.moved(w.mFrame.left, w.mFrame.top);
9023 } catch (RemoteException e) {
9024 }
9025 }
9026
9027 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
9028 w.mContentChanged = false;
9029
9030 // Moved from updateWindowsAndWallpaperLocked().
9031 if (w.mHasSurface) {
9032 // Take care of the window being ready to display.
Craig Mautner69b08182012-09-05 13:07:13 -07009033 final boolean committed =
9034 winAnimator.commitFinishDrawingLocked(currentTime);
9035 if (isDefaultDisplay && committed) {
Craig Mautner65d11b32012-10-01 13:59:52 -07009036 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
9037 if (DEBUG_WALLPAPER) Slog.v(TAG,
Craig Mautner76a71652012-09-03 23:23:58 -07009038 "First draw done in potential wallpaper target " + w);
9039 mInnerFields.mWallpaperMayChange = true;
9040 displayContent.pendingLayoutChanges |=
9041 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
9042 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
9043 debugLayoutRepeats(
9044 "wallpaper and commitFinishDrawingLocked true",
9045 displayContent.pendingLayoutChanges);
Craig Mautner6fbda632012-07-03 09:26:39 -07009046 }
9047 }
Craig Mautner76a71652012-09-03 23:23:58 -07009048 }
9049
Craig Mautnera91f9e22012-09-14 16:22:08 -07009050 winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
Craig Mautner76a71652012-09-03 23:23:58 -07009051
9052 final AppWindowToken atoken = w.mAppToken;
Craig Mautner65d11b32012-10-01 13:59:52 -07009053 if (DEBUG_STARTING_WINDOW && atoken != null
9054 && w == atoken.startingWindow) {
Craig Mautner76a71652012-09-03 23:23:58 -07009055 Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen="
9056 + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
9057 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
9058 }
9059 if (atoken != null
9060 && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
9061 if (atoken.lastTransactionSequence != mTransactionSequence) {
9062 atoken.lastTransactionSequence = mTransactionSequence;
9063 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
9064 atoken.startingDisplayed = false;
9065 }
Craig Mautner65d11b32012-10-01 13:59:52 -07009066 if ((w.isOnScreen() || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
Craig Mautner76a71652012-09-03 23:23:58 -07009067 && !w.mExiting && !w.mDestroying) {
9068 if (WindowManagerService.DEBUG_VISIBILITY ||
9069 WindowManagerService.DEBUG_ORIENTATION) {
9070 Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
9071 + ", isAnimating=" + winAnimator.isAnimating());
9072 if (!w.isDrawnLw()) {
9073 Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurface
9074 + " pv=" + w.mPolicyVisibility
9075 + " mDrawState=" + winAnimator.mDrawState
9076 + " ah=" + w.mAttachedHidden
9077 + " th=" + atoken.hiddenRequested
9078 + " a=" + winAnimator.mAnimating);
Craig Mautner6fbda632012-07-03 09:26:39 -07009079 }
9080 }
Craig Mautner76a71652012-09-03 23:23:58 -07009081 if (w != atoken.startingWindow) {
9082 if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
9083 atoken.numInterestingWindows++;
9084 if (w.isDrawnLw()) {
9085 atoken.numDrawnWindows++;
9086 if (WindowManagerService.DEBUG_VISIBILITY ||
9087 WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
9088 "tokenMayBeDrawn: " + atoken
9089 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen
9090 + " mAppFreezing=" + w.mAppFreezing);
9091 updateAllDrawn = true;
9092 }
9093 }
9094 } else if (w.isDrawnLw()) {
9095 atoken.startingDisplayed = true;
9096 }
Craig Mautner6fbda632012-07-03 09:26:39 -07009097 }
9098 }
9099 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009100
Craig Mautner76a71652012-09-03 23:23:58 -07009101 if (isDefaultDisplay && someoneLosingFocus && (w == mCurrentFocus)
9102 && w.isDisplayedLw()) {
9103 focusDisplayed = true;
9104 }
Craig Mautner51bb12b2012-04-27 14:39:53 -07009105
Craig Mautner76a71652012-09-03 23:23:58 -07009106 updateResizingWindows(w);
9107 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07009108
Craig Mautner65d11b32012-10-01 13:59:52 -07009109 final boolean hasUniqueContent;
9110 switch (mInnerFields.mDisplayHasContent) {
9111 case LayoutFields.DISPLAY_CONTENT_MIRROR:
9112 hasUniqueContent = isDefaultDisplay;
9113 break;
9114 case LayoutFields.DISPLAY_CONTENT_UNIQUE:
9115 hasUniqueContent = true;
9116 break;
9117 case LayoutFields.DISPLAY_CONTENT_UNKNOWN:
9118 default:
9119 hasUniqueContent = false;
9120 break;
9121 }
9122 mDisplayManagerService.setDisplayHasContent(displayId, hasUniqueContent,
9123 true /* inTraversal, must call performTraversalInTrans... below */);
9124
Craig Mautnera91f9e22012-09-14 16:22:08 -07009125 if (!mInnerFields.mDimming && mAnimator.isDimmingLocked(displayId)) {
9126 stopDimmingLocked(displayId);
9127 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009128 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009129
Craig Mautner6fbda632012-07-03 09:26:39 -07009130 if (updateAllDrawn) {
9131 updateAllDrawnLocked();
9132 }
9133
Craig Mautner7358fbf2012-04-12 21:06:33 -07009134 if (focusDisplayed) {
9135 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
9136 }
Craig Mautner65d11b32012-10-01 13:59:52 -07009137
9138 // Give the display manager a chance to adjust properties
9139 // like display rotation if it needs to.
9140 mDisplayManagerService.performTraversalInTransactionFromWindowManager();
9141
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009142 } catch (RuntimeException e) {
Dianne Hackborn89620282011-09-11 12:47:45 -07009143 Log.wtf(TAG, "Unhandled exception in Window Manager", e);
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07009144 } finally {
9145 Surface.closeTransaction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009146 }
9147
Craig Mautner76a71652012-09-03 23:23:58 -07009148 final WindowList defaultWindows = defaultDisplay.getWindowList();
9149
Craig Mautner764983d2012-03-22 11:37:36 -07009150 // If we are ready to perform an app transition, check through
9151 // all of the app tokens to be shown and see if they are ready
9152 // to go.
9153 if (mAppTransitionReady) {
Craig Mautner76a71652012-09-03 23:23:58 -07009154 defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009155 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAppTransitionReadyLocked",
Craig Mautner76a71652012-09-03 23:23:58 -07009156 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009157 }
9158
9159 mInnerFields.mAdjResult = 0;
9160
9161 if (!mAnimator.mAnimating && mAppTransitionRunning) {
9162 // We have finished the animation of an app transition. To do
9163 // this, we have delayed a lot of operations like showing and
9164 // hiding apps, moving apps in Z-order, etc. The app token list
9165 // reflects the correct Z-order, but the window list may now
9166 // be out of sync with it. So here we will just rebuild the
9167 // entire app window list. Fun!
Craig Mautner76a71652012-09-03 23:23:58 -07009168 defaultDisplay.pendingLayoutChanges |= handleAnimatingStoppedAndTransitionLocked();
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009169 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAnimStopAndXitionLock",
Craig Mautner76a71652012-09-03 23:23:58 -07009170 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009171 }
9172
Craig Mautner76a71652012-09-03 23:23:58 -07009173 if (mInnerFields.mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
9174 && !mAppTransitionReady) {
Craig Mautner764983d2012-03-22 11:37:36 -07009175 // At this point, there was a window with a wallpaper that
9176 // was force hiding other windows behind it, but now it
9177 // is going away. This may be simple -- just animate
9178 // away the wallpaper and its window -- or it may be
9179 // hard -- the wallpaper now needs to be shown behind
9180 // something that was hidden.
Craig Mautner76a71652012-09-03 23:23:58 -07009181 defaultDisplay.pendingLayoutChanges |= animateAwayWallpaperLocked();
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009182 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animateAwayWallpaperLocked",
Craig Mautner76a71652012-09-03 23:23:58 -07009183 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009184 }
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009185 mInnerFields.mWallpaperForceHidingChanged = false;
Craig Mautner764983d2012-03-22 11:37:36 -07009186
Craig Mautnere7ae2502012-03-26 17:11:19 -07009187 if (mInnerFields.mWallpaperMayChange) {
9188 if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG,
9189 "Wallpaper may change! Adjusting");
9190 mInnerFields.mAdjResult |= adjustWallpaperWindowsLocked();
9191 }
9192
9193 if ((mInnerFields.mAdjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
9194 if (DEBUG_WALLPAPER) Slog.v(TAG,
9195 "Wallpaper layer changed: assigning layers + relayout");
Craig Mautner76a71652012-09-03 23:23:58 -07009196 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
9197 assignLayersLocked(defaultWindows);
Craig Mautnere7ae2502012-03-26 17:11:19 -07009198 } else if ((mInnerFields.mAdjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
9199 if (DEBUG_WALLPAPER) Slog.v(TAG,
9200 "Wallpaper visibility changed: relayout");
Craig Mautner76a71652012-09-03 23:23:58 -07009201 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
Craig Mautnere7ae2502012-03-26 17:11:19 -07009202 }
9203
9204 if (mFocusMayChange) {
9205 mFocusMayChange = false;
9206 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
9207 false /*updateInputWindows*/)) {
Craig Mautner76a71652012-09-03 23:23:58 -07009208 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
Craig Mautnere7ae2502012-03-26 17:11:19 -07009209 mInnerFields.mAdjResult = 0;
9210 }
9211 }
Craig Mautner764983d2012-03-22 11:37:36 -07009212
Craig Mautner19d59bc2012-09-04 11:15:56 -07009213 if (needsLayout()) {
Craig Mautner76a71652012-09-03 23:23:58 -07009214 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
9215 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
9216 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009217 }
9218
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009219 if (!mResizingWindows.isEmpty()) {
9220 for (i = mResizingWindows.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009221 WindowState win = mResizingWindows.get(i);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009222 final WindowStateAnimator winAnimator = win.mWinAnimator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009223 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009224 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07009225 "Reporting new frame to " + win + ": " + win.mCompatFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -07009226 int diff = 0;
Craig Mautner812d2ca2012-09-27 15:35:34 -07009227 boolean configChanged = win.isConfigChanged();
Craig Mautnerc36c49e2012-09-29 16:02:43 -07009228 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION
9229 // TODO: Remove once b/7094175 is fixed
9230 || ((String)win.mAttrs.getTitle()).contains("Keyguard"))
Dianne Hackborn694f79b2010-03-17 19:44:59 -07009231 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009232 Slog.i(TAG, "Sending new config to window " + win + ": "
Craig Mautnera608b882012-03-30 13:03:49 -07009233 + winAnimator.mSurfaceW + "x" + winAnimator.mSurfaceH
Dianne Hackborn694f79b2010-03-17 19:44:59 -07009234 + " / " + mCurConfiguration + " / 0x"
9235 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009236 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07009237 win.mConfiguration = mCurConfiguration;
Craig Mautner749a7bb2012-04-02 13:49:53 -07009238 if (DEBUG_ORIENTATION &&
9239 winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) Slog.i(
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009240 TAG, "Resizing " + win + " WITH DRAW PENDING");
Svetoslav Ganov758143e2012-08-06 16:40:27 -07009241 win.mClient.resized(win.mFrame, win.mLastContentInsets, win.mLastVisibleInsets,
Craig Mautner749a7bb2012-04-02 13:49:53 -07009242 winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING,
9243 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009244 win.mContentInsetsChanged = false;
9245 win.mVisibleInsetsChanged = false;
Craig Mautnera608b882012-03-30 13:03:49 -07009246 winAnimator.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009247 } catch (RemoteException e) {
9248 win.mOrientationChanging = false;
9249 }
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009250 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009251 mResizingWindows.clear();
9252 }
Romain Guy06882f82009-06-10 13:36:04 -07009253
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009254 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
9255 "With display frozen, orientationChangeComplete="
9256 + mInnerFields.mOrientationChangeComplete);
9257 if (mInnerFields.mOrientationChangeComplete) {
9258 if (mWindowsFreezingScreen) {
9259 mWindowsFreezingScreen = false;
9260 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
9261 }
9262 stopFreezingDisplayLocked();
9263 }
9264
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009265 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009266 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009267 i = mDestroySurface.size();
9268 if (i > 0) {
9269 do {
9270 i--;
9271 WindowState win = mDestroySurface.get(i);
9272 win.mDestroying = false;
9273 if (mInputMethodWindow == win) {
9274 mInputMethodWindow = null;
9275 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009276 if (win == mWallpaperTarget) {
9277 wallpaperDestroyed = true;
9278 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009279 win.mWinAnimator.destroySurfaceLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009280 } while (i > 0);
9281 mDestroySurface.clear();
9282 }
9283
9284 // Time to remove any exiting tokens?
9285 for (i=mExitingTokens.size()-1; i>=0; i--) {
9286 WindowToken token = mExitingTokens.get(i);
9287 if (!token.hasVisible) {
9288 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07009289 if (token.windowType == TYPE_WALLPAPER) {
9290 mWallpaperTokens.remove(token);
Craig Mautner918b53b2012-07-09 14:15:54 -07009291 updateLayoutToAnimWallpaperTokens();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07009292 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009293 }
9294 }
9295
9296 // Time to remove any exiting applications?
9297 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
9298 AppWindowToken token = mExitingAppTokens.get(i);
9299 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009300 // Make sure there is no animation running on this token,
9301 // so any windows associated with it will be removed as
9302 // soon as their animations are complete
Craig Mautner59431632012-04-04 11:56:44 -07009303 token.mAppAnimator.clearAnimation();
9304 token.mAppAnimator.animating = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009305 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
9306 "performLayout: App token exiting now removed" + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009307 mAppTokens.remove(token);
Craig Mautneref25d7a2012-05-15 23:01:47 -07009308 mAnimatingAppTokens.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009309 mExitingAppTokens.remove(i);
9310 }
9311 }
9312
Dianne Hackborn12d3a942012-04-27 14:16:30 -07009313 if (!mAnimator.mAnimating && mRelayoutWhileAnimating.size() > 0) {
9314 for (int j=mRelayoutWhileAnimating.size()-1; j>=0; j--) {
9315 try {
9316 mRelayoutWhileAnimating.get(j).mClient.doneAnimating();
9317 } catch (RemoteException e) {
9318 }
9319 }
9320 mRelayoutWhileAnimating.clear();
9321 }
9322
Craig Mautner19d59bc2012-09-04 11:15:56 -07009323 if (wallpaperDestroyed && (adjustWallpaperWindowsLocked() != 0)) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07009324 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009325 }
Craig Mautner76a71652012-09-03 23:23:58 -07009326
9327 DisplayContentsIterator iterator = new DisplayContentsIterator();
9328 while (iterator.hasNext()) {
9329 DisplayContent displayContent = iterator.next();
9330 if (displayContent.pendingLayoutChanges != 0) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009331 displayContent.layoutNeeded = true;
Craig Mautner76a71652012-09-03 23:23:58 -07009332 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009333 }
Jeff Browneb857f12010-07-16 10:06:33 -07009334
Jeff Brown3a22cd92011-01-21 13:59:04 -08009335 // Finally update all input windows now that the window changes have stabilized.
Jeff Brown2e44b072011-01-24 15:21:56 -08009336 mInputMonitor.updateInputWindowsLw(true /*force*/);
Jeff Browneb857f12010-07-16 10:06:33 -07009337
Craig Mautner259328c2012-08-21 19:30:58 -07009338 setHoldScreenLocked(mInnerFields.mHoldScreen);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009339 if (!mDisplayFrozen) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009340 if (mInnerFields.mScreenBrightness < 0 || mInnerFields.mScreenBrightness > 1.0f) {
Jeff Brown96307042012-07-27 15:51:34 -07009341 mPowerManager.setScreenBrightnessOverrideFromWindowManager(-1);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009342 } else {
Jeff Brown96307042012-07-27 15:51:34 -07009343 mPowerManager.setScreenBrightnessOverrideFromWindowManager(
9344 toBrightnessOverride(mInnerFields.mScreenBrightness));
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009345 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009346 if (mInnerFields.mButtonBrightness < 0 || mInnerFields.mButtonBrightness > 1.0f) {
Jeff Brown96307042012-07-27 15:51:34 -07009347 mPowerManager.setButtonBrightnessOverrideFromWindowManager(-1);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009348 } else {
Jeff Brown96307042012-07-27 15:51:34 -07009349 mPowerManager.setButtonBrightnessOverrideFromWindowManager(
9350 toBrightnessOverride(mInnerFields.mButtonBrightness));
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009351 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009352 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009353
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009354 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009355 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Jeff Brown96307042012-07-27 15:51:34 -07009356 mPowerManager.wakeUp(SystemClock.uptimeMillis());
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009357 mTurnOnScreen = false;
9358 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009359
Craig Mautnera608b882012-03-30 13:03:49 -07009360 if (mInnerFields.mUpdateRotation) {
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009361 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009362 if (updateRotationUncheckedLocked(false)) {
Dianne Hackborn3e4f9d02011-02-04 14:05:55 -08009363 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07009364 } else {
Craig Mautnera608b882012-03-30 13:03:49 -07009365 mInnerFields.mUpdateRotation = false;
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009366 }
9367 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009368
Craig Mautner19d59bc2012-09-04 11:15:56 -07009369 if (mInnerFields.mOrientationChangeComplete && !defaultDisplay.layoutNeeded
9370 && !mInnerFields.mUpdateRotation) {
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07009371 checkDrawnWindowsLocked();
9372 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009373
Craig Mautner76a71652012-09-03 23:23:58 -07009374 final int N = mPendingRemove.size();
9375 if (N > 0) {
9376 if (mPendingRemoveTmp.length < N) {
9377 mPendingRemoveTmp = new WindowState[N+10];
9378 }
9379 mPendingRemove.toArray(mPendingRemoveTmp);
9380 mPendingRemove.clear();
9381 DisplayContentList displayList = new DisplayContentList();
9382 for (i = 0; i < N; i++) {
9383 WindowState w = mPendingRemoveTmp[i];
9384 removeWindowInnerLocked(w.mSession, w);
9385 if (!displayList.contains(w.mDisplayContent)) {
9386 displayList.add(w.mDisplayContent);
9387 }
9388 }
9389
9390 for (DisplayContent displayContent : displayList) {
9391 assignLayersLocked(displayContent.getWindowList());
Craig Mautner19d59bc2012-09-04 11:15:56 -07009392 displayContent.layoutNeeded = true;
Craig Mautner76a71652012-09-03 23:23:58 -07009393 }
Craig Mautner76a71652012-09-03 23:23:58 -07009394 }
9395
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08009396 // Check to see if we are now in a state where the screen should
9397 // be enabled, because the window obscured flags have changed.
9398 enableScreenIfNeededLocked();
Craig Mautner7d8df392012-04-06 15:26:23 -07009399
Craig Mautner711f90a2012-07-03 18:43:52 -07009400 updateLayoutToAnimationLocked();
Craig Mautner7d8df392012-04-06 15:26:23 -07009401
9402 if (DEBUG_WINDOW_TRACE) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009403 Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: animating="
9404 + mAnimator.mAnimating);
Craig Mautner7d8df392012-04-06 15:26:23 -07009405 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009406 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009407
Jeff Brown96307042012-07-27 15:51:34 -07009408 private int toBrightnessOverride(float value) {
9409 return (int)(value * PowerManager.BRIGHTNESS_ON);
9410 }
9411
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009412 void checkDrawnWindowsLocked() {
9413 if (mWaitingForDrawn.size() > 0) {
9414 for (int j=mWaitingForDrawn.size()-1; j>=0; j--) {
9415 Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(j);
9416 WindowState win = pair.first;
9417 //Slog.i(TAG, "Waiting for drawn " + win + ": removed="
9418 // + win.mRemoved + " visible=" + win.isVisibleLw()
9419 // + " shown=" + win.mSurfaceShown);
9420 if (win.mRemoved || !win.isVisibleLw()) {
9421 // Window has been removed or made invisible; no draw
9422 // will now happen, so stop waiting.
9423 Slog.w(TAG, "Aborted waiting for drawn: " + pair.first);
9424 try {
9425 pair.second.sendResult(null);
9426 } catch (RemoteException e) {
9427 }
9428 mWaitingForDrawn.remove(pair);
9429 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009430 } else if (win.mWinAnimator.mSurfaceShown) {
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009431 // Window is now drawn (and shown).
9432 try {
9433 pair.second.sendResult(null);
9434 } catch (RemoteException e) {
9435 }
9436 mWaitingForDrawn.remove(pair);
9437 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9438 }
9439 }
9440 }
9441 }
9442
9443 public void waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009444 synchronized (mWindowMap) {
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009445 WindowState win = windowForClientLocked(null, token, true);
9446 if (win != null) {
9447 Pair<WindowState, IRemoteCallback> pair =
9448 new Pair<WindowState, IRemoteCallback>(win, callback);
9449 Message m = mH.obtainMessage(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9450 mH.sendMessageDelayed(m, 2000);
9451 mWaitingForDrawn.add(pair);
9452 checkDrawnWindowsLocked();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009453 }
9454 }
9455 }
9456
Craig Mautner259328c2012-08-21 19:30:58 -07009457 void setHoldScreenLocked(final Session newHoldScreen) {
9458 final boolean hold = newHoldScreen != null;
9459
9460 if (hold && mHoldingScreenOn != newHoldScreen) {
9461 mHoldingScreenWakeLock.setWorkSource(new WorkSource(newHoldScreen.mUid));
9462 }
9463 mHoldingScreenOn = newHoldScreen;
9464
9465 final boolean state = mHoldingScreenWakeLock.isHeld();
9466 if (hold != state) {
9467 if (hold) {
Daniel Sandler0601eb72011-04-13 01:01:32 -04009468 mPolicy.screenOnStartedLw();
Jeff Brown46b9ac02010-04-22 18:58:52 -07009469 mHoldingScreenWakeLock.acquire();
9470 } else {
9471 mPolicy.screenOnStoppedLw();
9472 mHoldingScreenWakeLock.release();
9473 }
9474 }
9475 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009476
Craig Mautner722285e2012-09-07 13:55:58 -07009477 @Override
Jeff Brown4ed8fe72012-08-30 18:18:29 -07009478 public void requestTraversal() {
9479 synchronized (mWindowMap) {
9480 requestTraversalLocked();
9481 }
9482 }
9483
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08009484 void requestTraversalLocked() {
9485 if (!mTraversalScheduled) {
9486 mTraversalScheduled = true;
9487 mH.sendEmptyMessage(H.DO_TRAVERSAL);
9488 }
9489 }
9490
Craig Mautner711f90a2012-07-03 18:43:52 -07009491 /** Note that Locked in this case is on mLayoutToAnim */
Jeff Brown4a06c802012-02-15 15:06:01 -08009492 void scheduleAnimationLocked() {
Craig Mautner711f90a2012-07-03 18:43:52 -07009493 final LayoutToAnimatorParams layoutToAnim = mLayoutToAnim;
9494 if (!layoutToAnim.mAnimationScheduled) {
9495 layoutToAnim.mAnimationScheduled = true;
9496 mChoreographer.postCallback(
9497 Choreographer.CALLBACK_ANIMATION, mAnimator.mAnimationRunnable, null);
9498 }
9499 }
9500
9501 void updateLayoutToAnimationLocked() {
9502 final LayoutToAnimatorParams layoutToAnim = mLayoutToAnim;
Craig Mautner1caa3992012-06-22 09:46:48 -07009503 synchronized (layoutToAnim) {
9504 // Copy local params to transfer params.
Craig Mautnera91f9e22012-09-14 16:22:08 -07009505 SparseArray<WinAnimatorList> allWinAnimatorLists = layoutToAnim.mWinAnimatorLists;
Craig Mautner59c00972012-07-30 12:10:24 -07009506 allWinAnimatorLists.clear();
9507 DisplayContentsIterator iterator = new DisplayContentsIterator();
9508 while (iterator.hasNext()) {
9509 final DisplayContent displayContent = iterator.next();
9510 WinAnimatorList winAnimatorList = new WinAnimatorList();
9511 final WindowList windows = displayContent.getWindowList();
9512 int N = windows.size();
9513 for (int i = 0; i < N; i++) {
9514 final WindowStateAnimator winAnimator = windows.get(i).mWinAnimator;
9515 if (winAnimator.mSurface != null) {
9516 winAnimatorList.add(winAnimator);
9517 }
Craig Mautner1caa3992012-06-22 09:46:48 -07009518 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07009519 allWinAnimatorLists.put(displayContent.getDisplayId(), winAnimatorList);
Craig Mautner1caa3992012-06-22 09:46:48 -07009520 }
Craig Mautner322e4032012-07-13 13:35:20 -07009521
Craig Mautner1caa3992012-06-22 09:46:48 -07009522 layoutToAnim.mWallpaperTarget = mWallpaperTarget;
Craig Mautner918b53b2012-07-09 14:15:54 -07009523 layoutToAnim.mLowerWallpaperTarget = mLowerWallpaperTarget;
9524 layoutToAnim.mUpperWallpaperTarget = mUpperWallpaperTarget;
Craig Mautner322e4032012-07-13 13:35:20 -07009525
9526 final ArrayList<AppWindowAnimParams> paramList = layoutToAnim.mAppWindowAnimParams;
9527 paramList.clear();
Craig Mautner59c00972012-07-30 12:10:24 -07009528 int N = mAnimatingAppTokens.size();
Craig Mautner322e4032012-07-13 13:35:20 -07009529 for (int i = 0; i < N; i++) {
9530 paramList.add(new AppWindowAnimParams(mAnimatingAppTokens.get(i).mAppAnimator));
9531 }
9532
9533 layoutToAnim.mParamsModified = true;
Craig Mautner711f90a2012-07-03 18:43:52 -07009534 scheduleAnimationLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009535 }
9536 }
Romain Guy06882f82009-06-10 13:36:04 -07009537
Craig Mautner918b53b2012-07-09 14:15:54 -07009538 void updateLayoutToAnimWallpaperTokens() {
9539 synchronized(mLayoutToAnim) {
9540 mLayoutToAnim.mWallpaperTokens = new ArrayList<WindowToken>(mWallpaperTokens);
9541 mLayoutToAnim.mChanges |= LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED;
9542 }
9543 }
9544
Craig Mautnera91f9e22012-09-14 16:22:08 -07009545 void setAnimDimParams(int displayId, DimAnimator.Parameters params) {
Craig Mautnera76fdb72012-07-03 19:03:02 -07009546 synchronized (mLayoutToAnim) {
Craig Mautnera91f9e22012-09-14 16:22:08 -07009547 mLayoutToAnim.mDimParams.put(displayId, params);
Craig Mautnera76fdb72012-07-03 19:03:02 -07009548 scheduleAnimationLocked();
9549 }
9550 }
9551
Craig Mautnera91f9e22012-09-14 16:22:08 -07009552 void startDimmingLocked(final WindowStateAnimator winAnimator, final float target,
Craig Mautnera76fdb72012-07-03 19:03:02 -07009553 final int width, final int height) {
Craig Mautnera91f9e22012-09-14 16:22:08 -07009554 setAnimDimParams(winAnimator.mWin.getDisplayId(),
9555 new DimAnimator.Parameters(winAnimator, width, height, target));
Craig Mautnera76fdb72012-07-03 19:03:02 -07009556 }
9557
Craig Mautnera91f9e22012-09-14 16:22:08 -07009558 void stopDimmingLocked(int displayId) {
9559 setAnimDimParams(displayId, null);
Craig Mautnera76fdb72012-07-03 19:03:02 -07009560 }
9561
Craig Mautner19d59bc2012-09-04 11:15:56 -07009562 private boolean needsLayout() {
9563 DisplayContentsIterator iterator = new DisplayContentsIterator();
9564 while (iterator.hasNext()) {
9565 if (iterator.next().layoutNeeded) {
9566 return true;
9567 }
9568 }
9569 return false;
9570 }
9571
Craig Mautner322e4032012-07-13 13:35:20 -07009572 private boolean copyAnimToLayoutParamsLocked() {
9573 boolean doRequest = false;
9574 final WindowAnimator.AnimatorToLayoutParams animToLayout = mAnimator.mAnimToLayout;
9575 synchronized (animToLayout) {
9576 animToLayout.mUpdateQueued = false;
9577 final int bulkUpdateParams = animToLayout.mBulkUpdateParams;
9578 // TODO(cmautner): As the number of bits grows, use masks of bit groups to
9579 // eliminate unnecessary tests.
9580 if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) {
9581 mInnerFields.mUpdateRotation = true;
9582 doRequest = true;
9583 }
9584 if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
9585 mInnerFields.mWallpaperMayChange = true;
9586 doRequest = true;
9587 }
9588 if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
9589 mInnerFields.mWallpaperForceHidingChanged = true;
9590 doRequest = true;
9591 }
9592 if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
9593 mInnerFields.mOrientationChangeComplete = false;
9594 } else {
9595 mInnerFields.mOrientationChangeComplete = true;
9596 if (mWindowsFreezingScreen) {
9597 doRequest = true;
9598 }
9599 }
9600 if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
9601 mTurnOnScreen = true;
9602 }
9603
Craig Mautner76a71652012-09-03 23:23:58 -07009604 SparseIntArray pendingLayouts = animToLayout.mPendingLayoutChanges;
9605 final int count = pendingLayouts.size();
9606 if (count > 0) {
Craig Mautner322e4032012-07-13 13:35:20 -07009607 doRequest = true;
9608 }
Craig Mautner76a71652012-09-03 23:23:58 -07009609 for (int i = 0; i < count; ++i) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07009610 final DisplayContent displayContent =
9611 getDisplayContentLocked(pendingLayouts.keyAt(i));
Craig Mautner69b08182012-09-05 13:07:13 -07009612 displayContent.pendingLayoutChanges |= pendingLayouts.valueAt(i);
Craig Mautner76a71652012-09-03 23:23:58 -07009613 }
Craig Mautner322e4032012-07-13 13:35:20 -07009614
9615 mWindowDetachedWallpaper = animToLayout.mWindowDetachedWallpaper;
9616 }
9617 return doRequest;
9618 }
9619
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009620 boolean reclaimSomeSurfaceMemoryLocked(WindowStateAnimator winAnimator, String operation,
9621 boolean secure) {
9622 final Surface surface = winAnimator.mSurface;
Dianne Hackborn64825172011-03-02 21:32:58 -08009623 boolean leakedSurface = false;
9624 boolean killedApps = false;
Romain Guy06882f82009-06-10 13:36:04 -07009625
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009626 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
9627 winAnimator.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -07009628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009629 if (mForceRemoves == null) {
9630 mForceRemoves = new ArrayList<WindowState>();
9631 }
Romain Guy06882f82009-06-10 13:36:04 -07009632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009633 long callingIdentity = Binder.clearCallingIdentity();
9634 try {
9635 // There was some problem... first, do a sanity check of the
9636 // window list to make sure we haven't left any dangling surfaces
9637 // around.
Craig Mautner59c00972012-07-30 12:10:24 -07009638
9639 AllWindowsIterator iterator = new AllWindowsIterator();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009640 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
Craig Mautner59c00972012-07-30 12:10:24 -07009641 while (iterator.hasNext()) {
9642 WindowState ws = iterator.next();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009643 WindowStateAnimator wsa = ws.mWinAnimator;
9644 if (wsa.mSurface != null) {
9645 if (!mSessions.contains(wsa.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009646 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009647 + ws + " surface=" + wsa.mSurface
9648 + " token=" + ws.mToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009649 + " pid=" + ws.mSession.mPid
9650 + " uid=" + ws.mSession.mUid);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08009651 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009652 wsa.mSurface.destroy();
9653 wsa.mSurfaceShown = false;
9654 wsa.mSurface = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009655 ws.mHasSurface = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009656 mForceRemoves.add(ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009657 leakedSurface = true;
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08009658 } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009659 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009660 + ws + " surface=" + wsa.mSurface
9661 + " token=" + ws.mAppToken);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08009662 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009663 wsa.mSurface.destroy();
9664 wsa.mSurfaceShown = false;
9665 wsa.mSurface = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009666 ws.mHasSurface = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009667 leakedSurface = true;
9668 }
9669 }
9670 }
Romain Guy06882f82009-06-10 13:36:04 -07009671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009672 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009673 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009674 SparseIntArray pidCandidates = new SparseIntArray();
Craig Mautner59c00972012-07-30 12:10:24 -07009675 iterator = new AllWindowsIterator();
9676 while (iterator.hasNext()) {
9677 WindowState ws = iterator.next();
9678 if (mForceRemoves.contains(ws)) {
9679 continue;
9680 }
9681 WindowStateAnimator wsa = ws.mWinAnimator;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009682 if (wsa.mSurface != null) {
9683 pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009684 }
9685 }
9686 if (pidCandidates.size() > 0) {
9687 int[] pids = new int[pidCandidates.size()];
9688 for (int i=0; i<pids.length; i++) {
9689 pids[i] = pidCandidates.keyAt(i);
9690 }
9691 try {
Dianne Hackborn64825172011-03-02 21:32:58 -08009692 if (mActivityManager.killPids(pids, "Free memory", secure)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009693 killedApps = true;
9694 }
9695 } catch (RemoteException e) {
9696 }
9697 }
9698 }
Romain Guy06882f82009-06-10 13:36:04 -07009699
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009700 if (leakedSurface || killedApps) {
9701 // We managed to reclaim some memory, so get rid of the trouble
9702 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -08009703 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009704 if (surface != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009705 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
Dianne Hackborn5fd21692011-06-07 14:09:47 -07009706 "RECOVER DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009707 surface.destroy();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009708 winAnimator.mSurfaceShown = false;
9709 winAnimator.mSurface = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009710 winAnimator.mWin.mHasSurface = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009711 }
Romain Guy06882f82009-06-10 13:36:04 -07009712
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009713 try {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009714 winAnimator.mWin.mClient.dispatchGetNewSurface();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009715 } catch (RemoteException e) {
9716 }
9717 }
9718 } finally {
9719 Binder.restoreCallingIdentity(callingIdentity);
9720 }
Dianne Hackborn64825172011-03-02 21:32:58 -08009721
9722 return leakedSurface || killedApps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009723 }
Romain Guy06882f82009-06-10 13:36:04 -07009724
Jeff Brown3a22cd92011-01-21 13:59:04 -08009725 private boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009726 WindowState newFocus = computeFocusedWindowLocked();
9727 if (mCurrentFocus != newFocus) {
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07009728 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009729 // This check makes sure that we don't already have the focus
9730 // change message pending.
9731 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
9732 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009733 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009734 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
9735 final WindowState oldFocus = mCurrentFocus;
9736 mCurrentFocus = newFocus;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009737 mAnimator.setCurrentFocus(newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009738 mLosingFocus.remove(newFocus);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009739 int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus);
Romain Guy06882f82009-06-10 13:36:04 -07009740
Craig Mautner59c00972012-07-30 12:10:24 -07009741 // TODO(multidisplay): Focused windows on default display only.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07009742 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07009743
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009744 final WindowState imWindow = mInputMethodWindow;
9745 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009746 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009747 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009748 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
Jeff Brown20337632012-09-24 14:25:54 -07009749 displayContent.layoutNeeded = true;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009750 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009751 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Craig Mautner59c00972012-07-30 12:10:24 -07009752 performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009753 focusChanged &= ~WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009754 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
9755 // Client will do the layout, but we need to assign layers
9756 // for handleNewWindowLocked() below.
Craig Mautner59c00972012-07-30 12:10:24 -07009757 assignLayersLocked(displayContent.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009758 }
9759 }
Dianne Hackborndf89e652011-10-06 22:35:11 -07009760
Craig Mautner39834192012-09-02 07:47:24 -07009761 if ((focusChanged & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07009762 // The change in focus caused us to need to do a layout. Okay.
Jeff Brown20337632012-09-24 14:25:54 -07009763 displayContent.layoutNeeded = true;
Dianne Hackborndf89e652011-10-06 22:35:11 -07009764 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Craig Mautner59c00972012-07-30 12:10:24 -07009765 performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009766 }
9767 }
9768
Jeff Brown349703e2010-06-22 01:27:15 -07009769 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
9770 // If we defer assigning layers, then the caller is responsible for
9771 // doing this part.
Jeff Brown3a22cd92011-01-21 13:59:04 -08009772 finishUpdateFocusedWindowAfterAssignLayersLocked(updateInputWindows);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009773 }
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07009774
9775 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009776 return true;
9777 }
9778 return false;
9779 }
Jeff Brown349703e2010-06-22 01:27:15 -07009780
Jeff Brown3a22cd92011-01-21 13:59:04 -08009781 private void finishUpdateFocusedWindowAfterAssignLayersLocked(boolean updateInputWindows) {
9782 mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows);
Jeff Brown349703e2010-06-22 01:27:15 -07009783 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009784
9785 private WindowState computeFocusedWindowLocked() {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07009786 if (mAnimator.mUniverseBackground != null
9787 && mAnimator.mUniverseBackground.mWin.canReceiveKeys()) {
9788 return mAnimator.mUniverseBackground.mWin;
9789 }
9790
Jeff Brown20337632012-09-24 14:25:54 -07009791 final int displayCount = mDisplayContents.size();
9792 for (int i = 0; i < displayCount; i++) {
9793 final DisplayContent displayContent = mDisplayContents.valueAt(i);
9794 WindowState win = findFocusedWindowLocked(displayContent);
9795 if (win != null) {
9796 return win;
9797 }
9798 }
9799 return null;
9800 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009801
Jeff Brown20337632012-09-24 14:25:54 -07009802 private WindowState findFocusedWindowLocked(DisplayContent displayContent) {
9803 int nextAppIndex = mAppTokens.size()-1;
9804 WindowToken nextApp = nextAppIndex >= 0 ? mAppTokens.get(nextAppIndex) : null;
9805
9806 final WindowList windows = displayContent.getWindowList();
Craig Mautner59c00972012-07-30 12:10:24 -07009807 for (int i = windows.size() - 1; i >= 0; i--) {
Jeff Brown20337632012-09-24 14:25:54 -07009808 final WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009809
Joe Onorato8a9b2202010-02-26 18:56:32 -08009810 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009811 TAG, "Looking for focus: " + i
9812 + " = " + win
9813 + ", flags=" + win.mAttrs.flags
9814 + ", canReceive=" + win.canReceiveKeys());
9815
9816 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -07009817
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009818 // If this window's application has been removed, just skip it.
Craig Mautneref25d7a2012-05-15 23:01:47 -07009819 if (thisApp != null && (thisApp.removed || thisApp.sendingToBottom)) {
Craig Mautner3f99fde2012-06-19 14:10:01 -07009820 if (DEBUG_FOCUS) Slog.v(TAG, "Skipping app because " + (thisApp.removed
9821 ? "removed" : "sendingToBottom"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009822 continue;
9823 }
Romain Guy06882f82009-06-10 13:36:04 -07009824
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009825 // If there is a focused app, don't allow focus to go to any
9826 // windows below it. If this is an application window, step
9827 // through the app tokens until we find its app.
9828 if (thisApp != null && nextApp != null && thisApp != nextApp
9829 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
9830 int origAppIndex = nextAppIndex;
9831 while (nextAppIndex > 0) {
9832 if (nextApp == mFocusedApp) {
9833 // Whoops, we are below the focused app... no focus
9834 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -08009835 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009836 TAG, "Reached focused app: " + mFocusedApp);
9837 return null;
9838 }
9839 nextAppIndex--;
9840 nextApp = mAppTokens.get(nextAppIndex);
9841 if (nextApp == thisApp) {
9842 break;
9843 }
9844 }
9845 if (thisApp != nextApp) {
9846 // Uh oh, the app token doesn't exist! This shouldn't
9847 // happen, but if it does we can get totally hosed...
9848 // so restart at the original app.
9849 nextAppIndex = origAppIndex;
9850 nextApp = mAppTokens.get(nextAppIndex);
9851 }
9852 }
9853
9854 // Dispatch to this window if it is wants key events.
9855 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009856 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009857 TAG, "Found focus @ " + i + " = " + win);
Jeff Brown20337632012-09-24 14:25:54 -07009858 return win;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009859 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009860 }
Jeff Brown20337632012-09-24 14:25:54 -07009861 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009862 }
9863
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009864 private void startFreezingDisplayLocked(boolean inTransaction,
9865 int exitAnim, int enterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009866 if (mDisplayFrozen) {
9867 return;
9868 }
Romain Guy06882f82009-06-10 13:36:04 -07009869
Jeff Browne215f262012-09-10 16:01:14 -07009870 if (!mDisplayReady || !mPolicy.isScreenOnFully()) {
Dianne Hackborn8e8d65f2011-08-11 19:36:18 -07009871 // No need to freeze the screen before the system is ready or if
9872 // the screen is off.
9873 return;
9874 }
9875
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009876 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -07009877
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009878 mDisplayFrozen = true;
Craig Mautner7d8df392012-04-06 15:26:23 -07009879
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009880 mInputMonitor.freezeInputDispatchingLw();
Craig Mautner7d8df392012-04-06 15:26:23 -07009881
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009882 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
9883 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07009884 mNextAppTransitionType = ActivityOptions.ANIM_NONE;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009885 mNextAppTransitionPackage = null;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07009886 mNextAppTransitionThumbnail = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009887 mAppTransitionReady = true;
9888 }
Romain Guy06882f82009-06-10 13:36:04 -07009889
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009890 if (PROFILE_ORIENTATION) {
9891 File file = new File("/data/system/frozen");
9892 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
9893 }
Dianne Hackborna1111872010-11-23 20:55:11 -08009894
9895 if (CUSTOM_SCREEN_ROTATION) {
Craig Mautnera91f9e22012-09-14 16:22:08 -07009896 final DisplayContent displayContent = getDefaultDisplayContentLocked();
9897 final int displayId = displayContent.getDisplayId();
9898 ScreenRotationAnimation screenRotationAnimation =
9899 mAnimator.getScreenRotationAnimationLocked(displayId);
9900 if (screenRotationAnimation != null) {
9901 screenRotationAnimation.kill();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08009902 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07009903
Craig Mautner59c00972012-07-30 12:10:24 -07009904 // TODO(multidisplay): rotation on main screen only.
Jeff Browne215f262012-09-10 16:01:14 -07009905 final Display display = displayContent.getDisplay();
9906 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
Craig Mautnera91f9e22012-09-14 16:22:08 -07009907 screenRotationAnimation = new ScreenRotationAnimation(mContext,
Jeff Browne215f262012-09-10 16:01:14 -07009908 display, mFxSession, inTransaction, displayInfo.logicalWidth,
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009909 displayInfo.logicalHeight, display.getRotation(),
9910 exitAnim, enterAnim);
Craig Mautnera91f9e22012-09-14 16:22:08 -07009911 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackborna1111872010-11-23 20:55:11 -08009912 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009913 }
Romain Guy06882f82009-06-10 13:36:04 -07009914
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009915 private void stopFreezingDisplayLocked() {
9916 if (!mDisplayFrozen) {
9917 return;
9918 }
Romain Guy06882f82009-06-10 13:36:04 -07009919
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009920 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen
9921 || mClientFreezingScreen) {
Craig Mautnerd87946b2012-03-29 18:00:19 -07009922 if (DEBUG_ORIENTATION) Slog.d(TAG,
9923 "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + mWaitingForConfig
9924 + ", mAppsFreezingScreen=" + mAppsFreezingScreen
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009925 + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen
9926 + ", mClientFreezingScreen=" + mClientFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009927 return;
9928 }
9929
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009930 mDisplayFrozen = false;
9931 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009932 mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009933 if (PROFILE_ORIENTATION) {
9934 Debug.stopMethodTracing();
9935 }
Dianne Hackborna1111872010-11-23 20:55:11 -08009936
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009937 boolean updateRotation = false;
Craig Mautner59c00972012-07-30 12:10:24 -07009938
Craig Mautnera91f9e22012-09-14 16:22:08 -07009939 final DisplayContent displayContent = getDefaultDisplayContentLocked();
9940 final int displayId = displayContent.getDisplayId();
9941 ScreenRotationAnimation screenRotationAnimation =
9942 mAnimator.getScreenRotationAnimationLocked(displayId);
9943 if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
9944 && screenRotationAnimation.hasScreenshot()) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07009945 if (DEBUG_ORIENTATION) Slog.i(TAG, "**** Dismissing screen rotation animation");
Craig Mautner59c00972012-07-30 12:10:24 -07009946 // TODO(multidisplay): rotation on main screen only.
Craig Mautnera91f9e22012-09-14 16:22:08 -07009947 DisplayInfo displayInfo = displayContent.getDisplayInfo();
9948 if (screenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
Craig Mautner59c00972012-07-30 12:10:24 -07009949 mTransitionAnimationScale, displayInfo.logicalWidth,
9950 displayInfo.logicalHeight)) {
Craig Mautner711f90a2012-07-03 18:43:52 -07009951 updateLayoutToAnimationLocked();
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009952 } else {
Craig Mautnera91f9e22012-09-14 16:22:08 -07009953 screenRotationAnimation.kill();
9954 screenRotationAnimation = null;
9955 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009956 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -08009957 }
9958 } else {
Craig Mautnera91f9e22012-09-14 16:22:08 -07009959 if (screenRotationAnimation != null) {
9960 screenRotationAnimation.kill();
9961 screenRotationAnimation = null;
9962 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009963 }
9964 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -08009965 }
Romain Guy06882f82009-06-10 13:36:04 -07009966
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009967 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009968
Dianne Hackborn420829e2011-01-28 11:30:35 -08009969 boolean configChanged;
9970
Christopher Tateb696aee2010-04-02 19:08:30 -07009971 // While the display is frozen we don't re-compute the orientation
9972 // to avoid inconsistent states. However, something interesting
9973 // could have actually changed during that time so re-evaluate it
9974 // now to catch that.
Dianne Hackborn420829e2011-01-28 11:30:35 -08009975 configChanged = updateOrientationFromAppTokensLocked(false);
Christopher Tateb696aee2010-04-02 19:08:30 -07009976
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009977 // A little kludge: a lot could have happened while the
9978 // display was frozen, so now that we are coming back we
9979 // do a gc so that any remote references the system
9980 // processes holds on others can be released if they are
9981 // no longer needed.
9982 mH.removeMessages(H.FORCE_GC);
9983 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
9984 2000);
Romain Guy06882f82009-06-10 13:36:04 -07009985
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009986 mScreenFrozenLock.release();
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009987
9988 if (updateRotation) {
9989 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Jeff Brown01a98dd2011-09-20 15:08:29 -07009990 configChanged |= updateRotationUncheckedLocked(false);
Dianne Hackborn420829e2011-01-28 11:30:35 -08009991 }
9992
9993 if (configChanged) {
9994 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009995 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009996 }
Romain Guy06882f82009-06-10 13:36:04 -07009997
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07009998 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
9999 DisplayMetrics dm) {
10000 if (index < tokens.length) {
10001 String str = tokens[index];
10002 if (str != null && str.length() > 0) {
10003 try {
10004 int val = Integer.parseInt(str);
10005 return val;
10006 } catch (Exception e) {
10007 }
10008 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010009 }
10010 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
10011 return defDps;
10012 }
10013 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
10014 return val;
10015 }
10016
Jeff Brown4ed8fe72012-08-30 18:18:29 -070010017 void createWatermarkInTransaction() {
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010018 if (mWatermark != null) {
10019 return;
10020 }
10021
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010022 File file = new File("/system/etc/setup.conf");
10023 FileInputStream in = null;
10024 try {
10025 in = new FileInputStream(file);
10026 DataInputStream ind = new DataInputStream(in);
10027 String line = ind.readLine();
10028 if (line != null) {
10029 String[] toks = line.split("%");
10030 if (toks != null && toks.length > 0) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010031 mWatermark = new Watermark(getDefaultDisplayContentLocked().getDisplay(),
Jeff Browne215f262012-09-10 16:01:14 -070010032 mRealDisplayMetrics, mFxSession, toks);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010033 }
10034 }
10035 } catch (FileNotFoundException e) {
10036 } catch (IOException e) {
10037 } finally {
10038 if (in != null) {
10039 try {
10040 in.close();
10041 } catch (IOException e) {
10042 }
10043 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010044 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010045 }
10046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010047 @Override
Joe Onorato664644d2011-01-23 17:53:23 -080010048 public void statusBarVisibilityChanged(int visibility) {
Dianne Hackborndf89e652011-10-06 22:35:11 -070010049 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
10050 != PackageManager.PERMISSION_GRANTED) {
10051 throw new SecurityException("Caller does not hold permission "
10052 + android.Manifest.permission.STATUS_BAR);
10053 }
Dianne Hackborn9a230e02011-10-06 11:51:27 -070010054
Joe Onorato664644d2011-01-23 17:53:23 -080010055 synchronized (mWindowMap) {
Dianne Hackborndf89e652011-10-06 22:35:11 -070010056 mLastStatusBarVisibility = visibility;
10057 visibility = mPolicy.adjustSystemUiVisibilityLw(visibility);
10058 updateStatusBarVisibilityLocked(visibility);
10059 }
10060 }
10061
Craig Mautner59c00972012-07-30 12:10:24 -070010062 // TOOD(multidisplay): StatusBar on multiple screens?
Dianne Hackborndf89e652011-10-06 22:35:11 -070010063 void updateStatusBarVisibilityLocked(int visibility) {
10064 mInputManager.setSystemUiVisibility(visibility);
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010065 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -070010066 final int N = windows.size();
Dianne Hackborndf89e652011-10-06 22:35:11 -070010067 for (int i = 0; i < N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -070010068 WindowState ws = windows.get(i);
Dianne Hackborndf89e652011-10-06 22:35:11 -070010069 try {
10070 int curValue = ws.mSystemUiVisibility;
10071 int diff = curValue ^ visibility;
10072 // We are only interested in differences of one of the
10073 // clearable flags...
10074 diff &= View.SYSTEM_UI_CLEARABLE_FLAGS;
10075 // ...if it has actually been cleared.
10076 diff &= ~visibility;
10077 int newValue = (curValue&~diff) | (visibility&diff);
10078 if (newValue != curValue) {
10079 ws.mSeq++;
10080 ws.mSystemUiVisibility = newValue;
10081 }
10082 if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) {
10083 ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq,
10084 visibility, newValue, diff);
10085 }
10086 } catch (RemoteException e) {
10087 // so sorry
10088 }
10089 }
10090 }
10091
10092 @Override
10093 public void reevaluateStatusBarVisibility() {
10094 synchronized (mWindowMap) {
10095 int visibility = mPolicy.adjustSystemUiVisibilityLw(mLastStatusBarVisibility);
10096 updateStatusBarVisibilityLocked(visibility);
10097 performLayoutAndPlaceSurfacesLocked();
10098 }
10099 }
10100
10101 @Override
Jeff Brown32cbc38552011-12-01 14:01:49 -080010102 public FakeWindow addFakeWindow(Looper looper,
10103 InputEventReceiver.Factory inputEventReceiverFactory,
Dianne Hackborndf89e652011-10-06 22:35:11 -070010104 String name, int windowType, int layoutParamsFlags, boolean canReceiveKeys,
10105 boolean hasFocus, boolean touchFullscreen) {
10106 synchronized (mWindowMap) {
Jeff Brown32cbc38552011-12-01 14:01:49 -080010107 FakeWindowImpl fw = new FakeWindowImpl(this, looper, inputEventReceiverFactory,
10108 name, windowType,
Dianne Hackborndf89e652011-10-06 22:35:11 -070010109 layoutParamsFlags, canReceiveKeys, hasFocus, touchFullscreen);
10110 int i=0;
10111 while (i<mFakeWindows.size()) {
10112 if (mFakeWindows.get(i).mWindowLayer <= fw.mWindowLayer) {
10113 break;
Joe Onorato664644d2011-01-23 17:53:23 -080010114 }
10115 }
Dianne Hackborndf89e652011-10-06 22:35:11 -070010116 mFakeWindows.add(i, fw);
10117 mInputMonitor.updateInputWindowsLw(true);
10118 return fw;
10119 }
10120 }
10121
10122 boolean removeFakeWindowLocked(FakeWindow window) {
10123 synchronized (mWindowMap) {
10124 if (mFakeWindows.remove(window)) {
10125 mInputMonitor.updateInputWindowsLw(true);
10126 return true;
10127 }
10128 return false;
Joe Onorato664644d2011-01-23 17:53:23 -080010129 }
10130 }
10131
satoke0a99412012-05-10 02:22:58 +090010132 // It is assumed that this method is called only by InputMethodManagerService.
10133 public void saveLastInputMethodWindowForTransition() {
10134 synchronized (mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -070010135 // TODO(multidisplay): Pass in the displayID.
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010136 DisplayContent displayContent = getDefaultDisplayContentLocked();
satoke0a99412012-05-10 02:22:58 +090010137 if (mInputMethodWindow != null) {
10138 mPolicy.setLastInputMethodWindowLw(mInputMethodWindow, mInputMethodTarget);
10139 }
10140 }
10141 }
10142
Daniel Sandler0c4ccff2011-10-19 16:39:14 -040010143 @Override
10144 public boolean hasNavigationBar() {
10145 return mPolicy.hasNavigationBar();
10146 }
10147
Jim Miller93c518e2012-01-17 15:55:31 -080010148 public void lockNow() {
10149 mPolicy.lockNow();
10150 }
10151
Jeff Brownd7a04de2012-06-17 14:17:52 -070010152 void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010153 pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010154 mPolicy.dump(" ", pw, args);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010155 }
10156
Jeff Brownd7a04de2012-06-17 14:17:52 -070010157 void dumpTokensLocked(PrintWriter pw, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010158 pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
10159 if (mTokenMap.size() > 0) {
10160 pw.println(" All tokens:");
10161 Iterator<WindowToken> it = mTokenMap.values().iterator();
10162 while (it.hasNext()) {
10163 WindowToken token = it.next();
10164 pw.print(" Token "); pw.print(token.token);
10165 if (dumpAll) {
10166 pw.println(':');
10167 token.dump(pw, " ");
10168 } else {
10169 pw.println();
10170 }
10171 }
10172 }
10173 if (mWallpaperTokens.size() > 0) {
10174 pw.println();
10175 pw.println(" Wallpaper tokens:");
10176 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
10177 WindowToken token = mWallpaperTokens.get(i);
10178 pw.print(" Wallpaper #"); pw.print(i);
10179 pw.print(' '); pw.print(token);
10180 if (dumpAll) {
10181 pw.println(':');
10182 token.dump(pw, " ");
10183 } else {
10184 pw.println();
10185 }
10186 }
10187 }
10188 if (mAppTokens.size() > 0) {
10189 pw.println();
10190 pw.println(" Application tokens in Z order:");
10191 for (int i=mAppTokens.size()-1; i>=0; i--) {
Craig Mautnerdbb79912012-03-01 18:59:14 -080010192 pw.print(" App #"); pw.print(i); pw.println(": ");
10193 mAppTokens.get(i).dump(pw, " ");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010194 }
10195 }
10196 if (mFinishedStarting.size() > 0) {
10197 pw.println();
10198 pw.println(" Finishing start of application tokens:");
10199 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
10200 WindowToken token = mFinishedStarting.get(i);
10201 pw.print(" Finished Starting #"); pw.print(i);
10202 pw.print(' '); pw.print(token);
10203 if (dumpAll) {
10204 pw.println(':');
10205 token.dump(pw, " ");
10206 } else {
10207 pw.println();
10208 }
10209 }
10210 }
10211 if (mExitingTokens.size() > 0) {
10212 pw.println();
10213 pw.println(" Exiting tokens:");
10214 for (int i=mExitingTokens.size()-1; i>=0; i--) {
10215 WindowToken token = mExitingTokens.get(i);
10216 pw.print(" Exiting #"); pw.print(i);
10217 pw.print(' '); pw.print(token);
10218 if (dumpAll) {
10219 pw.println(':');
10220 token.dump(pw, " ");
10221 } else {
10222 pw.println();
10223 }
10224 }
10225 }
10226 if (mExitingAppTokens.size() > 0) {
10227 pw.println();
10228 pw.println(" Exiting application tokens:");
10229 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
10230 WindowToken token = mExitingAppTokens.get(i);
10231 pw.print(" Exiting App #"); pw.print(i);
10232 pw.print(' '); pw.print(token);
10233 if (dumpAll) {
10234 pw.println(':');
10235 token.dump(pw, " ");
10236 } else {
10237 pw.println();
10238 }
10239 }
10240 }
Craig Mautneref25d7a2012-05-15 23:01:47 -070010241 if (mAppTransitionRunning && mAnimatingAppTokens.size() > 0) {
10242 pw.println();
10243 pw.println(" Application tokens during animation:");
10244 for (int i=mAnimatingAppTokens.size()-1; i>=0; i--) {
10245 WindowToken token = mAnimatingAppTokens.get(i);
10246 pw.print(" App moving to bottom #"); pw.print(i);
10247 pw.print(' '); pw.print(token);
10248 if (dumpAll) {
10249 pw.println(':');
10250 token.dump(pw, " ");
10251 } else {
10252 pw.println();
10253 }
10254 }
10255 }
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010256 if (mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
10257 pw.println();
10258 if (mOpeningApps.size() > 0) {
10259 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
10260 }
10261 if (mClosingApps.size() > 0) {
10262 pw.print(" mClosingApps="); pw.println(mClosingApps);
10263 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010264 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010265 }
10266
Jeff Brownd7a04de2012-06-17 14:17:52 -070010267 void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010268 pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
10269 if (mSessions.size() > 0) {
10270 Iterator<Session> it = mSessions.iterator();
10271 while (it.hasNext()) {
10272 Session s = it.next();
10273 pw.print(" Session "); pw.print(s); pw.println(':');
10274 s.dump(pw, " ");
10275 }
10276 }
10277 }
10278
Jeff Brownd7a04de2012-06-17 14:17:52 -070010279 void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010280 ArrayList<WindowState> windows) {
10281 pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010282 dumpWindowsNoHeaderLocked(pw, dumpAll, windows);
10283 }
10284
10285 void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll,
10286 ArrayList<WindowState> windows) {
Craig Mautner59c00972012-07-30 12:10:24 -070010287 int j = 0;
10288 final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
10289 while (iterator.hasNext()) {
10290 final WindowState w = iterator.next();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010291 if (windows == null || windows.contains(w)) {
Craig Mautner59c00972012-07-30 12:10:24 -070010292 pw.print(" Window #"); pw.print(j++); pw.print(' ');
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010293 pw.print(w); pw.println(":");
Dianne Hackborn89620282011-09-11 12:47:45 -070010294 w.dump(pw, " ", dumpAll || windows != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010295 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010296 }
10297 if (mInputMethodDialogs.size() > 0) {
10298 pw.println();
10299 pw.println(" Input method dialogs:");
10300 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
10301 WindowState w = mInputMethodDialogs.get(i);
10302 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010303 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010304 }
10305 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010306 }
10307 if (mPendingRemove.size() > 0) {
10308 pw.println();
10309 pw.println(" Remove pending for:");
10310 for (int i=mPendingRemove.size()-1; i>=0; i--) {
10311 WindowState w = mPendingRemove.get(i);
10312 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010313 pw.print(" Remove #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010314 pw.print(w);
10315 if (dumpAll) {
10316 pw.println(":");
10317 w.dump(pw, " ", true);
10318 } else {
10319 pw.println();
10320 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010321 }
10322 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010323 }
10324 if (mForceRemoves != null && mForceRemoves.size() > 0) {
10325 pw.println();
10326 pw.println(" Windows force removing:");
10327 for (int i=mForceRemoves.size()-1; i>=0; i--) {
10328 WindowState w = mForceRemoves.get(i);
10329 pw.print(" Removing #"); pw.print(i); pw.print(' ');
10330 pw.print(w);
10331 if (dumpAll) {
10332 pw.println(":");
10333 w.dump(pw, " ", true);
10334 } else {
10335 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010336 }
10337 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010338 }
10339 if (mDestroySurface.size() > 0) {
10340 pw.println();
10341 pw.println(" Windows waiting to destroy their surface:");
10342 for (int i=mDestroySurface.size()-1; i>=0; i--) {
10343 WindowState w = mDestroySurface.get(i);
10344 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010345 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010346 pw.print(w);
10347 if (dumpAll) {
10348 pw.println(":");
10349 w.dump(pw, " ", true);
10350 } else {
10351 pw.println();
10352 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010353 }
10354 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010355 }
10356 if (mLosingFocus.size() > 0) {
10357 pw.println();
10358 pw.println(" Windows losing focus:");
10359 for (int i=mLosingFocus.size()-1; i>=0; i--) {
10360 WindowState w = mLosingFocus.get(i);
10361 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010362 pw.print(" Losing #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010363 pw.print(w);
10364 if (dumpAll) {
10365 pw.println(":");
10366 w.dump(pw, " ", true);
10367 } else {
10368 pw.println();
10369 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010370 }
10371 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010372 }
10373 if (mResizingWindows.size() > 0) {
10374 pw.println();
10375 pw.println(" Windows waiting to resize:");
10376 for (int i=mResizingWindows.size()-1; i>=0; i--) {
10377 WindowState w = mResizingWindows.get(i);
10378 if (windows == null || windows.contains(w)) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010379 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010380 pw.print(w);
10381 if (dumpAll) {
10382 pw.println(":");
10383 w.dump(pw, " ", true);
10384 } else {
10385 pw.println();
10386 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010387 }
10388 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010389 }
Dianne Hackborn38e29a62011-09-18 14:43:08 -070010390 if (mWaitingForDrawn.size() > 0) {
10391 pw.println();
10392 pw.println(" Clients waiting for these windows to be drawn:");
10393 for (int i=mWaitingForDrawn.size()-1; i>=0; i--) {
10394 Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(i);
10395 pw.print(" Waiting #"); pw.print(i); pw.print(' '); pw.print(pair.first);
10396 pw.print(": "); pw.println(pair.second);
10397 }
10398 }
Craig Mautnera91f9e22012-09-14 16:22:08 -070010399 pw.println(" DisplayContents");
Jeff Browne215f262012-09-10 16:01:14 -070010400 if (mDisplayReady) {
Craig Mautner59c00972012-07-30 12:10:24 -070010401 DisplayContentsIterator dCIterator = new DisplayContentsIterator();
10402 while (dCIterator.hasNext()) {
Craig Mautnera91f9e22012-09-14 16:22:08 -070010403 dCIterator.next().dump(" ", pw);
Craig Mautner59c00972012-07-30 12:10:24 -070010404 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010405 } else {
10406 pw.println(" NO DISPLAY");
10407 }
10408 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
10409 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
10410 if (mLastFocus != mCurrentFocus) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010411 pw.print(" mLastFocus="); pw.println(mLastFocus);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010412 }
10413 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
10414 if (mInputMethodTarget != null) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010415 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010416 }
10417 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
10418 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
10419 if (dumpAll) {
Dianne Hackborn85afd1b2012-05-13 13:31:06 -070010420 pw.print(" mSystemDecorRect="); pw.print(mSystemDecorRect.toShortString());
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070010421 pw.print(" mSystemDecorLayer="); pw.print(mSystemDecorLayer);
10422 pw.print(" mScreenRecr="); pw.println(mScreenRect.toShortString());
Dianne Hackborndf89e652011-10-06 22:35:11 -070010423 if (mLastStatusBarVisibility != 0) {
10424 pw.print(" mLastStatusBarVisibility=0x");
10425 pw.println(Integer.toHexString(mLastStatusBarVisibility));
10426 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010427 if (mInputMethodWindow != null) {
10428 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
10429 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -070010430 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -070010431 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
10432 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
10433 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
10434 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010435 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
10436 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
10437 if (mInputMethodAnimLayerAdjustment != 0 ||
10438 mWallpaperAnimLayerAdjustment != 0) {
10439 pw.print(" mInputMethodAnimLayerAdjustment=");
10440 pw.print(mInputMethodAnimLayerAdjustment);
10441 pw.print(" mWallpaperAnimLayerAdjustment=");
10442 pw.println(mWallpaperAnimLayerAdjustment);
10443 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010444 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
10445 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
Craig Mautner19d59bc2012-09-04 11:15:56 -070010446 if (needsLayout()) {
10447 pw.print(" layoutNeeded on displays=");
10448 DisplayContentsIterator dcIterator = new DisplayContentsIterator();
10449 while (dcIterator.hasNext()) {
10450 final DisplayContent displayContent = dcIterator.next();
10451 if (displayContent.layoutNeeded) {
10452 pw.print(displayContent.getDisplayId());
10453 }
10454 }
10455 pw.println();
10456 }
Craig Mautner69b08182012-09-05 13:07:13 -070010457 pw.print(" mTransactionSequence="); pw.println(mTransactionSequence);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010458 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -070010459 pw.print(" windows="); pw.print(mWindowsFreezingScreen);
10460 pw.print(" client="); pw.print(mClientFreezingScreen);
10461 pw.print(" apps="); pw.print(mAppsFreezingScreen);
10462 pw.print(" waitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010463 pw.print(" mRotation="); pw.print(mRotation);
Dianne Hackborndacea8c2011-04-21 17:26:39 -070010464 pw.print(" mAltOrientation="); pw.println(mAltOrientation);
Craig Mautnerf20588f2012-04-11 17:06:21 -070010465 pw.print(" mLastWindowForcedOrientation="); pw.print(mLastWindowForcedOrientation);
Dianne Hackbornbc7386c2011-06-06 17:27:54 -070010466 pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation);
Jeff Brown01a98dd2011-09-20 15:08:29 -070010467 pw.print(" mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
Dianne Hackborn4dcece82012-02-10 14:50:32 -080010468 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
10469 pw.print(" mTransitionWindowAnimationScale="); pw.print(mTransitionAnimationScale);
Chet Haasec38fa1f2012-02-01 16:37:46 -080010470 pw.print(" mAnimatorDurationScale="); pw.println(mAnimatorDurationScale);
Dianne Hackborn4dcece82012-02-10 14:50:32 -080010471 pw.print(" mTraversalScheduled="); pw.print(mTraversalScheduled);
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010472 pw.print(" mNextAppTransition=0x");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010473 pw.print(Integer.toHexString(mNextAppTransition));
Dianne Hackborn9d132642011-04-21 17:26:39 -070010474 pw.print(" mAppTransitionReady="); pw.println(mAppTransitionReady);
10475 pw.print(" mAppTransitionRunning="); pw.print(mAppTransitionRunning);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010476 pw.print(" mAppTransitionTimeout="); pw.println(mAppTransitionTimeout);
10477 if (mNextAppTransitionType != ActivityOptions.ANIM_NONE) {
10478 pw.print(" mNextAppTransitionType="); pw.println(mNextAppTransitionType);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010479 }
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010480 switch (mNextAppTransitionType) {
10481 case ActivityOptions.ANIM_CUSTOM:
10482 pw.print(" mNextAppTransitionPackage=");
Dianne Hackborn84375872012-06-01 19:03:50 -070010483 pw.println(mNextAppTransitionPackage);
10484 pw.print(" mNextAppTransitionEnter=0x");
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010485 pw.print(Integer.toHexString(mNextAppTransitionEnter));
10486 pw.print(" mNextAppTransitionExit=0x");
Dianne Hackborn84375872012-06-01 19:03:50 -070010487 pw.println(Integer.toHexString(mNextAppTransitionExit));
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010488 break;
10489 case ActivityOptions.ANIM_SCALE_UP:
10490 pw.print(" mNextAppTransitionStartX="); pw.print(mNextAppTransitionStartX);
10491 pw.print(" mNextAppTransitionStartY=");
10492 pw.println(mNextAppTransitionStartY);
10493 pw.print(" mNextAppTransitionStartWidth=");
10494 pw.print(mNextAppTransitionStartWidth);
10495 pw.print(" mNextAppTransitionStartHeight=");
10496 pw.println(mNextAppTransitionStartHeight);
10497 break;
Michael Jurka832cb222012-04-13 09:32:47 -070010498 case ActivityOptions.ANIM_THUMBNAIL_SCALE_UP:
10499 case ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN:
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010500 pw.print(" mNextAppTransitionThumbnail=");
10501 pw.print(mNextAppTransitionThumbnail);
Dianne Hackborn84375872012-06-01 19:03:50 -070010502 pw.print(" mNextAppTransitionStartX=");
10503 pw.print(mNextAppTransitionStartX);
10504 pw.print(" mNextAppTransitionStartY=");
10505 pw.println(mNextAppTransitionStartY);
Michael Jurka832cb222012-04-13 09:32:47 -070010506 pw.print(" mNextAppTransitionScaleUp="); pw.println(mNextAppTransitionScaleUp);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010507 break;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070010508 }
Dianne Hackborn84375872012-06-01 19:03:50 -070010509 if (mNextAppTransitionCallback != null) {
10510 pw.print(" mNextAppTransitionCallback=");
10511 pw.println(mNextAppTransitionCallback);
10512 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010513 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010514 pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Craig Mautner6fbda632012-07-03 09:26:39 -070010515 pw.println(" Window Animator:");
Craig Mautnera91f9e22012-09-14 16:22:08 -070010516 mAnimator.dumpLocked(pw, " ", dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010517 }
10518 }
10519
Jeff Brownd7a04de2012-06-17 14:17:52 -070010520 boolean dumpWindows(PrintWriter pw, String name, String[] args,
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010521 int opti, boolean dumpAll) {
Craig Mautner722285e2012-09-07 13:55:58 -070010522 WindowList windows = new WindowList();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010523 if ("visible".equals(name)) {
10524 synchronized(mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -070010525 final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
10526 while (iterator.hasNext()) {
10527 final WindowState w = iterator.next();
Craig Mautnerc2f9be02012-03-27 17:32:29 -070010528 if (w.mWinAnimator.mSurfaceShown) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010529 windows.add(w);
10530 }
10531 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010532 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010533 } else {
10534 int objectId = 0;
10535 // See if this is an object ID.
10536 try {
10537 objectId = Integer.parseInt(name, 16);
10538 name = null;
10539 } catch (RuntimeException e) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010540 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010541 synchronized(mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -070010542 final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
10543 while (iterator.hasNext()) {
10544 final WindowState w = iterator.next();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010545 if (name != null) {
10546 if (w.mAttrs.getTitle().toString().contains(name)) {
10547 windows.add(w);
10548 }
10549 } else if (System.identityHashCode(w) == objectId) {
10550 windows.add(w);
10551 }
10552 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010553 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010554 }
10555
10556 if (windows.size() <= 0) {
10557 return false;
10558 }
10559
10560 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010561 dumpWindowsLocked(pw, dumpAll, windows);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010562 }
10563 return true;
10564 }
10565
Jeff Brownd7a04de2012-06-17 14:17:52 -070010566 void dumpLastANRLocked(PrintWriter pw) {
10567 pw.println("WINDOW MANAGER LAST ANR (dumpsys window lastanr)");
10568 if (mLastANRState == null) {
10569 pw.println(" <no ANR has occurred since boot>");
10570 } else {
10571 pw.println(mLastANRState);
10572 }
10573 }
10574
10575 /**
10576 * Saves information about the state of the window manager at
10577 * the time an ANR occurred before anything else in the system changes
10578 * in response.
10579 *
Jeff Brownee172412012-06-18 12:58:03 -070010580 * @param appWindowToken The application that ANR'd, may be null.
Jeff Brownd7a04de2012-06-17 14:17:52 -070010581 * @param windowState The window that ANR'd, may be null.
10582 */
10583 public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState) {
10584 StringWriter sw = new StringWriter();
10585 PrintWriter pw = new PrintWriter(sw);
10586 pw.println(" ANR time: " + DateFormat.getInstance().format(new Date()));
Jeff Brownee172412012-06-18 12:58:03 -070010587 if (appWindowToken != null) {
10588 pw.println(" Application at fault: " + appWindowToken.stringName);
10589 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010590 if (windowState != null) {
10591 pw.println(" Window at fault: " + windowState.mAttrs.getTitle());
10592 }
10593 pw.println();
10594 dumpWindowsNoHeaderLocked(pw, true, null);
10595 pw.close();
10596 mLastANRState = sw.toString();
10597 }
10598
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010599 @Override
10600 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10601 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
10602 != PackageManager.PERMISSION_GRANTED) {
10603 pw.println("Permission Denial: can't dump WindowManager from from pid="
10604 + Binder.getCallingPid()
10605 + ", uid=" + Binder.getCallingUid());
10606 return;
10607 }
10608
10609 boolean dumpAll = false;
10610
10611 int opti = 0;
10612 while (opti < args.length) {
10613 String opt = args[opti];
10614 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10615 break;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010616 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010617 opti++;
10618 if ("-a".equals(opt)) {
10619 dumpAll = true;
10620 } else if ("-h".equals(opt)) {
10621 pw.println("Window manager dump options:");
10622 pw.println(" [-a] [-h] [cmd] ...");
10623 pw.println(" cmd may be one of:");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010624 pw.println(" l[astanr]: last ANR information");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010625 pw.println(" p[policy]: policy state");
10626 pw.println(" s[essions]: active sessions");
10627 pw.println(" t[okens]: token list");
10628 pw.println(" w[indows]: window list");
10629 pw.println(" cmd may also be a NAME to dump windows. NAME may");
10630 pw.println(" be a partial substring in a window name, a");
10631 pw.println(" Window hex object identifier, or");
10632 pw.println(" \"all\" for all windows, or");
10633 pw.println(" \"visible\" for the visible windows.");
10634 pw.println(" -a: include all available server state.");
10635 return;
Dianne Hackborn87fc3082010-12-03 13:09:12 -080010636 } else {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010637 pw.println("Unknown argument: " + opt + "; use -h for help");
Dianne Hackborn87fc3082010-12-03 13:09:12 -080010638 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010639 }
10640
10641 // Is the caller requesting to dump a particular piece of data?
10642 if (opti < args.length) {
10643 String cmd = args[opti];
10644 opti++;
Jeff Brownd7a04de2012-06-17 14:17:52 -070010645 if ("lastanr".equals(cmd) || "l".equals(cmd)) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010646 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010647 dumpLastANRLocked(pw);
10648 }
10649 return;
10650 } else if ("policy".equals(cmd) || "p".equals(cmd)) {
10651 synchronized(mWindowMap) {
10652 dumpPolicyLocked(pw, args, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010653 }
10654 return;
10655 } else if ("sessions".equals(cmd) || "s".equals(cmd)) {
10656 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010657 dumpSessionsLocked(pw, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010658 }
10659 return;
10660 } else if ("tokens".equals(cmd) || "t".equals(cmd)) {
10661 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010662 dumpTokensLocked(pw, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010663 }
10664 return;
10665 } else if ("windows".equals(cmd) || "w".equals(cmd)) {
10666 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010667 dumpWindowsLocked(pw, true, null);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010668 }
10669 return;
10670 } else if ("all".equals(cmd) || "a".equals(cmd)) {
10671 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010672 dumpWindowsLocked(pw, true, null);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010673 }
10674 return;
10675 } else {
10676 // Dumping a single name?
Jeff Brownd7a04de2012-06-17 14:17:52 -070010677 if (!dumpWindows(pw, cmd, args, opti, dumpAll)) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010678 pw.println("Bad window command, or no windows match: " + cmd);
10679 pw.println("Use -h for help.");
10680 }
10681 return;
10682 }
10683 }
10684
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010685 synchronized(mWindowMap) {
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010686 pw.println();
10687 if (dumpAll) {
10688 pw.println("-------------------------------------------------------------------------------");
10689 }
10690 dumpLastANRLocked(pw);
10691 pw.println();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010692 if (dumpAll) {
10693 pw.println("-------------------------------------------------------------------------------");
10694 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010695 dumpPolicyLocked(pw, args, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010696 pw.println();
10697 if (dumpAll) {
10698 pw.println("-------------------------------------------------------------------------------");
10699 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010700 dumpSessionsLocked(pw, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010701 pw.println();
10702 if (dumpAll) {
10703 pw.println("-------------------------------------------------------------------------------");
10704 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010705 dumpTokensLocked(pw, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010706 pw.println();
10707 if (dumpAll) {
10708 pw.println("-------------------------------------------------------------------------------");
10709 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010710 dumpWindowsLocked(pw, dumpAll, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010711 }
10712 }
10713
Jeff Brown349703e2010-06-22 01:27:15 -070010714 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010715 public void monitor() {
10716 synchronized (mWindowMap) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070010717 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010718
Jeff Brown2992ea72011-01-28 22:04:14 -080010719 public interface OnHardKeyboardStatusChangeListener {
10720 public void onHardKeyboardStatusChange(boolean available, boolean enabled);
10721 }
Craig Mautnera2c77052012-03-26 12:14:43 -070010722
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070010723 void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
Craig Mautnercf8cbbe2012-03-25 21:54:36 -070010724 if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070010725 Slog.v(TAG, "Layouts looping: " + msg + ", mPendingLayoutChanges = 0x" +
10726 Integer.toHexString(pendingLayoutChanges));
Craig Mautnercf8cbbe2012-03-25 21:54:36 -070010727 }
10728 }
Craig Mautner59c00972012-07-30 12:10:24 -070010729
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010730 public void createDisplayContentLocked(final Display display) {
Craig Mautner722285e2012-09-07 13:55:58 -070010731 if (display == null) {
10732 throw new IllegalArgumentException("getDisplayContent: display must not be null");
10733 }
10734 final DisplayContent displayContent = new DisplayContent(display);
10735 mDisplayContents.put(display.getDisplayId(), displayContent);
10736 }
10737
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010738 public DisplayContent getDisplayContentLocked(final int displayId) {
Craig Mautner59c00972012-07-30 12:10:24 -070010739 DisplayContent displayContent = mDisplayContents.get(displayId);
10740 if (displayContent == null) {
Jeff Brownbd6e1502012-08-28 03:27:37 -070010741 displayContent = new DisplayContent(mDisplayManager.getDisplay(displayId));
Craig Mautner59c00972012-07-30 12:10:24 -070010742 mDisplayContents.put(displayId, displayContent);
10743 }
10744 return displayContent;
10745 }
10746
10747 class DisplayContentsIterator implements Iterator<DisplayContent> {
10748 private int cur;
10749
10750 @Override
10751 public boolean hasNext() {
10752 return cur < mDisplayContents.size();
10753 }
10754
10755 @Override
10756 public DisplayContent next() {
10757 if (hasNext()) {
10758 return mDisplayContents.valueAt(cur++);
10759 }
10760 throw new NoSuchElementException();
10761 }
10762
10763 @Override
10764 public void remove() {
10765 throw new IllegalArgumentException("AllDisplayContentIterator.remove not implemented");
10766 }
10767 }
10768
Jeff Brown83d616a2012-09-09 20:33:43 -070010769 final static boolean REVERSE_ITERATOR = true;
Craig Mautner59c00972012-07-30 12:10:24 -070010770 class AllWindowsIterator implements Iterator<WindowState> {
10771 private DisplayContent mDisplayContent;
10772 private DisplayContentsIterator mDisplayContentsIterator;
10773 private WindowList mWindowList;
10774 private int mWindowListIndex;
10775 private boolean mReverse;
10776
10777 AllWindowsIterator() {
10778 mDisplayContentsIterator = new DisplayContentsIterator();
10779 mDisplayContent = mDisplayContentsIterator.next();
10780 mWindowList = mDisplayContent.getWindowList();
10781 }
10782
10783 AllWindowsIterator(boolean reverse) {
10784 this();
10785 mReverse = reverse;
10786 mWindowListIndex = reverse ? mWindowList.size() - 1 : 0;
10787 }
10788
10789 @Override
10790 public boolean hasNext() {
10791 if (mReverse) {
10792 return mWindowListIndex >= 0;
10793 }
10794 return mWindowListIndex < mWindowList.size();
10795 }
10796
10797 @Override
10798 public WindowState next() {
10799 if (hasNext()) {
10800 WindowState win = mWindowList.get(mWindowListIndex);
10801 if (mReverse) {
10802 mWindowListIndex--;
10803 if (mWindowListIndex < 0 && mDisplayContentsIterator.hasNext()) {
10804 mDisplayContent = mDisplayContentsIterator.next();
10805 mWindowList = mDisplayContent.getWindowList();
10806 mWindowListIndex = mWindowList.size() - 1;
10807 }
10808 } else {
10809 mWindowListIndex++;
Craig Mautnerb47bbc32012-08-22 17:41:48 -070010810 if (mWindowListIndex >= mWindowList.size()
10811 && mDisplayContentsIterator.hasNext()) {
Craig Mautner59c00972012-07-30 12:10:24 -070010812 mDisplayContent = mDisplayContentsIterator.next();
10813 mWindowList = mDisplayContent.getWindowList();
10814 mWindowListIndex = 0;
10815 }
10816 }
10817 return win;
10818 }
10819 throw new NoSuchElementException();
10820 }
10821
10822 @Override
10823 public void remove() {
10824 throw new IllegalArgumentException("AllWindowsIterator.remove not implemented");
10825 }
10826 }
10827
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010828 public DisplayContent getDefaultDisplayContentLocked() {
10829 return getDisplayContentLocked(Display.DEFAULT_DISPLAY);
Craig Mautner59c00972012-07-30 12:10:24 -070010830 }
10831
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010832 public WindowList getDefaultWindowListLocked() {
10833 return getDefaultDisplayContentLocked().getWindowList();
Craig Mautner59c00972012-07-30 12:10:24 -070010834 }
10835
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010836 public DisplayInfo getDefaultDisplayInfoLocked() {
10837 return getDefaultDisplayContentLocked().getDisplayInfo();
Craig Mautner59c00972012-07-30 12:10:24 -070010838 }
10839
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010840 public WindowList getWindowListLocked(final Display display) {
10841 return getDisplayContentLocked(display.getDisplayId()).getWindowList();
Craig Mautner39834192012-09-02 07:47:24 -070010842 }
Craig Mautner722285e2012-09-07 13:55:58 -070010843
10844 @Override
10845 public void onDisplayAdded(int displayId) {
10846 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_ADDED, displayId, 0));
10847 }
10848
10849 private void handleDisplayAddedLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010850 createDisplayContentLocked(mDisplayManager.getDisplay(displayId));
Craig Mautnera91f9e22012-09-14 16:22:08 -070010851 displayReady(displayId);
Craig Mautner722285e2012-09-07 13:55:58 -070010852 }
10853
10854 @Override
10855 public void onDisplayRemoved(int displayId) {
10856 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_REMOVED, displayId, 0));
10857 }
10858
10859 private void handleDisplayRemovedLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010860 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner722285e2012-09-07 13:55:58 -070010861 mDisplayContents.delete(displayId);
10862 WindowList windows = displayContent.getWindowList();
10863 for (int i = windows.size() - 1; i >= 0; --i) {
10864 final WindowState win = windows.get(i);
10865 removeWindowLocked(win.mSession, win);
10866 }
Craig Mautnera91f9e22012-09-14 16:22:08 -070010867 mAnimator.removeDisplayLocked(displayId);
Craig Mautner722285e2012-09-07 13:55:58 -070010868 }
10869
10870 @Override
10871 public void onDisplayChanged(int displayId) {
10872 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_CHANGED, displayId, 0));
10873 }
10874
10875 private void handleDisplayChangedLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010876 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner722285e2012-09-07 13:55:58 -070010877 if (displayContent != null) {
10878 displayContent.updateDisplayInfo();
10879 }
10880 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010881}