blob: e670028d2b3cb4f3082ee16172664e64dee98bba [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080017package com.android.server.wm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080019import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
20import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
Craig Mautner65d11b32012-10-01 13:59:52 -070021import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Dianne Hackborn5fd21692011-06-07 14:09:47 -070022import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
24import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070026import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
28import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
Craig Mautner65d11b32012-10-01 13:59:52 -070029import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
31import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Craig Mautner65d11b32012-10-01 13:59:52 -070032import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
Daniel Sandler7d276c32012-01-30 14:33:52 -050033import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
35import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
Craig Mautner65d11b32012-10-01 13:59:52 -070036import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD;
Craig Mautner88400d32012-09-30 12:35:45 -070037import static android.view.WindowManager.LayoutParams.TYPE_RECENTS_OVERLAY;
Craig Mautner65d11b32012-10-01 13:59:52 -070038import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
39import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070040import static android.view.WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070041import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042
43import com.android.internal.app.IBatteryStats;
44import com.android.internal.policy.PolicyManager;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080045import com.android.internal.policy.impl.PhoneWindowManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import com.android.internal.view.IInputContext;
47import com.android.internal.view.IInputMethodClient;
48import com.android.internal.view.IInputMethodManager;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080049import com.android.internal.view.WindowManagerPolicyThread;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080050import com.android.server.AttributeCache;
51import com.android.server.EventLogTags;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080052import com.android.server.Watchdog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053import com.android.server.am.BatteryStatsService;
Jeff Brownfa25bf52012-07-23 19:26:30 -070054import com.android.server.display.DisplayManagerService;
Jeff Brown4532e612012-04-05 14:27:12 -070055import com.android.server.input.InputManagerService;
Jeff Brown4f8ecd82012-06-18 18:29:13 -070056import com.android.server.power.PowerManagerService;
57import com.android.server.power.ShutdownThread;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058
59import android.Manifest;
60import android.app.ActivityManagerNative;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070061import android.app.ActivityOptions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import android.app.IActivityManager;
Joe Onoratoac0ee892011-01-30 15:38:30 -080063import android.app.StatusBarManager;
Jim Millerd6b57052010-06-07 17:52:42 -070064import android.app.admin.DevicePolicyManager;
Jeff Brownff7e6ef2012-08-15 02:05:18 -070065import android.animation.ValueAnimator;
Jim Miller284b62e2010-06-08 14:27:42 -070066import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import android.content.Context;
Jim Miller284b62e2010-06-08 14:27:42 -070068import android.content.Intent;
69import android.content.IntentFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070import android.content.pm.ActivityInfo;
71import android.content.pm.PackageManager;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070072import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.content.res.Configuration;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080074import android.graphics.Bitmap;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070075import android.graphics.Canvas;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076import android.graphics.Matrix;
77import android.graphics.PixelFormat;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -070078import android.graphics.Point;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079import android.graphics.Rect;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070080import android.graphics.RectF;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.graphics.Region;
Craig Mautnerb47bbc32012-08-22 17:41:48 -070082import android.hardware.display.DisplayManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083import android.os.Binder;
Dianne Hackborn75804932009-10-20 20:15:20 -070084import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085import android.os.Debug;
86import android.os.Handler;
87import android.os.IBinder;
Dianne Hackborn38e29a62011-09-18 14:43:08 -070088import android.os.IRemoteCallback;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089import android.os.Looper;
90import android.os.Message;
91import android.os.Parcel;
92import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093import android.os.PowerManager;
94import android.os.Process;
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -070095import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096import android.os.RemoteException;
97import android.os.ServiceManager;
Brad Fitzpatrickec062f62010-11-03 09:56:54 -070098import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099import android.os.SystemClock;
100import android.os.SystemProperties;
Dianne Hackborn1ded0b12012-04-26 14:14:50 -0700101import android.os.Trace;
Craig Mautner259328c2012-08-21 19:30:58 -0700102import android.os.WorkSource;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103import android.provider.Settings;
Dianne Hackborn723738c2009-06-25 19:48:04 -0700104import android.util.DisplayMetrics;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import android.util.EventLog;
Michael Jurka4accb6a2012-03-26 09:18:46 -0700106import android.util.FloatMath;
Jim Millerd6b57052010-06-07 17:52:42 -0700107import android.util.Log;
Craig Mautner59c00972012-07-30 12:10:24 -0700108import android.util.SparseArray;
Dianne Hackborn38e29a62011-09-18 14:43:08 -0700109import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800110import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111import android.util.SparseIntArray;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700112import android.util.TypedValue;
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800113import android.view.Choreographer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114import android.view.Display;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700115import android.view.DisplayInfo;
Adam Powelldfee59a2011-08-05 20:48:30 -0700116import android.view.Gravity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117import android.view.IApplicationToken;
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -0700118import android.view.IDisplayContentChangeListener;
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -0700119import android.view.IInputFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120import android.view.IOnKeyguardExitResult;
121import android.view.IRotationWatcher;
122import android.view.IWindow;
123import android.view.IWindowManager;
124import android.view.IWindowSession;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700125import android.view.InputChannel;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700126import android.view.InputDevice;
Jeff Brownbbda99d2010-07-28 15:48:59 -0700127import android.view.InputEvent;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800128import android.view.InputEventReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129import android.view.KeyEvent;
130import android.view.MotionEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131import android.view.Surface;
132import android.view.SurfaceSession;
133import android.view.View;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700134import android.view.ViewTreeObserver;
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -0700135import android.view.WindowInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136import android.view.WindowManager;
Jeff Brown98365d72012-08-19 20:30:52 -0700137import android.view.WindowManagerGlobal;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138import android.view.WindowManagerPolicy;
139import android.view.WindowManager.LayoutParams;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700140import android.view.WindowManagerPolicy.FakeWindow;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700141import android.view.animation.AlphaAnimation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142import android.view.animation.Animation;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700143import android.view.animation.AnimationSet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144import android.view.animation.AnimationUtils;
Michael Jurkac016aaa2012-06-05 17:22:24 -0700145import android.view.animation.DecelerateInterpolator;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700146import android.view.animation.Interpolator;
147import android.view.animation.ScaleAnimation;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700148import android.view.animation.Transformation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149
150import java.io.BufferedWriter;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700151import java.io.DataInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152import java.io.File;
153import java.io.FileDescriptor;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700154import java.io.FileInputStream;
155import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156import java.io.IOException;
157import java.io.OutputStream;
158import java.io.OutputStreamWriter;
159import java.io.PrintWriter;
160import java.io.StringWriter;
161import java.net.Socket;
Jeff Brownd7a04de2012-06-17 14:17:52 -0700162import java.text.DateFormat;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163import java.util.ArrayList;
Jeff Brownd7a04de2012-06-17 14:17:52 -0700164import java.util.Date;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165import java.util.HashMap;
166import java.util.HashSet;
167import java.util.Iterator;
168import java.util.List;
Craig Mautner59c00972012-07-30 12:10:24 -0700169import java.util.NoSuchElementException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170
171/** {@hide} */
Dianne Hackbornddca3ee2009-07-23 19:01:31 -0700172public class WindowManagerService extends IWindowManager.Stub
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700173 implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs,
Craig Mautner722285e2012-09-07 13:55:58 -0700174 DisplayManagerService.WindowManagerFuncs, DisplayManager.DisplayListener {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175 static final String TAG = "WindowManager";
176 static final boolean DEBUG = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700177 static final boolean DEBUG_ADD_REMOVE = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800178 static final boolean DEBUG_FOCUS = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179 static final boolean DEBUG_ANIM = false;
Dianne Hackborn9b52a212009-12-11 14:51:35 -0800180 static final boolean DEBUG_LAYOUT = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800181 static final boolean DEBUG_RESIZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 static final boolean DEBUG_LAYERS = false;
183 static final boolean DEBUG_INPUT = false;
184 static final boolean DEBUG_INPUT_METHOD = false;
185 static final boolean DEBUG_VISIBILITY = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700186 static final boolean DEBUG_WINDOW_MOVEMENT = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800187 static final boolean DEBUG_TOKEN_MOVEMENT = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188 static final boolean DEBUG_ORIENTATION = false;
Dianne Hackbornbc7386c2011-06-06 17:27:54 -0700189 static final boolean DEBUG_APP_ORIENTATION = false;
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700190 static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800191 static final boolean DEBUG_APP_TRANSITIONS = false;
192 static final boolean DEBUG_STARTING_WINDOW = false;
193 static final boolean DEBUG_REORDER = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800194 static final boolean DEBUG_WALLPAPER = false;
Christopher Tate994ef922011-01-12 20:06:07 -0800195 static final boolean DEBUG_DRAG = false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700196 static final boolean DEBUG_SCREEN_ON = false;
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -0700197 static final boolean DEBUG_SCREENSHOT = false;
Dianne Hackborn38cc8962011-10-13 11:33:55 -0700198 static final boolean DEBUG_BOOT = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700199 static final boolean DEBUG_LAYOUT_REPEATS = true;
Craig Mautner7358fbf2012-04-12 21:06:33 -0700200 static final boolean DEBUG_SURFACE_TRACE = false;
Craig Mautner7d8df392012-04-06 15:26:23 -0700201 static final boolean DEBUG_WINDOW_TRACE = false;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700202 static final boolean SHOW_SURFACE_ALLOC = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800203 static final boolean SHOW_TRANSACTIONS = false;
Dianne Hackborn36991742011-10-11 21:35:26 -0700204 static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700205 static final boolean HIDE_STACK_CRAWLS = true;
Craig Mautnercf8cbbe2012-03-25 21:54:36 -0700206 static final int LAYOUT_REPEAT_THRESHOLD = 4;
Michael Chan53071d62009-05-13 17:29:48 -0700207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208 static final boolean PROFILE_ORIENTATION = false;
Dave Bortcfe65242009-04-09 14:51:04 -0700209 static final boolean localLOGV = DEBUG;
Romain Guy06882f82009-06-10 13:36:04 -0700210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 /** How much to multiply the policy's type layer, to reserve room
212 * for multiple windows of the same type and Z-ordering adjustment
213 * with TYPE_LAYER_OFFSET. */
214 static final int TYPE_LAYER_MULTIPLIER = 10000;
Romain Guy06882f82009-06-10 13:36:04 -0700215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
217 * or below others in the same layer. */
218 static final int TYPE_LAYER_OFFSET = 1000;
Romain Guy06882f82009-06-10 13:36:04 -0700219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 /** How much to increment the layer for each window, to reserve room
221 * for effect surfaces between them.
222 */
223 static final int WINDOW_LAYER_MULTIPLIER = 5;
Romain Guy06882f82009-06-10 13:36:04 -0700224
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800225 /**
226 * Dim surface layer is immediately below target window.
227 */
228 static final int LAYER_OFFSET_DIM = 1;
229
230 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700231 * Blur surface layer is immediately below dim layer.
232 */
233 static final int LAYER_OFFSET_BLUR = 2;
234
235 /**
236 * Animation thumbnail is as far as possible below the window above
237 * the thumbnail (or in other words as far as possible above the window
238 * below it).
239 */
240 static final int LAYER_OFFSET_THUMBNAIL = WINDOW_LAYER_MULTIPLIER-1;
241
242 /**
Dianne Hackborn7916ac62011-05-16 20:45:48 -0700243 * Layer at which to put the rotation freeze snapshot.
244 */
245 static final int FREEZE_LAYER = (TYPE_LAYER_MULTIPLIER * 200) + 1;
246
247 /**
248 * Layer at which to put the mask for emulated screen sizes.
249 */
250 static final int MASK_LAYER = TYPE_LAYER_MULTIPLIER * 200;
251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 /** The maximum length we will accept for a loaded animation duration:
253 * this is 10 seconds.
254 */
255 static final int MAX_ANIMATION_DURATION = 10*1000;
256
257 /** Amount of time (in milliseconds) to animate the dim surface from one
258 * value to another, when no window animation is driving it.
259 */
260 static final int DEFAULT_DIM_DURATION = 200;
261
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700262 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
263 * compatible windows.
264 */
265 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
266
Dianne Hackborna1111872010-11-23 20:55:11 -0800267 /**
268 * If true, the window manager will do its own custom freezing and general
269 * management of the screen during rotation.
270 */
271 static final boolean CUSTOM_SCREEN_ROTATION = true;
272
Jeff Brownb09abc12011-01-13 21:08:27 -0800273 // Maximum number of milliseconds to wait for input devices to be enumerated before
274 // proceding with safe mode detection.
275 private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
Jim Miller28637ba2011-07-06 19:57:05 -0700276
Jeff Brown349703e2010-06-22 01:27:15 -0700277 // Default input dispatching timeout in nanoseconds.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800278 static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
Romain Guy06882f82009-06-10 13:36:04 -0700279
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 static final int UPDATE_FOCUS_NORMAL = 0;
281 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
282 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
283 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700286 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800287
Craig Mautner5642a482012-08-23 12:16:53 -0700288 final private KeyguardDisableHandler mKeyguardDisableHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700290 private final boolean mHeadless;
291
Michael Jurkac016aaa2012-06-05 17:22:24 -0700292 private static final float THUMBNAIL_ANIMATION_DECELERATE_FACTOR = 1.5f;
293
Jim Miller284b62e2010-06-08 14:27:42 -0700294 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
295 @Override
296 public void onReceive(Context context, Intent intent) {
Craig Mautner9dc52bc2012-08-06 14:15:42 -0700297 final String action = intent.getAction();
298 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
Craig Mautner5642a482012-08-23 12:16:53 -0700299 mKeyguardDisableHandler.sendEmptyMessage(
300 KeyguardDisableHandler.KEYGUARD_POLICY_CHANGED);
Jim Miller284b62e2010-06-08 14:27:42 -0700301 }
302 }
303 };
304
Craig Mautner9dc52bc2012-08-06 14:15:42 -0700305 // Current user when multi-user is enabled. Don't show windows of non-current user.
306 int mCurrentUserId;
307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308 final Context mContext;
309
310 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700311
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700312 final boolean mAllowBootMessages;
313
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
317
318 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700319
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 /**
323 * All currently active sessions with clients.
324 */
325 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 /**
328 * Mapping from an IWindow IBinder to the server's Window object.
329 * This is also used as the lock for all of our state.
330 */
331 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
332
333 /**
334 * Mapping from a token IBinder to a WindowToken object.
335 */
336 final HashMap<IBinder, WindowToken> mTokenMap =
337 new HashMap<IBinder, WindowToken>();
338
339 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 * Window tokens that are in the process of exiting, but still
341 * on screen for animations.
342 */
343 final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
344
345 /**
Craig Mautneref25d7a2012-05-15 23:01:47 -0700346 * List controlling the ordering of windows in different applications which must
347 * be kept in sync with ActivityManager.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800348 */
Craig Mautnerbec53f72012-04-05 11:49:05 -0700349 final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800350
351 /**
Craig Mautneref25d7a2012-05-15 23:01:47 -0700352 * AppWindowTokens in the Z order they were in at the start of an animation. Between
353 * animations this list is maintained in the exact order of mAppTokens. If tokens
354 * are added to mAppTokens during an animation an attempt is made to insert them at the same
355 * logical location in this list. Note that this list is always in sync with mWindows.
356 */
357 ArrayList<AppWindowToken> mAnimatingAppTokens = new ArrayList<AppWindowToken>();
358
359 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360 * Application tokens that are in the process of exiting, but still
361 * on screen for animations.
362 */
363 final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
364
365 /**
366 * List of window tokens that have finished starting their application,
367 * and now need to have the policy remove their windows.
368 */
369 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
370
371 /**
Dianne Hackborndf89e652011-10-06 22:35:11 -0700372 * Fake windows added to the window manager. Note: ordered from top to
373 * bottom, opposite of mWindows.
374 */
375 final ArrayList<FakeWindowImpl> mFakeWindows = new ArrayList<FakeWindowImpl>();
376
377 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378 * Windows that are being resized. Used so we can tell the client about
379 * the resize after closing the transaction in which we resized the
380 * underlying surface.
381 */
382 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
383
384 /**
385 * Windows whose animations have ended and now must be removed.
386 */
387 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
388
389 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800390 * Used when processing mPendingRemove to avoid working on the original array.
391 */
392 WindowState[] mPendingRemoveTmp = new WindowState[20];
393
394 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 * Windows whose surface should be destroyed.
396 */
397 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
398
399 /**
400 * Windows that have lost input focus and are waiting for the new
401 * focus window to be displayed before they are told about this.
402 */
403 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
404
405 /**
406 * This is set when we have run out of memory, and will either be an empty
407 * list or contain windows that need to be force removed.
408 */
409 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700410
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800411 /**
Dianne Hackborn38e29a62011-09-18 14:43:08 -0700412 * Windows that clients are waiting to have drawn.
413 */
414 ArrayList<Pair<WindowState, IRemoteCallback>> mWaitingForDrawn
415 = new ArrayList<Pair<WindowState, IRemoteCallback>>();
416
417 /**
Dianne Hackborn12d3a942012-04-27 14:16:30 -0700418 * Windows that have called relayout() while we were running animations,
419 * so we need to tell when the animation is done.
420 */
421 final ArrayList<WindowState> mRelayoutWhileAnimating = new ArrayList<WindowState>();
422
423 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800424 * Used when rebuilding window list to keep track of windows that have
425 * been removed.
426 */
427 WindowState[] mRebuildTmp = new WindowState[20];
428
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800429 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700430
Craig Mautner7358fbf2012-04-12 21:06:33 -0700431 final SurfaceSession mFxSession;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700432 Watermark mWatermark;
Brad Fitzpatrick68044332010-11-22 18:19:48 -0800433 StrictModeFlash mStrictModeFlash;
Romain Guy06882f82009-06-10 13:36:04 -0700434
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800435 final float[] mTmpFloats = new float[9];
436
Jeff Browne215f262012-09-10 16:01:14 -0700437 boolean mDisplayReady;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800438 boolean mSafeMode;
439 boolean mDisplayEnabled = false;
440 boolean mSystemBooted = false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700441 boolean mForceDisplayEnabled = false;
Dianne Hackborn661cd522011-08-22 00:26:20 -0700442 boolean mShowingBootMessages = false;
Dianne Hackborn1fbee792011-11-30 11:29:58 -0800443
Jeff Brownd7a04de2012-06-17 14:17:52 -0700444 String mLastANRState;
445
Craig Mautner59c00972012-07-30 12:10:24 -0700446 /** All DisplayDontents in the world, kept here */
447 private SparseArray<DisplayContent> mDisplayContents = new SparseArray<DisplayContent>();
Dianne Hackborn1fbee792011-11-30 11:29:58 -0800448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 int mRotation = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborndacea8c2011-04-21 17:26:39 -0700451 boolean mAltOrientation = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452 ArrayList<IRotationWatcher> mRotationWatchers
453 = new ArrayList<IRotationWatcher>();
Jeff Brown01a98dd2011-09-20 15:08:29 -0700454 int mDeferredRotationPauseCount;
Romain Guy06882f82009-06-10 13:36:04 -0700455
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700456 final Rect mSystemDecorRect = new Rect();
457 int mSystemDecorLayer = 0;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700458 final Rect mScreenRect = new Rect();
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700459
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800460 boolean mTraversalScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800461 boolean mDisplayFrozen = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800462 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800463 boolean mWindowsFreezingScreen = false;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700464 boolean mClientFreezingScreen = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465 int mAppsFreezingScreen = 0;
Dianne Hackbornbc7386c2011-06-06 17:27:54 -0700466 int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800467
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800468 int mLayoutSeq = 0;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700469
470 int mLastStatusBarVisibility = 0;
471
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800472 // State while inside of layoutAndPlaceSurfacesLocked().
473 boolean mFocusMayChange;
Craig Mautner01cd0e72012-06-18 10:19:11 -0700474
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800475 Configuration mCurConfiguration = new Configuration();
Craig Mautner01cd0e72012-06-18 10:19:11 -0700476
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800477 // This is held as long as we have the screen frozen, to give us time to
478 // perform a rotation animation when turning off shows the lock screen which
479 // changes the orientation.
480 PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800482 // State management of app transitions. When we are preparing for a
483 // transition, mNextAppTransition will be the kind of transition to
484 // perform or TRANSIT_NONE if we are not waiting. If we are waiting,
485 // mOpeningApps and mClosingApps are the lists of tokens that will be
486 // made visible or hidden at the next transition.
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700487 int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700488 int mNextAppTransitionType = ActivityOptions.ANIM_NONE;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700489 String mNextAppTransitionPackage;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700490 Bitmap mNextAppTransitionThumbnail;
Michael Jurka832cb222012-04-13 09:32:47 -0700491 // Used for thumbnail transitions. True if we're scaling up, false if scaling down
492 boolean mNextAppTransitionScaleUp;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700493 IRemoteCallback mNextAppTransitionCallback;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700494 int mNextAppTransitionEnter;
495 int mNextAppTransitionExit;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700496 int mNextAppTransitionStartX;
497 int mNextAppTransitionStartY;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700498 int mNextAppTransitionStartWidth;
499 int mNextAppTransitionStartHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800500 boolean mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -0700501 boolean mAppTransitionRunning = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502 boolean mAppTransitionTimeout = false;
503 boolean mStartingIconInTransition = false;
504 boolean mSkipAppTransitionAnimation = false;
505 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
506 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700507
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700508 boolean mIsTouchDevice;
509
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700510 final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Jeff Brownbc68a592011-07-25 12:58:12 -0700511 final DisplayMetrics mRealDisplayMetrics = new DisplayMetrics();
Dianne Hackborn48a76512011-06-08 21:51:44 -0700512 final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics();
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700513 final DisplayMetrics mCompatDisplayMetrics = new DisplayMetrics();
514
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800515 final H mH = new H();
516
517 final Choreographer mChoreographer = Choreographer.getInstance();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518
519 WindowState mCurrentFocus = null;
520 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700521
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800522 /** This just indicates the window the input method is on top of, not
523 * necessarily the window its input is going to. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524 WindowState mInputMethodTarget = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800525
526 /** If true hold off on modifying the animation layer of mInputMethodTarget */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800527 boolean mInputMethodTargetWaitingAnim;
528 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700529
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530 WindowState mInputMethodWindow = null;
531 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
532
Jeff Brown2992ea72011-01-28 22:04:14 -0800533 boolean mHardKeyboardAvailable;
534 boolean mHardKeyboardEnabled;
535 OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
536
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700537 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800538
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700539 // If non-null, this is the currently visible window that is associated
540 // with the wallpaper.
541 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700542 // If non-null, we are in the middle of animating from one wallpaper target
543 // to another, and this is the lower one in Z-order.
Craig Mautner918b53b2012-07-09 14:15:54 -0700544 private WindowState mLowerWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700545 // If non-null, we are in the middle of animating from one wallpaper target
546 // to another, and this is the higher one in Z-order.
Craig Mautner918b53b2012-07-09 14:15:54 -0700547 private WindowState mUpperWallpaperTarget = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700548 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700549 float mLastWallpaperX = -1;
550 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800551 float mLastWallpaperXStep = -1;
552 float mLastWallpaperYStep = -1;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700553 // This is set when we are waiting for a wallpaper to tell us it is done
554 // changing its scroll position.
555 WindowState mWaitingOnWallpaper;
556 // The last time we had a timeout when waiting for a wallpaper.
557 long mLastWallpaperTimeoutTime;
558 // We give a wallpaper up to 150ms to finish scrolling.
559 static final long WALLPAPER_TIMEOUT = 150;
560 // Time we wait after a timeout before trying to wait again.
561 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800562
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800563 AppWindowToken mFocusedApp = null;
564
565 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800567 float mWindowAnimationScale = 1.0f;
568 float mTransitionAnimationScale = 1.0f;
Chet Haasec38fa1f2012-02-01 16:37:46 -0800569 float mAnimatorDurationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700570
Jeff Brown4532e612012-04-05 14:27:12 -0700571 final InputManagerService mInputManager;
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700572 final DisplayManagerService mDisplayManagerService;
573 final DisplayManager mDisplayManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800574
575 // Who is holding the screen on.
576 Session mHoldingScreenOn;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700577 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700578
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700579 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800580
Christopher Tatea53146c2010-09-07 11:57:52 -0700581 DragState mDragState = null;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800582
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800583 /** Pulled out of performLayoutAndPlaceSurfacesLockedInner in order to refactor into multiple
584 * methods. */
Craig Mautnera608b882012-03-30 13:03:49 -0700585 class LayoutFields {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700586 static final int SET_UPDATE_ROTATION = 1 << 0;
587 static final int SET_WALLPAPER_MAY_CHANGE = 1 << 1;
588 static final int SET_FORCE_HIDING_CHANGED = 1 << 2;
Craig Mautner2639da52012-07-09 09:39:06 -0700589 static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3;
Craig Mautner7d8df392012-04-06 15:26:23 -0700590 static final int SET_TURN_ON_SCREEN = 1 << 4;
Craig Mautnera608b882012-03-30 13:03:49 -0700591
Craig Mautner764983d2012-03-22 11:37:36 -0700592 boolean mWallpaperForceHidingChanged = false;
593 boolean mWallpaperMayChange = false;
Craig Mautner764983d2012-03-22 11:37:36 -0700594 boolean mOrientationChangeComplete = true;
Craig Mautnere7ae2502012-03-26 17:11:19 -0700595 int mAdjResult = 0;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800596 private Session mHoldScreen = null;
597 private boolean mObscured = false;
Craig Mautner764983d2012-03-22 11:37:36 -0700598 boolean mDimming = false;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800599 private boolean mSyswin = false;
600 private float mScreenBrightness = -1;
601 private float mButtonBrightness = -1;
Jeff Brown1e3b98d2012-09-30 18:58:59 -0700602 private long mUserActivityTimeout = -1;
Craig Mautnera608b882012-03-30 13:03:49 -0700603 private boolean mUpdateRotation = false;
Craig Mautner65d11b32012-10-01 13:59:52 -0700604
605 private static final int DISPLAY_CONTENT_UNKNOWN = 0;
606 private static final int DISPLAY_CONTENT_MIRROR = 1;
607 private static final int DISPLAY_CONTENT_UNIQUE = 2;
608 private int mDisplayHasContent = DISPLAY_CONTENT_UNKNOWN;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800609 }
Craig Mautner01cd0e72012-06-18 10:19:11 -0700610 final LayoutFields mInnerFields = new LayoutFields();
611
Craig Mautner322e4032012-07-13 13:35:20 -0700612 static class AppWindowAnimParams {
613 AppWindowAnimator mAppAnimator;
614 ArrayList<WindowStateAnimator> mWinAnimators;
615
616 public AppWindowAnimParams(final AppWindowAnimator appAnimator) {
617 mAppAnimator = appAnimator;
618
Craig Mautner5c0e78c2012-09-12 16:45:36 -0700619 final AppWindowToken atoken = appAnimator.mAppToken;
Craig Mautner322e4032012-07-13 13:35:20 -0700620 mWinAnimators = new ArrayList<WindowStateAnimator>();
Craig Mautner5c0e78c2012-09-12 16:45:36 -0700621 final int N = atoken.allAppWindows.size();
Craig Mautner322e4032012-07-13 13:35:20 -0700622 for (int i = 0; i < N; i++) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -0700623 mWinAnimators.add(atoken.allAppWindows.get(i).mWinAnimator);
Craig Mautner322e4032012-07-13 13:35:20 -0700624 }
625 }
626 }
627
Craig Mautner711f90a2012-07-03 18:43:52 -0700628 static class LayoutToAnimatorParams {
Craig Mautner322e4032012-07-13 13:35:20 -0700629 boolean mParamsModified;
630
Craig Mautner918b53b2012-07-09 14:15:54 -0700631 static final long WALLPAPER_TOKENS_CHANGED = 1 << 0;
632 long mChanges;
633
Craig Mautner711f90a2012-07-03 18:43:52 -0700634 boolean mAnimationScheduled;
Craig Mautnera91f9e22012-09-14 16:22:08 -0700635 SparseArray<WinAnimatorList> mWinAnimatorLists = new SparseArray<WinAnimatorList>();
Craig Mautner711f90a2012-07-03 18:43:52 -0700636 WindowState mWallpaperTarget;
Craig Mautner918b53b2012-07-09 14:15:54 -0700637 WindowState mLowerWallpaperTarget;
638 WindowState mUpperWallpaperTarget;
Craig Mautnera91f9e22012-09-14 16:22:08 -0700639 SparseArray<DimAnimator.Parameters> mDimParams = new SparseArray<DimAnimator.Parameters>();
Craig Mautner918b53b2012-07-09 14:15:54 -0700640 ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Craig Mautner322e4032012-07-13 13:35:20 -0700641 ArrayList<AppWindowAnimParams> mAppWindowAnimParams = new ArrayList<AppWindowAnimParams>();
Craig Mautner711f90a2012-07-03 18:43:52 -0700642 }
Craig Mautner918b53b2012-07-09 14:15:54 -0700643 /** Params from WindowManagerService to WindowAnimator. Do not modify or read without first
644 * locking on either mWindowMap or mAnimator and then on mLayoutToAnim */
Craig Mautner711f90a2012-07-03 18:43:52 -0700645 final LayoutToAnimatorParams mLayoutToAnim = new LayoutToAnimatorParams();
Craig Mautner01cd0e72012-06-18 10:19:11 -0700646
647 /** The lowest wallpaper target with a detached wallpaper animation on it. */
648 WindowState mWindowDetachedWallpaper = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800649
Craig Mautner6fbda632012-07-03 09:26:39 -0700650 /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
651 * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
652 private int mTransactionSequence;
653
Craig Mautnerbb1449b2012-03-23 16:11:14 -0700654 /** Only do a maximum of 6 repeated layouts. After that quit */
655 private int mLayoutRepeatCount;
656
Craig Mautner764983d2012-03-22 11:37:36 -0700657 final WindowAnimator mAnimator;
Jeff Brown4a06c802012-02-15 15:06:01 -0800658
Jeff Brown32cbc38552011-12-01 14:01:49 -0800659 final class DragInputEventReceiver extends InputEventReceiver {
660 public DragInputEventReceiver(InputChannel inputChannel, Looper looper) {
661 super(inputChannel, looper);
662 }
663
Christopher Tatea53146c2010-09-07 11:57:52 -0700664 @Override
Jeff Brown32cbc38552011-12-01 14:01:49 -0800665 public void onInputEvent(InputEvent event) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700666 boolean handled = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700667 try {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800668 if (event instanceof MotionEvent
669 && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
Jeff Brown3915bb82010-11-05 15:02:16 -0700670 && mDragState != null) {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800671 final MotionEvent motionEvent = (MotionEvent)event;
Jeff Brown3915bb82010-11-05 15:02:16 -0700672 boolean endDrag = false;
Jeff Brown4952dfd2011-11-30 19:23:22 -0800673 final float newX = motionEvent.getRawX();
674 final float newY = motionEvent.getRawY();
Jeff Brown3915bb82010-11-05 15:02:16 -0700675
Jeff Brown4952dfd2011-11-30 19:23:22 -0800676 switch (motionEvent.getAction()) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700677 case MotionEvent.ACTION_DOWN: {
678 if (DEBUG_DRAG) {
679 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
680 }
681 } break;
682
683 case MotionEvent.ACTION_MOVE: {
684 synchronized (mWindowMap) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700685 // move the surface and tell the involved window(s) where we are
Christopher Tatea53146c2010-09-07 11:57:52 -0700686 mDragState.notifyMoveLw(newX, newY);
687 }
688 } break;
689
690 case MotionEvent.ACTION_UP: {
691 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
692 + newX + "," + newY);
693 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700694 endDrag = mDragState.notifyDropLw(newX, newY);
Christopher Tatea53146c2010-09-07 11:57:52 -0700695 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700696 } break;
697
698 case MotionEvent.ACTION_CANCEL: {
699 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
700 endDrag = true;
701 } break;
702 }
703
704 if (endDrag) {
705 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
706 // tell all the windows that the drag has ended
Chris Tate59943592010-10-11 20:33:44 -0700707 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700708 mDragState.endDragLw();
Chris Tate59943592010-10-11 20:33:44 -0700709 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700710 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700711
712 handled = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700713 }
714 } catch (Exception e) {
715 Slog.e(TAG, "Exception caught by drag handleMotion", e);
716 } finally {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800717 finishInputEvent(event, handled);
Christopher Tatea53146c2010-09-07 11:57:52 -0700718 }
719 }
Jeff Brown32cbc38552011-12-01 14:01:49 -0800720 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700721
722 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723 * Whether the UI is currently running in touch mode (not showing
724 * navigational focus because the user is directly pressing the screen).
725 */
Michael Jurkae99adc72011-08-11 18:28:01 -0700726 boolean mInTouchMode = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800727
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -0700728 // Temp regions for intermediary calculations.
729 private final Region mTempRegion = new Region();
730
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800731 private ViewServer mViewServer;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700732 private ArrayList<WindowChangeListener> mWindowChangeListeners =
733 new ArrayList<WindowChangeListener>();
734 private boolean mWindowsChanged = false;
735
736 public interface WindowChangeListener {
737 public void windowsChanged();
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -0700738 public void focusChanged();
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700739 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800740
Dianne Hackbornc485a602009-03-24 22:39:49 -0700741 final Configuration mTempConfiguration = new Configuration();
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700742
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700743 // The desired scaling factor for compatible apps.
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400744 float mCompatibleScreenScale;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700745
Jeff Brown780c46f2012-06-24 12:15:38 -0700746 // If true, only the core apps and services are being launched because the device
747 // is in a special boot mode, such as being encrypted or waiting for a decryption password.
748 // For example, when this flag is true, there will be no wallpaper service.
749 final boolean mOnlyCore;
750
Jeff Brownbd6e1502012-08-28 03:27:37 -0700751 public static WindowManagerService main(final Context context,
752 final PowerManagerService pm, final DisplayManagerService dm,
Jeff Browna9d131c2012-09-20 16:48:17 -0700753 final InputManagerService im,
Jeff Brownbd6e1502012-08-28 03:27:37 -0700754 final Handler uiHandler, final Handler wmHandler,
755 final boolean haveInputMethods, final boolean showBootMsgs,
756 final boolean onlyCore) {
757 final WindowManagerService[] holder = new WindowManagerService[1];
758 wmHandler.runWithScissors(new Runnable() {
759 @Override
760 public void run() {
Jeff Browna9d131c2012-09-20 16:48:17 -0700761 holder[0] = new WindowManagerService(context, pm, dm, im,
Jeff Brownbd6e1502012-08-28 03:27:37 -0700762 uiHandler, haveInputMethods, showBootMsgs, onlyCore);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800763 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700764 }, 0);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700765 return holder[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800766 }
Romain Guy06882f82009-06-10 13:36:04 -0700767
Jeff Brownbd6e1502012-08-28 03:27:37 -0700768 private void initPolicy(Handler uiHandler) {
769 uiHandler.runWithScissors(new Runnable() {
770 @Override
771 public void run() {
772 WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
Romain Guy06882f82009-06-10 13:36:04 -0700773
Jeff Brownbd6e1502012-08-28 03:27:37 -0700774 mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
775 mAnimator.mAboveUniverseLayer = mPolicy.getAboveUniverseLayer()
776 * TYPE_LAYER_MULTIPLIER
777 + TYPE_LAYER_OFFSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800778 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700779 }, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800780 }
781
782 private WindowManagerService(Context context, PowerManagerService pm,
Jeff Browna9d131c2012-09-20 16:48:17 -0700783 DisplayManagerService displayManager, InputManagerService inputManager,
784 Handler uiHandler,
Jeff Brown780c46f2012-06-24 12:15:38 -0700785 boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800786 mContext = context;
787 mHaveInputMethods = haveInputMethods;
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700788 mAllowBootMessages = showBootMsgs;
Jeff Brown780c46f2012-06-24 12:15:38 -0700789 mOnlyCore = onlyCore;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800790 mLimitedAlphaCompositing = context.getResources().getBoolean(
791 com.android.internal.R.bool.config_sf_limitedAlpha);
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700792 mDisplayManagerService = displayManager;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700793 mHeadless = displayManager.isHeadless();
Romain Guy06882f82009-06-10 13:36:04 -0700794
Craig Mautner722285e2012-09-07 13:55:58 -0700795 mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
796 mDisplayManager.registerDisplayListener(this, null);
797 Display[] displays = mDisplayManager.getDisplays();
798 for (Display display : displays) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -0700799 createDisplayContentLocked(display);
Craig Mautner722285e2012-09-07 13:55:58 -0700800 }
801
Craig Mautner5642a482012-08-23 12:16:53 -0700802 mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);
803
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800804 mPowerManager = pm;
805 mPowerManager.setPolicy(mPolicy);
806 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
807 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
808 "SCREEN_FROZEN");
809 mScreenFrozenLock.setReferenceCounted(false);
810
811 mActivityManager = ActivityManagerNative.getDefault();
812 mBatteryStats = BatteryStatsService.getService();
813
814 // Get persisted window scale setting
Jeff Sharkey6e2bee72012-10-01 13:39:08 -0700815 mWindowAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
816 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
817 mTransitionAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
818 Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
819 setAnimatorDurationScale(Settings.Global.getFloat(context.getContentResolver(),
820 Settings.Global.ANIMATOR_DURATION_SCALE, mTransitionAnimationScale));
Romain Guy06882f82009-06-10 13:36:04 -0700821
Jim Miller284b62e2010-06-08 14:27:42 -0700822 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
823 IntentFilter filter = new IntentFilter();
824 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
825 mContext.registerReceiver(mBroadcastReceiver, filter);
826
Dianne Hackbornb80395c2012-06-14 19:38:20 -0700827 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
Craig Mautner259328c2012-08-21 19:30:58 -0700828 | PowerManager.ON_AFTER_RELEASE, TAG);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700829 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830
Jeff Browna9d131c2012-09-20 16:48:17 -0700831 mInputManager = inputManager;
Craig Mautner9e809442012-06-22 17:13:04 -0700832 mFxSession = new SurfaceSession();
Craig Mautner918b53b2012-07-09 14:15:54 -0700833 mAnimator = new WindowAnimator(this);
Romain Guy06882f82009-06-10 13:36:04 -0700834
Jeff Brownbd6e1502012-08-28 03:27:37 -0700835 initPolicy(uiHandler);
Romain Guy06882f82009-06-10 13:36:04 -0700836
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800837 // Add ourself to the Watchdog monitors.
838 Watchdog.getInstance().addMonitor(this);
Craig Mautner7358fbf2012-04-12 21:06:33 -0700839
840 Surface.openTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700841 try {
842 createWatermarkInTransaction();
843 } finally {
844 Surface.closeTransaction();
845 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800846 }
847
Jeff Browna9d131c2012-09-20 16:48:17 -0700848 public InputMonitor getInputMonitor() {
849 return mInputMonitor;
Jeff Brown4532e612012-04-05 14:27:12 -0700850 }
851
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800852 @Override
853 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
854 throws RemoteException {
855 try {
856 return super.onTransact(code, data, reply, flags);
857 } catch (RuntimeException e) {
858 // The window manager only throws security exceptions, so let's
859 // log all others.
860 if (!(e instanceof SecurityException)) {
Dianne Hackborn89620282011-09-11 12:47:45 -0700861 Log.wtf(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800862 }
863 throw e;
864 }
865 }
866
Jeff Browne33348b2010-07-15 23:54:05 -0700867 private void placeWindowAfter(WindowState pos, WindowState window) {
Craig Mautner59c00972012-07-30 12:10:24 -0700868 final WindowList windows = pos.getWindowList();
869 final int i = windows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800870 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800871 TAG, "Adding window " + window + " at "
Craig Mautner59c00972012-07-30 12:10:24 -0700872 + (i+1) + " of " + windows.size() + " (after " + pos + ")");
873 windows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700874 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800875 }
876
Jeff Browne33348b2010-07-15 23:54:05 -0700877 private void placeWindowBefore(WindowState pos, WindowState window) {
Craig Mautner59c00972012-07-30 12:10:24 -0700878 final WindowList windows = pos.getWindowList();
879 final int i = windows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800880 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800881 TAG, "Adding window " + window + " at "
Craig Mautner59c00972012-07-30 12:10:24 -0700882 + i + " of " + windows.size() + " (before " + pos + ")");
883 windows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700884 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800885 }
886
887 //This method finds out the index of a window that has the same app token as
888 //win. used for z ordering the windows in mWindows
889 private int findIdxBasedOnAppTokens(WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -0700890 WindowList windows = win.getWindowList();
891 for(int j = windows.size() - 1; j >= 0; j--) {
892 WindowState wentry = windows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800893 if(wentry.mAppToken == win.mAppToken) {
894 return j;
895 }
896 }
897 return -1;
898 }
Romain Guy06882f82009-06-10 13:36:04 -0700899
Craig Mautnerefb735d2012-09-07 15:40:24 -0700900 /**
901 * Return the list of Windows from the passed token on the given Display.
902 * @param token The token with all the windows.
903 * @param displayContent The display we are interested in.
904 * @return List of windows from token that are on displayContent.
905 */
Craig Mautner69b08182012-09-05 13:07:13 -0700906 WindowList getTokenWindowsOnDisplay(WindowToken token, DisplayContent displayContent) {
907 final WindowList windowList = new WindowList();
908 final int count = token.windows.size();
909 for (int i = 0; i < count; i++) {
910 final WindowState win = token.windows.get(i);
911 if (win.mDisplayContent == displayContent) {
912 windowList.add(win);
913 }
914 }
915 return windowList;
916 }
917
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800918 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
919 final IWindow client = win.mClient;
920 final WindowToken token = win.mToken;
Craig Mautner69b08182012-09-05 13:07:13 -0700921 final DisplayContent displayContent = win.mDisplayContent;
Romain Guy06882f82009-06-10 13:36:04 -0700922
Craig Mautner59c00972012-07-30 12:10:24 -0700923 final WindowList windows = win.getWindowList();
924 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800925 final WindowState attached = win.mAttachedWindow;
926 int i;
Craig Mautner69b08182012-09-05 13:07:13 -0700927 WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800928 if (attached == null) {
Craig Mautner69b08182012-09-05 13:07:13 -0700929 int tokenWindowsPos = 0;
930 int windowListPos = tokenWindowList.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800931 if (token.appWindowToken != null) {
Craig Mautner69b08182012-09-05 13:07:13 -0700932 int index = windowListPos - 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 if (index >= 0) {
934 // If this application has existing windows, we
935 // simply place the new window on top of them... but
936 // keep the starting window on top.
937 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
938 // Base windows go behind everything else.
Craig Mautner69b08182012-09-05 13:07:13 -0700939 WindowState lowestWindow = tokenWindowList.get(0);
940 placeWindowBefore(lowestWindow, win);
941 tokenWindowsPos = token.windows.indexOf(lowestWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800942 } else {
943 AppWindowToken atoken = win.mAppToken;
Craig Mautner69b08182012-09-05 13:07:13 -0700944 WindowState lastWindow = tokenWindowList.get(index);
945 if (atoken != null && lastWindow == atoken.startingWindow) {
946 placeWindowBefore(lastWindow, win);
Craig Mautnerefb735d2012-09-07 15:40:24 -0700947 tokenWindowsPos = token.windows.indexOf(lastWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800948 } else {
Craig Mautner69b08182012-09-05 13:07:13 -0700949 int newIdx = findIdxBasedOnAppTokens(win);
950 //there is a window above this one associated with the same
951 //apptoken note that the window could be a floating window
952 //that was created later or a window at the top of the list of
953 //windows associated with this token.
954 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
955 Slog.v(TAG, "Adding window " + win + " at "
Craig Mautnerefb735d2012-09-07 15:40:24 -0700956 + (newIdx + 1) + " of " + N);
Romain Guy06882f82009-06-10 13:36:04 -0700957 }
Craig Mautnerefb735d2012-09-07 15:40:24 -0700958 windows.add(newIdx + 1, win);
959 if (newIdx < 0) {
960 // No window from token found on win's display.
961 tokenWindowsPos = 0;
962 } else {
963 tokenWindowsPos = token.windows.indexOf(windows.get(newIdx)) + 1;
964 }
Craig Mautner69b08182012-09-05 13:07:13 -0700965 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800966 }
967 }
968 } else {
Craig Mautner69b08182012-09-05 13:07:13 -0700969 // No windows from this token on this display
Joe Onorato8a9b2202010-02-26 18:56:32 -0800970 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800971 TAG, "Figuring out where to add app window "
972 + client.asBinder() + " (token=" + token + ")");
973 // Figure out where the window should go, based on the
974 // order of applications.
Craig Mautneref25d7a2012-05-15 23:01:47 -0700975 final int NA = mAnimatingAppTokens.size();
Jeff Browne33348b2010-07-15 23:54:05 -0700976 WindowState pos = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800977 for (i=NA-1; i>=0; i--) {
Craig Mautneref25d7a2012-05-15 23:01:47 -0700978 AppWindowToken t = mAnimatingAppTokens.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800979 if (t == token) {
980 i--;
981 break;
982 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800983
Dianne Hackborna8f60182009-09-01 19:01:50 -0700984 // We haven't reached the token yet; if this token
Craig Mautner69b08182012-09-05 13:07:13 -0700985 // is not going to the bottom and has windows on this display, we can
Dianne Hackborna8f60182009-09-01 19:01:50 -0700986 // use it as an anchor for when we do reach the token.
Craig Mautner69b08182012-09-05 13:07:13 -0700987 tokenWindowList = getTokenWindowsOnDisplay(t, win.mDisplayContent);
988 if (!t.sendingToBottom && tokenWindowList.size() > 0) {
989 pos = tokenWindowList.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800990 }
991 }
992 // We now know the index into the apps. If we found
993 // an app window above, that gives us the position; else
994 // we need to look some more.
995 if (pos != null) {
996 // Move behind any windows attached to this one.
Jeff Browne33348b2010-07-15 23:54:05 -0700997 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800998 if (atoken != null) {
Craig Mautner69b08182012-09-05 13:07:13 -0700999 tokenWindowList =
1000 getTokenWindowsOnDisplay(atoken, win.mDisplayContent);
1001 final int NC = tokenWindowList.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001002 if (NC > 0) {
Craig Mautner69b08182012-09-05 13:07:13 -07001003 WindowState bottom = tokenWindowList.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001004 if (bottom.mSubLayer < 0) {
1005 pos = bottom;
1006 }
1007 }
1008 }
1009 placeWindowBefore(pos, win);
1010 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -07001011 // Continue looking down until we find the first
Craig Mautner69b08182012-09-05 13:07:13 -07001012 // token that has windows on this display.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001013 while (i >= 0) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07001014 AppWindowToken t = mAnimatingAppTokens.get(i);
Craig Mautner69b08182012-09-05 13:07:13 -07001015 tokenWindowList = getTokenWindowsOnDisplay(t, win.mDisplayContent);
1016 final int NW = tokenWindowList.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001017 if (NW > 0) {
Craig Mautner69b08182012-09-05 13:07:13 -07001018 pos = tokenWindowList.get(NW-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001019 break;
1020 }
1021 i--;
1022 }
1023 if (pos != null) {
1024 // Move in front of any windows attached to this
1025 // one.
Jeff Browne33348b2010-07-15 23:54:05 -07001026 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001027 if (atoken != null) {
1028 final int NC = atoken.windows.size();
1029 if (NC > 0) {
1030 WindowState top = atoken.windows.get(NC-1);
1031 if (top.mSubLayer >= 0) {
1032 pos = top;
1033 }
1034 }
1035 }
1036 placeWindowAfter(pos, win);
1037 } else {
1038 // Just search for the start of this layer.
1039 final int myLayer = win.mBaseLayer;
1040 for (i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07001041 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001042 if (w.mBaseLayer > myLayer) {
1043 break;
1044 }
1045 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001046 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
1047 Slog.v(TAG, "Adding window " + win + " at "
1048 + i + " of " + N);
1049 }
Craig Mautner59c00972012-07-30 12:10:24 -07001050 windows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001051 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001052 }
1053 }
1054 }
1055 } else {
1056 // Figure out where window should go, based on layer.
1057 final int myLayer = win.mBaseLayer;
1058 for (i=N-1; i>=0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07001059 if (windows.get(i).mBaseLayer <= myLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001060 break;
1061 }
1062 }
Craig Mautner69b08182012-09-05 13:07:13 -07001063 i++;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001064 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001065 TAG, "Adding window " + win + " at "
1066 + i + " of " + N);
Craig Mautner59c00972012-07-30 12:10:24 -07001067 windows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001068 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001069 }
Craig Mautner59c00972012-07-30 12:10:24 -07001070
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001071 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001072 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001073 token.windows.add(tokenWindowsPos, win);
1074 }
1075
1076 } else {
1077 // Figure out this window's ordering relative to the window
1078 // it is attached to.
Craig Mautner69b08182012-09-05 13:07:13 -07001079 final int NA = tokenWindowList.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001080 final int sublayer = win.mSubLayer;
1081 int largestSublayer = Integer.MIN_VALUE;
1082 WindowState windowWithLargestSublayer = null;
1083 for (i=0; i<NA; i++) {
Craig Mautner69b08182012-09-05 13:07:13 -07001084 WindowState w = tokenWindowList.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001085 final int wSublayer = w.mSubLayer;
1086 if (wSublayer >= largestSublayer) {
1087 largestSublayer = wSublayer;
1088 windowWithLargestSublayer = w;
1089 }
1090 if (sublayer < 0) {
1091 // For negative sublayers, we go below all windows
1092 // in the same sublayer.
1093 if (wSublayer >= sublayer) {
1094 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001095 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001096 token.windows.add(i, win);
1097 }
Craig Mautner59c00972012-07-30 12:10:24 -07001098 placeWindowBefore(wSublayer >= 0 ? attached : w, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001099 break;
1100 }
1101 } else {
1102 // For positive sublayers, we go above all windows
1103 // in the same sublayer.
1104 if (wSublayer > sublayer) {
1105 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001106 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001107 token.windows.add(i, win);
1108 }
1109 placeWindowBefore(w, win);
1110 break;
1111 }
1112 }
1113 }
1114 if (i >= NA) {
1115 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001116 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001117 token.windows.add(win);
1118 }
1119 if (sublayer < 0) {
1120 placeWindowBefore(attached, win);
1121 } else {
1122 placeWindowAfter(largestSublayer >= 0
1123 ? windowWithLargestSublayer
1124 : attached,
1125 win);
1126 }
1127 }
1128 }
Romain Guy06882f82009-06-10 13:36:04 -07001129
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001130 if (win.mAppToken != null && addToToken) {
1131 win.mAppToken.allAppWindows.add(win);
1132 }
1133 }
Romain Guy06882f82009-06-10 13:36:04 -07001134
Craig Mautneref25d7a2012-05-15 23:01:47 -07001135 /** TODO(cmautner): Is this the same as {@link WindowState#canReceiveKeys()} */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001136 static boolean canBeImeTarget(WindowState w) {
1137 final int fl = w.mAttrs.flags
1138 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
Dianne Hackborne75d8722011-01-27 19:37:40 -08001139 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)
Craig Mautner65d11b32012-10-01 13:59:52 -07001140 || w.mAttrs.type == TYPE_APPLICATION_STARTING) {
Dianne Hackborne75d8722011-01-27 19:37:40 -08001141 if (DEBUG_INPUT_METHOD) {
1142 Slog.i(TAG, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
1143 if (!w.isVisibleOrAdding()) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07001144 Slog.i(TAG, " mSurface=" + w.mWinAnimator.mSurface
Dianne Hackborne75d8722011-01-27 19:37:40 -08001145 + " relayoutCalled=" + w.mRelayoutCalled + " viewVis=" + w.mViewVisibility
Dianne Hackbornac920872012-05-22 11:49:49 -07001146 + " policyVis=" + w.mPolicyVisibility
1147 + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim
1148 + " attachHid=" + w.mAttachedHidden
Dianne Hackborne75d8722011-01-27 19:37:40 -08001149 + " exiting=" + w.mExiting + " destroying=" + w.mDestroying);
1150 if (w.mAppToken != null) {
1151 Slog.i(TAG, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
1152 }
1153 }
1154 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001155 return w.isVisibleOrAdding();
1156 }
1157 return false;
1158 }
Romain Guy06882f82009-06-10 13:36:04 -07001159
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001160 /**
1161 * Dig through the WindowStates and find the one that the Input Method will target.
1162 * @param willMove
1163 * @return The index+1 in mWindows of the discovered target.
1164 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001165 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001166 // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
1167 // same display. Or even when the current IME/target are not on the same screen as the next
1168 // IME/target. For now only look for input windows on the main screen.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001169 WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07001170 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001171 WindowState w = null;
1172 int i = N;
1173 while (i > 0) {
1174 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07001175 w = windows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -07001176
Dianne Hackborne75d8722011-01-27 19:37:40 -08001177 if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG, "Checking window @" + i
1178 + " " + w + " fl=0x" + Integer.toHexString(w.mAttrs.flags));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001179 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001180 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -07001181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001182 // Yet more tricksyness! If this window is a "starting"
1183 // window, we do actually want to be on top of it, but
1184 // it is not -really- where input will go. So if the caller
1185 // is not actually looking to move the IME, look down below
1186 // for a real window to target...
1187 if (!willMove
Craig Mautner65d11b32012-10-01 13:59:52 -07001188 && w.mAttrs.type == TYPE_APPLICATION_STARTING
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001189 && i > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001190 WindowState wb = windows.get(i-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001191 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1192 i--;
1193 w = wb;
1194 }
1195 }
1196 break;
1197 }
1198 }
Romain Guy06882f82009-06-10 13:36:04 -07001199
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001200 // Now w is either mWindows[0] or an IME (or null if mWindows is empty).
1201
Dianne Hackborne75d8722011-01-27 19:37:40 -08001202 if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG, "Proposed new IME target: " + w);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001203
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001204 // Now, a special case -- if the last target's window is in the
1205 // process of exiting, and is above the new target, keep on the
1206 // last target to avoid flicker. Consider for example a Dialog with
1207 // the IME shown: when the Dialog is dismissed, we want to keep
1208 // the IME above it until it is completely gone so it doesn't drop
1209 // behind the dialog or its full-screen scrim.
Craig Mautner59c00972012-07-30 12:10:24 -07001210 final WindowState curTarget = mInputMethodTarget;
1211 if (curTarget != null && w != null
1212 && curTarget.isDisplayedLw()
1213 && curTarget.mExiting) {
1214 if (curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
1215 w = curTarget;
1216 i = windows.indexOf(w);
Dianne Hackborne75d8722011-01-27 19:37:40 -08001217 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Current target higher, switching to: " + w);
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001218 }
1219 }
Romain Guy06882f82009-06-10 13:36:04 -07001220
Joe Onorato8a9b2202010-02-26 18:56:32 -08001221 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001222 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -07001223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001224 if (willMove && w != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07001225 AppWindowToken token = curTarget == null ? null : curTarget.mAppToken;
1226 if (token != null) {
Romain Guy06882f82009-06-10 13:36:04 -07001227
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001228 // Now some fun for dealing with window animations that
1229 // modify the Z order. We need to look at all windows below
1230 // the current target that are in this app, finding the highest
1231 // visible one in layering.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001232 WindowState highestTarget = null;
1233 int highestPos = 0;
Craig Mautner59431632012-04-04 11:56:44 -07001234 if (token.mAppAnimator.animating || token.mAppAnimator.animation != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07001235 WindowList curWindows = curTarget.getWindowList();
1236 int pos = curWindows.indexOf(curTarget);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001237 while (pos >= 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001238 WindowState win = curWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001239 if (win.mAppToken != token) {
1240 break;
1241 }
1242 if (!win.mRemoved) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001243 if (highestTarget == null || win.mWinAnimator.mAnimLayer >
1244 highestTarget.mWinAnimator.mAnimLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001245 highestTarget = win;
1246 highestPos = pos;
1247 }
1248 }
1249 pos--;
1250 }
1251 }
Romain Guy06882f82009-06-10 13:36:04 -07001252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001253 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001254 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001255 + mNextAppTransition + " " + highestTarget
Craig Mautnera2c77052012-03-26 12:14:43 -07001256 + " animating=" + highestTarget.mWinAnimator.isAnimating()
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001257 + " layer=" + highestTarget.mWinAnimator.mAnimLayer
1258 + " new layer=" + w.mWinAnimator.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001259
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001260 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001261 // If we are currently setting up for an animation,
1262 // hold everything until we can find out what will happen.
1263 mInputMethodTargetWaitingAnim = true;
1264 mInputMethodTarget = highestTarget;
1265 return highestPos + 1;
Craig Mautnera2c77052012-03-26 12:14:43 -07001266 } else if (highestTarget.mWinAnimator.isAnimating() &&
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001267 highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001268 // If the window we are currently targeting is involved
1269 // with an animation, and it is on top of the next target
1270 // we will be over, then hold off on moving until
1271 // that is done.
Dianne Hackborne75d8722011-01-27 19:37:40 -08001272 mInputMethodTargetWaitingAnim = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001273 mInputMethodTarget = highestTarget;
1274 return highestPos + 1;
1275 }
1276 }
1277 }
1278 }
Romain Guy06882f82009-06-10 13:36:04 -07001279
Joe Onorato8a9b2202010-02-26 18:56:32 -08001280 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001281 if (w != null) {
1282 if (willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001283 if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to "
1284 + w + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001285 mInputMethodTarget = w;
Dianne Hackborne75d8722011-01-27 19:37:40 -08001286 mInputMethodTargetWaitingAnim = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001287 if (w.mAppToken != null) {
Craig Mautner59431632012-04-04 11:56:44 -07001288 setInputMethodAnimLayerAdjustment(w.mAppToken.mAppAnimator.animLayerAdjustment);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001289 } else {
1290 setInputMethodAnimLayerAdjustment(0);
1291 }
1292 }
1293 return i+1;
1294 }
1295 if (willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001296 if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to null."
1297 + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001298 mInputMethodTarget = null;
1299 setInputMethodAnimLayerAdjustment(0);
1300 }
1301 return -1;
1302 }
Romain Guy06882f82009-06-10 13:36:04 -07001303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001304 void addInputMethodWindowToListLocked(WindowState win) {
1305 int pos = findDesiredInputMethodWindowIndexLocked(true);
1306 if (pos >= 0) {
1307 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001308 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001309 TAG, "Adding input method window " + win + " at " + pos);
Craig Mautner59c00972012-07-30 12:10:24 -07001310 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001311 getDefaultWindowListLocked().add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001312 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001313 moveInputMethodDialogsLocked(pos+1);
1314 return;
1315 }
1316 win.mTargetAppToken = null;
1317 addWindowToListInOrderLocked(win, true);
1318 moveInputMethodDialogsLocked(pos);
1319 }
Romain Guy06882f82009-06-10 13:36:04 -07001320
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001321 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001322 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001323 mInputMethodAnimLayerAdjustment = adj;
1324 WindowState imw = mInputMethodWindow;
1325 if (imw != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001326 imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001327 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001328 + " anim layer: " + imw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001329 int wi = imw.mChildWindows.size();
1330 while (wi > 0) {
1331 wi--;
Jeff Browne33348b2010-07-15 23:54:05 -07001332 WindowState cw = imw.mChildWindows.get(wi);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001333 cw.mWinAnimator.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001334 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001335 + " anim layer: " + cw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001336 }
1337 }
1338 int di = mInputMethodDialogs.size();
1339 while (di > 0) {
1340 di --;
1341 imw = mInputMethodDialogs.get(di);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001342 imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001343 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001344 + " anim layer: " + imw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001345 }
1346 }
Romain Guy06882f82009-06-10 13:36:04 -07001347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001348 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -07001349 WindowList windows = win.getWindowList();
1350 int wpos = windows.indexOf(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001351 if (wpos >= 0) {
1352 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001353 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
Craig Mautner59c00972012-07-30 12:10:24 -07001354 windows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001355 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001356 int NC = win.mChildWindows.size();
1357 while (NC > 0) {
1358 NC--;
Jeff Browne33348b2010-07-15 23:54:05 -07001359 WindowState cw = win.mChildWindows.get(NC);
Craig Mautner59c00972012-07-30 12:10:24 -07001360 int cpos = windows.indexOf(cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001361 if (cpos >= 0) {
1362 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001363 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001364 + cpos + ": " + cw);
Craig Mautner59c00972012-07-30 12:10:24 -07001365 windows.remove(cpos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001366 }
1367 }
1368 }
1369 return interestingPos;
1370 }
Romain Guy06882f82009-06-10 13:36:04 -07001371
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001372 private void reAddWindowToListInOrderLocked(WindowState win) {
1373 addWindowToListInOrderLocked(win, false);
1374 // This is a hack to get all of the child windows added as well
1375 // at the right position. Child windows should be rare and
1376 // this case should be rare, so it shouldn't be that big a deal.
Craig Mautner59c00972012-07-30 12:10:24 -07001377 WindowList windows = win.getWindowList();
1378 int wpos = windows.indexOf(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001379 if (wpos >= 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001380 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos + ": " + win);
1381 windows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001382 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001383 reAddWindowLocked(wpos, win);
1384 }
1385 }
Romain Guy06882f82009-06-10 13:36:04 -07001386
Craig Mautner59c00972012-07-30 12:10:24 -07001387 void logWindowList(final WindowList windows, String prefix) {
1388 int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001389 while (N > 0) {
1390 N--;
Craig Mautner59c00972012-07-30 12:10:24 -07001391 Slog.v(TAG, prefix + "#" + N + ": " + windows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001392 }
1393 }
Romain Guy06882f82009-06-10 13:36:04 -07001394
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001395 void moveInputMethodDialogsLocked(int pos) {
1396 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001397
Craig Mautner59c00972012-07-30 12:10:24 -07001398 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001399 WindowList windows = getDefaultWindowListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001400 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001401 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001402 for (int i=0; i<N; i++) {
1403 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1404 }
1405 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001406 Slog.v(TAG, "Window list w/pos=" + pos);
Craig Mautner59c00972012-07-30 12:10:24 -07001407 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001408 }
Romain Guy06882f82009-06-10 13:36:04 -07001409
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001410 if (pos >= 0) {
1411 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
Craig Mautner59c00972012-07-30 12:10:24 -07001412 if (pos < windows.size()) {
1413 WindowState wp = windows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001414 if (wp == mInputMethodWindow) {
1415 pos++;
1416 }
1417 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001418 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001419 for (int i=0; i<N; i++) {
1420 WindowState win = dialogs.get(i);
1421 win.mTargetAppToken = targetAppToken;
1422 pos = reAddWindowLocked(pos, win);
1423 }
1424 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001425 Slog.v(TAG, "Final window list:");
Craig Mautner59c00972012-07-30 12:10:24 -07001426 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427 }
1428 return;
1429 }
1430 for (int i=0; i<N; i++) {
1431 WindowState win = dialogs.get(i);
1432 win.mTargetAppToken = null;
1433 reAddWindowToListInOrderLocked(win);
1434 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001435 Slog.v(TAG, "No IM target, final list:");
Craig Mautner59c00972012-07-30 12:10:24 -07001436 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001437 }
1438 }
1439 }
Romain Guy06882f82009-06-10 13:36:04 -07001440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001441 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1442 final WindowState imWin = mInputMethodWindow;
1443 final int DN = mInputMethodDialogs.size();
1444 if (imWin == null && DN == 0) {
1445 return false;
1446 }
Romain Guy06882f82009-06-10 13:36:04 -07001447
Craig Mautner59c00972012-07-30 12:10:24 -07001448 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001449 WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07001450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001451 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1452 if (imPos >= 0) {
1453 // In this case, the input method windows are to be placed
1454 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456 // First check to see if the input method windows are already
1457 // located here, and contiguous.
Craig Mautner59c00972012-07-30 12:10:24 -07001458 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001459 WindowState firstImWin = imPos < N
Craig Mautner59c00972012-07-30 12:10:24 -07001460 ? windows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001461
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001462 // Figure out the actual input method window that should be
1463 // at the bottom of their stack.
1464 WindowState baseImWin = imWin != null
1465 ? imWin : mInputMethodDialogs.get(0);
1466 if (baseImWin.mChildWindows.size() > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001467 WindowState cw = baseImWin.mChildWindows.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001468 if (cw.mSubLayer < 0) baseImWin = cw;
1469 }
Romain Guy06882f82009-06-10 13:36:04 -07001470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001471 if (firstImWin == baseImWin) {
1472 // The windows haven't moved... but are they still contiguous?
1473 // First find the top IM window.
1474 int pos = imPos+1;
1475 while (pos < N) {
Craig Mautner59c00972012-07-30 12:10:24 -07001476 if (!(windows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001477 break;
1478 }
1479 pos++;
1480 }
1481 pos++;
1482 // Now there should be no more input method windows above.
1483 while (pos < N) {
Craig Mautner59c00972012-07-30 12:10:24 -07001484 if ((windows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001485 break;
1486 }
1487 pos++;
1488 }
1489 if (pos >= N) {
1490 // All is good!
1491 return false;
1492 }
1493 }
Romain Guy06882f82009-06-10 13:36:04 -07001494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001495 if (imWin != null) {
1496 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001497 Slog.v(TAG, "Moving IM from " + imPos);
Craig Mautner59c00972012-07-30 12:10:24 -07001498 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001499 }
1500 imPos = tmpRemoveWindowLocked(imPos, imWin);
1501 if (DEBUG_INPUT_METHOD) {
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001502 Slog.v(TAG, "List after removing with new pos " + imPos + ":");
Craig Mautner59c00972012-07-30 12:10:24 -07001503 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001504 }
1505 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1506 reAddWindowLocked(imPos, imWin);
1507 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001508 Slog.v(TAG, "List after moving IM to " + imPos + ":");
Craig Mautner59c00972012-07-30 12:10:24 -07001509 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 }
1511 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1512 } else {
1513 moveInputMethodDialogsLocked(imPos);
1514 }
Romain Guy06882f82009-06-10 13:36:04 -07001515
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001516 } else {
1517 // In this case, the input method windows go in a fixed layer,
1518 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001519
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001521 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001522 tmpRemoveWindowLocked(0, imWin);
1523 imWin.mTargetAppToken = null;
1524 reAddWindowToListInOrderLocked(imWin);
1525 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001526 Slog.v(TAG, "List with no IM target:");
Craig Mautner59c00972012-07-30 12:10:24 -07001527 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001528 }
Craig Mautner01cd0e72012-06-18 10:19:11 -07001529 if (DN > 0) moveInputMethodDialogsLocked(-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001530 } else {
Craig Mautner01cd0e72012-06-18 10:19:11 -07001531 moveInputMethodDialogsLocked(-1);
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 }
Romain Guy06882f82009-06-10 13:36:04 -07001535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001536 if (needAssignLayers) {
Craig Mautner59c00972012-07-30 12:10:24 -07001537 assignLayersLocked(windows);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001538 }
Romain Guy06882f82009-06-10 13:36:04 -07001539
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001540 return true;
1541 }
Romain Guy06882f82009-06-10 13:36:04 -07001542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001543 void adjustInputMethodDialogsLocked() {
1544 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1545 }
Romain Guy06882f82009-06-10 13:36:04 -07001546
Dianne Hackborn25994b42009-09-04 14:21:19 -07001547 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Craig Mautnerad3a9bb2012-03-09 11:31:06 -08001548 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001549 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1550 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
Craig Mautner59431632012-04-04 11:56:44 -07001551 ? wallpaperTarget.mAppToken.mAppAnimator.animation : null)
Dianne Hackborn25994b42009-09-04 14:21:19 -07001552 + " upper=" + mUpperWallpaperTarget
1553 + " lower=" + mLowerWallpaperTarget);
1554 return (wallpaperTarget != null
1555 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
Craig Mautner59431632012-04-04 11:56:44 -07001556 && wallpaperTarget.mAppToken.mAppAnimator.animation != null)))
Dianne Hackborn25994b42009-09-04 14:21:19 -07001557 || mUpperWallpaperTarget != null
1558 || mLowerWallpaperTarget != null;
1559 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001560
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001561 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1562 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001563
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001564 int adjustWallpaperWindowsLocked() {
Craig Mautnera608b882012-03-30 13:03:49 -07001565 mInnerFields.mWallpaperMayChange = false;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001566 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001567
Craig Mautner59c00972012-07-30 12:10:24 -07001568 // TODO(multidisplay): Wallpapers on main screen only.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001569 final DisplayInfo displayInfo = getDefaultDisplayContentLocked().getDisplayInfo();
Craig Mautner59c00972012-07-30 12:10:24 -07001570 final int dw = displayInfo.appWidth;
1571 final int dh = displayInfo.appHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001572
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001573 // First find top-most window that has asked to be on top of the
1574 // wallpaper; all wallpapers go behind it.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001575 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07001576 int N = windows.size();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001577 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001578 WindowState foundW = null;
1579 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001580 WindowState topCurW = null;
1581 int topCurI = 0;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001582 int windowDetachedI = -1;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001583 int i = N;
1584 while (i > 0) {
1585 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07001586 w = windows.get(i);
Craig Mautner65d11b32012-10-01 13:59:52 -07001587 if ((w.mAttrs.type == TYPE_WALLPAPER)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001588 if (topCurW == null) {
1589 topCurW = w;
1590 topCurI = i;
1591 }
1592 continue;
1593 }
1594 topCurW = null;
Craig Mautner01cd0e72012-06-18 10:19:11 -07001595 if (w != mWindowDetachedWallpaper && w.mAppToken != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001596 // If this window's app token is hidden and not animating,
1597 // it is of no interest to us.
Craig Mautner59431632012-04-04 11:56:44 -07001598 if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001599 if (DEBUG_WALLPAPER) Slog.v(TAG,
Craig Mautner1d961d42012-05-27 12:02:11 -07001600 "Skipping hidden and not animating token: " + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001601 continue;
1602 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001603 }
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001604 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win #" + i + " " + w + ": readyfordisplay="
Craig Mautner749a7bb2012-04-02 13:49:53 -07001605 + w.isReadyForDisplay() + " mDrawState=" + w.mWinAnimator.mDrawState);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001606 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07001607 && (mWallpaperTarget == w || w.isDrawnLw())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001608 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001609 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001610 foundW = w;
1611 foundI = i;
Craig Mautner4d7349b2012-04-20 14:52:47 -07001612 if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001613 // The current wallpaper target is animating, so we'll
1614 // look behind it for another possible target and figure
1615 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001616 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001617 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001618 continue;
1619 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001620 break;
Craig Mautner01cd0e72012-06-18 10:19:11 -07001621 } else if (w == mWindowDetachedWallpaper) {
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001622 windowDetachedI = i;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001623 }
1624 }
1625
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001626 if (foundW == null && windowDetachedI >= 0) {
1627 if (DEBUG_WALLPAPER) Slog.v(TAG,
1628 "Found animating detached wallpaper activity: #" + i + "=" + w);
1629 foundW = w;
1630 foundI = windowDetachedI;
1631 }
1632
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001633 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001634 // If we are currently waiting for an app transition, and either
1635 // the current target or the next target are involved with it,
1636 // then hold off on doing anything with the wallpaper.
1637 // Note that we are checking here for just whether the target
1638 // is part of an app token... which is potentially overly aggressive
1639 // (the app token may not be involved in the transition), but good
1640 // enough (we'll just wait until whatever transition is pending
1641 // executes).
1642 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001643 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001644 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001645 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001646 }
1647 if (foundW != null && foundW.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001648 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001649 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001650 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001651 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001652 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001653
Craig Mautner8863cca2012-09-18 15:04:34 -07001654 if (mWallpaperTarget != foundW
1655 && (mLowerWallpaperTarget == null || mLowerWallpaperTarget != foundW)) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001656 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001657 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001658 + " oldTarget: " + mWallpaperTarget);
1659 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001660
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001661 mLowerWallpaperTarget = null;
1662 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001663
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001664 WindowState oldW = mWallpaperTarget;
1665 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001666
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001667 // Now what is happening... if the current and new targets are
1668 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001669 if (foundW != null && oldW != null) {
Craig Mautnera2c77052012-03-26 12:14:43 -07001670 boolean oldAnim = oldW.mWinAnimator.mAnimation != null
Craig Mautner59431632012-04-04 11:56:44 -07001671 || (oldW.mAppToken != null
1672 && oldW.mAppToken.mAppAnimator.animation != null);
Craig Mautnera2c77052012-03-26 12:14:43 -07001673 boolean foundAnim = foundW.mWinAnimator.mAnimation != null
Craig Mautner59431632012-04-04 11:56:44 -07001674 || (foundW.mAppToken != null &&
1675 foundW.mAppToken.mAppAnimator.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001676 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001677 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001678 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001679 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001680 if (foundAnim && oldAnim) {
Craig Mautner59c00972012-07-30 12:10:24 -07001681 int oldI = windows.indexOf(oldW);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001682 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001683 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001684 }
1685 if (oldI >= 0) {
1686 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001687 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001688 + "=" + oldW + "; new#" + foundI
1689 + "=" + foundW);
1690 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001691
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001692 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001693 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001694 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001695 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001696 }
1697 mWallpaperTarget = oldW;
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001698 foundW = oldW;
1699 foundI = oldI;
Craig Mautner711f90a2012-07-03 18:43:52 -07001700 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001701 // Now set the upper and lower wallpaper targets
1702 // correctly, and make sure that we are positioning
1703 // the wallpaper below the lower.
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001704 else if (foundI > oldI) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001705 // The new target is on top of the old one.
1706 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001707 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001708 }
1709 mUpperWallpaperTarget = foundW;
1710 mLowerWallpaperTarget = oldW;
1711 foundW = oldW;
1712 foundI = oldI;
1713 } else {
1714 // The new target is below the old one.
1715 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001716 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001717 }
1718 mUpperWallpaperTarget = oldW;
1719 mLowerWallpaperTarget = foundW;
1720 }
1721 }
1722 }
1723 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001724
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001725 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001726 // Is it time to stop animating?
Craig Mautnera2c77052012-03-26 12:14:43 -07001727 boolean lowerAnimating = mLowerWallpaperTarget.mWinAnimator.mAnimation != null
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001728 || (mLowerWallpaperTarget.mAppToken != null
Craig Mautner59431632012-04-04 11:56:44 -07001729 && mLowerWallpaperTarget.mAppToken.mAppAnimator.animation != null);
Craig Mautnera2c77052012-03-26 12:14:43 -07001730 boolean upperAnimating = mUpperWallpaperTarget.mWinAnimator.mAnimation != null
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001731 || (mUpperWallpaperTarget.mAppToken != null
Craig Mautner59431632012-04-04 11:56:44 -07001732 && mUpperWallpaperTarget.mAppToken.mAppAnimator.animation != null);
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001733 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001734 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001735 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001736 }
1737 mLowerWallpaperTarget = null;
1738 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001739 }
1740 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001741
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001742 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001743 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001744 // The window is visible to the compositor... but is it visible
1745 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001746 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001747 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001748
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001749 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001750 // its layer adjustment. Only do this if we are not transfering
1751 // between two wallpaper targets.
1752 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001753 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Craig Mautner59431632012-04-04 11:56:44 -07001754 ? foundW.mAppToken.mAppAnimator.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001755
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001756 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1757 * TYPE_LAYER_MULTIPLIER
1758 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001759
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001760 // Now w is the window we are supposed to be behind... but we
1761 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001762 // AND any starting window associated with it, AND below the
1763 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001764 while (foundI > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001765 WindowState wb = windows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001766 if (wb.mBaseLayer < maxLayer &&
1767 wb.mAttachedWindow != foundW &&
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001768 (foundW.mAttachedWindow == null ||
1769 wb.mAttachedWindow != foundW.mAttachedWindow) &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001770 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001771 foundW.mToken == null || wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001772 // This window is not related to the previous one in any
1773 // interesting way, so stop here.
1774 break;
1775 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001776 foundW = wb;
1777 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001778 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001779 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001780 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001781 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001782
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001783 if (foundW == null && topCurW != null) {
1784 // There is no wallpaper target, so it goes at the bottom.
1785 // We will assume it is the same place as last time, if known.
1786 foundW = topCurW;
1787 foundI = topCurI+1;
1788 } else {
1789 // Okay i is the position immediately above the wallpaper. Look at
1790 // what is below it for later.
Craig Mautner59c00972012-07-30 12:10:24 -07001791 foundW = foundI > 0 ? windows.get(foundI-1) : null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001792 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001793
Dianne Hackborn284ac932009-08-28 10:34:25 -07001794 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001795 if (mWallpaperTarget.mWallpaperX >= 0) {
1796 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001797 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001798 }
1799 if (mWallpaperTarget.mWallpaperY >= 0) {
1800 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001801 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001802 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001803 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001804
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001805 // Start stepping backwards from here, ensuring that our wallpaper windows
1806 // are correctly placed.
1807 int curTokenIndex = mWallpaperTokens.size();
1808 while (curTokenIndex > 0) {
1809 curTokenIndex--;
1810 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001811 if (token.hidden == visible) {
1812 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1813 token.hidden = !visible;
1814 // Need to do a layout to ensure the wallpaper now has the
1815 // correct size.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001816 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001817 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001818
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001819 int curWallpaperIndex = token.windows.size();
1820 while (curWallpaperIndex > 0) {
1821 curWallpaperIndex--;
1822 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001823
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001824 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001825 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001826 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001827
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001828 // First, make sure the client has the current visibility
1829 // state.
Craig Mautner507a2ee2012-06-13 08:39:38 -07001830 dispatchWallpaperVisibility(wallpaper, visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001831
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001832 wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Craig Mautneref25d7a2012-05-15 23:01:47 -07001833 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "adjustWallpaper win "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001834 + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001835
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001836 // First, if this window is at the current index, then all
1837 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001838 if (wallpaper == foundW) {
1839 foundI--;
1840 foundW = foundI > 0
Craig Mautner59c00972012-07-30 12:10:24 -07001841 ? windows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001842 continue;
1843 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001844
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001845 // The window didn't match... the current wallpaper window,
1846 // wherever it is, is in the wrong place, so make sure it is
1847 // not in the list.
Craig Mautner59c00972012-07-30 12:10:24 -07001848 int oldIndex = windows.indexOf(wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001849 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001850 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001851 + oldIndex + ": " + wallpaper);
Craig Mautner59c00972012-07-30 12:10:24 -07001852 windows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001853 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001854 if (oldIndex < foundI) {
1855 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001856 }
1857 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001858
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001859 // Now stick it in.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001860 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
1861 Slog.v(TAG, "Moving wallpaper " + wallpaper
1862 + " from " + oldIndex + " to " + foundI);
1863 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001864
Craig Mautner59c00972012-07-30 12:10:24 -07001865 windows.add(foundI, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001866 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001867 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001868 }
1869 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001870
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001871 return changed;
1872 }
1873
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001874 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001875 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001876 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001877 mWallpaperAnimLayerAdjustment = adj;
1878 int curTokenIndex = mWallpaperTokens.size();
1879 while (curTokenIndex > 0) {
1880 curTokenIndex--;
1881 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1882 int curWallpaperIndex = token.windows.size();
1883 while (curWallpaperIndex > 0) {
1884 curWallpaperIndex--;
1885 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001886 wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + adj;
Craig Mautneref25d7a2012-05-15 23:01:47 -07001887 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "setWallpaper win "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001888 + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001889 }
1890 }
1891 }
1892
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001893 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
1894 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001895 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001896 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001897 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001898 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackbornffb3d932011-05-17 17:44:51 -07001899 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001900 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
1901 changed = wallpaperWin.mXOffset != offset;
1902 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001903 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001904 + wallpaperWin + " x: " + offset);
1905 wallpaperWin.mXOffset = offset;
1906 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001907 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001908 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001909 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001910 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001911 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001912
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001913 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001914 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001915 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1916 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1917 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001918 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001919 + wallpaperWin + " y: " + offset);
1920 changed = true;
1921 wallpaperWin.mYOffset = offset;
1922 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001923 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001924 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001925 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001926 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001927 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001928
Craig Mautnerbb1449b2012-03-23 16:11:14 -07001929 if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
Chet Haasea8e5a2b2011-10-28 13:18:16 -07001930 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001931 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001932 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001933 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
1934 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001935 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001936 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001937 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001938 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001939 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
1940 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001941 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001942 if (mWaitingOnWallpaper != null) {
1943 long start = SystemClock.uptimeMillis();
1944 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
1945 < start) {
1946 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001947 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07001948 "Waiting for offset complete...");
1949 mWindowMap.wait(WALLPAPER_TIMEOUT);
1950 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001951 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001952 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07001953 if ((start+WALLPAPER_TIMEOUT)
1954 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001955 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07001956 + wallpaperWin);
1957 mLastWallpaperTimeoutTime = start;
1958 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001959 }
Dianne Hackborn75804932009-10-20 20:15:20 -07001960 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001961 }
1962 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001963 } catch (RemoteException e) {
1964 }
1965 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001966
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001967 return changed;
1968 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001969
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001970 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001971 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001972 if (mWaitingOnWallpaper != null &&
1973 mWaitingOnWallpaper.mClient.asBinder() == window) {
1974 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07001975 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001976 }
1977 }
1978 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001979
Chet Haasea8e5a2b2011-10-28 13:18:16 -07001980 void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Craig Mautner59c00972012-07-30 12:10:24 -07001981 final DisplayContent displayContent = changingTarget.mDisplayContent;
1982 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
1983 final int dw = displayInfo.appWidth;
1984 final int dh = displayInfo.appHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001985
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001986 WindowState target = mWallpaperTarget;
1987 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001988 if (target.mWallpaperX >= 0) {
1989 mLastWallpaperX = target.mWallpaperX;
1990 } else if (changingTarget.mWallpaperX >= 0) {
1991 mLastWallpaperX = changingTarget.mWallpaperX;
1992 }
1993 if (target.mWallpaperY >= 0) {
1994 mLastWallpaperY = target.mWallpaperY;
1995 } else if (changingTarget.mWallpaperY >= 0) {
1996 mLastWallpaperY = changingTarget.mWallpaperY;
1997 }
1998 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001999
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002000 int curTokenIndex = mWallpaperTokens.size();
2001 while (curTokenIndex > 0) {
2002 curTokenIndex--;
2003 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2004 int curWallpaperIndex = token.windows.size();
2005 while (curWallpaperIndex > 0) {
2006 curWallpaperIndex--;
2007 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2008 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002009 WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
2010 winAnimator.computeShownFrameLocked();
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002011 // No need to lay out the windows - we can just set the wallpaper position
2012 // directly.
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07002013 // TODO(cmautner): Don't move this from here, just lock the WindowAnimator.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002014 if (winAnimator.mSurfaceX != wallpaper.mShownFrame.left
2015 || winAnimator.mSurfaceY != wallpaper.mShownFrame.top) {
Craig Mautner12670b52012-07-03 19:15:35 -07002016 winAnimator.setWallpaperOffset((int) wallpaper.mShownFrame.left,
Craig Mautner48ba1e72012-04-02 13:18:16 -07002017 (int) wallpaper.mShownFrame.top);
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002018 }
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002019 // We only want to be synchronous with one wallpaper.
2020 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002021 }
2022 }
2023 }
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002024 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002025
Craig Mautner507a2ee2012-06-13 08:39:38 -07002026 /**
2027 * Check wallpaper for visiblity change and notify window if so.
2028 * @param wallpaper The wallpaper to test and notify.
2029 * @param visible Current visibility.
2030 */
2031 void dispatchWallpaperVisibility(final WindowState wallpaper, final boolean visible) {
2032 if (wallpaper.mWallpaperVisible != visible) {
2033 wallpaper.mWallpaperVisible = visible;
2034 try {
2035 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
2036 "Updating visibility of wallpaper " + wallpaper
2037 + ": " + visible + " Callers=" + Debug.getCallers(2));
2038 wallpaper.mClient.dispatchAppVisibility(visible);
2039 } catch (RemoteException e) {
2040 }
2041 }
2042 }
2043
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002044 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07002045 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Craig Mautner59c00972012-07-30 12:10:24 -07002046 final DisplayContent displayContent = mWallpaperTarget.mDisplayContent;
2047 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
2048 final int dw = displayInfo.appWidth;
2049 final int dh = displayInfo.appHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002050
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002051 int curTokenIndex = mWallpaperTokens.size();
2052 while (curTokenIndex > 0) {
2053 curTokenIndex--;
2054 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002055 if (token.hidden == visible) {
2056 token.hidden = !visible;
2057 // Need to do a layout to ensure the wallpaper now has the
2058 // correct size.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07002059 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002060 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002061
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002062 int curWallpaperIndex = token.windows.size();
2063 while (curWallpaperIndex > 0) {
2064 curWallpaperIndex--;
2065 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2066 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002067 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002068 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002069
Craig Mautner507a2ee2012-06-13 08:39:38 -07002070 dispatchWallpaperVisibility(wallpaper, visible);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002071 }
2072 }
2073 }
Craig Mautner711f90a2012-07-03 18:43:52 -07002074
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002075 public int addWindow(Session session, IWindow client, int seq,
Craig Mautner6881a102012-07-27 13:04:51 -07002076 WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002077 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002078 int res = mPolicy.checkAddPermission(attrs);
Jeff Brown98365d72012-08-19 20:30:52 -07002079 if (res != WindowManagerGlobal.ADD_OKAY) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002080 return res;
2081 }
Romain Guy06882f82009-06-10 13:36:04 -07002082
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002083 boolean reportNewConfig = false;
2084 WindowState attachedWindow = null;
2085 WindowState win = null;
Dianne Hackborn5132b372010-07-29 12:51:35 -07002086 long origId;
Craig Mautner88400d32012-09-30 12:35:45 -07002087 final int type = attrs.type;
Romain Guy06882f82009-06-10 13:36:04 -07002088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002089 synchronized(mWindowMap) {
Jeff Browne215f262012-09-10 16:01:14 -07002090 if (!mDisplayReady) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07002091 throw new IllegalStateException("Display has not been initialialized");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002092 }
Romain Guy06882f82009-06-10 13:36:04 -07002093
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002094 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002095 Slog.w(TAG, "Window " + client + " is already added");
Jeff Brown98365d72012-08-19 20:30:52 -07002096 return WindowManagerGlobal.ADD_DUPLICATE_ADD;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002097 }
2098
Craig Mautner88400d32012-09-30 12:35:45 -07002099 if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002100 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002101 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002102 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002103 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002104 return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002105 }
2106 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
2107 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002108 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002109 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002110 return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002111 }
2112 }
2113
2114 boolean addToken = false;
2115 WindowToken token = mTokenMap.get(attrs.token);
2116 if (token == null) {
Craig Mautner88400d32012-09-30 12:35:45 -07002117 if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002118 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002119 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002120 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002121 }
Craig Mautner88400d32012-09-30 12:35:45 -07002122 if (type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002123 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002124 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002125 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002126 }
Craig Mautner88400d32012-09-30 12:35:45 -07002127 if (type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002128 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002129 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002130 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002131 }
Craig Mautner88400d32012-09-30 12:35:45 -07002132 if (type == TYPE_DREAM) {
Daniel Sandler7d276c32012-01-30 14:33:52 -05002133 Slog.w(TAG, "Attempted to add Dream window with unknown token "
2134 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002135 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Daniel Sandler7d276c32012-01-30 14:33:52 -05002136 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002137 token = new WindowToken(this, attrs.token, -1, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002138 addToken = true;
Craig Mautner88400d32012-09-30 12:35:45 -07002139 } else if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002140 AppWindowToken atoken = token.appWindowToken;
2141 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002142 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002143 + token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002144 return WindowManagerGlobal.ADD_NOT_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002145 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002146 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002147 + token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002148 return WindowManagerGlobal.ADD_APP_EXITING;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002149 }
Craig Mautner88400d32012-09-30 12:35:45 -07002150 if (type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002151 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002152 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002153 TAG, "**** NO NEED TO START: " + attrs.getTitle());
Jeff Brown98365d72012-08-19 20:30:52 -07002154 return WindowManagerGlobal.ADD_STARTING_NOT_NEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002155 }
Craig Mautner88400d32012-09-30 12:35:45 -07002156 } else if (type == TYPE_INPUT_METHOD) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002157 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002158 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002159 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002160 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002161 }
Craig Mautner88400d32012-09-30 12:35:45 -07002162 } else if (type == TYPE_WALLPAPER) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002163 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002164 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002165 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002166 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002167 }
Craig Mautner88400d32012-09-30 12:35:45 -07002168 } else if (type == TYPE_DREAM) {
Daniel Sandler7d276c32012-01-30 14:33:52 -05002169 if (token.windowType != TYPE_DREAM) {
2170 Slog.w(TAG, "Attempted to add Dream window with bad token "
2171 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002172 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Daniel Sandler7d276c32012-01-30 14:33:52 -05002173 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002174 }
2175
Craig Mautner5c0e78c2012-09-12 16:45:36 -07002176 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002177 win = new WindowState(this, session, client, token,
Craig Mautner59c00972012-07-30 12:10:24 -07002178 attachedWindow, seq, attrs, viewVisibility, displayContent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002179 if (win.mDeathRecipient == null) {
2180 // Client has apparently died, so there is no reason to
2181 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002182 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002183 + " that is dead, aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002184 return WindowManagerGlobal.ADD_APP_EXITING;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002185 }
2186
2187 mPolicy.adjustWindowParamsLw(win.mAttrs);
Craig Mautner88400d32012-09-30 12:35:45 -07002188 win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));
Romain Guy06882f82009-06-10 13:36:04 -07002189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002190 res = mPolicy.prepareAddWindowLw(win, attrs);
Jeff Brown98365d72012-08-19 20:30:52 -07002191 if (res != WindowManagerGlobal.ADD_OKAY) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002192 return res;
2193 }
Craig Mautner918b53b2012-07-09 14:15:54 -07002194
Jeff Browncc4f7db2011-08-30 20:34:48 -07002195 if (outInputChannel != null && (attrs.inputFeatures
2196 & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002197 String name = win.makeInputChannelName();
2198 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
Jeff Browncc4f7db2011-08-30 20:34:48 -07002199 win.setInputChannel(inputChannels[0]);
Jeff Brown0a0ab122011-08-12 18:08:08 -07002200 inputChannels[1].transferTo(outInputChannel);
Craig Mautner918b53b2012-07-09 14:15:54 -07002201
Jeff Brown928e0542011-01-10 11:17:36 -08002202 mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002203 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002204
2205 // From now on, no exceptions or errors allowed!
2206
Jeff Brown98365d72012-08-19 20:30:52 -07002207 res = WindowManagerGlobal.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002208
Dianne Hackborn5132b372010-07-29 12:51:35 -07002209 origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002211 if (addToken) {
2212 mTokenMap.put(attrs.token, token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002213 }
2214 win.attach();
2215 mWindowMap.put(client.asBinder(), win);
2216
Craig Mautner88400d32012-09-30 12:35:45 -07002217 if (type == TYPE_APPLICATION_STARTING && token.appWindowToken != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002218 token.appWindowToken.startingWindow = win;
Craig Mautner38b24782012-07-02 16:21:28 -07002219 if (DEBUG_STARTING_WINDOW) Slog.v (TAG, "addWindow: " + token.appWindowToken
2220 + " startingWindow=" + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002221 }
2222
2223 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002224
Craig Mautner88400d32012-09-30 12:35:45 -07002225 if (type == TYPE_INPUT_METHOD) {
satok1bc0a492012-04-25 22:47:12 +09002226 win.mGivenInsetsPending = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002227 mInputMethodWindow = win;
2228 addInputMethodWindowToListLocked(win);
2229 imMayMove = false;
Craig Mautner88400d32012-09-30 12:35:45 -07002230 } else if (type == TYPE_INPUT_METHOD_DIALOG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002231 mInputMethodDialogs.add(win);
2232 addWindowToListInOrderLocked(win, true);
2233 adjustInputMethodDialogsLocked();
2234 imMayMove = false;
2235 } else {
2236 addWindowToListInOrderLocked(win, true);
Craig Mautner88400d32012-09-30 12:35:45 -07002237 if (type == TYPE_WALLPAPER) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002238 mLastWallpaperTimeoutTime = 0;
2239 adjustWallpaperWindowsLocked();
2240 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002241 adjustWallpaperWindowsLocked();
2242 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002243 }
Romain Guy06882f82009-06-10 13:36:04 -07002244
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002245 win.mWinAnimator.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002246
Craig Mautner69b08182012-09-05 13:07:13 -07002247 if (displayContent.isDefaultDisplay) {
2248 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
2249 } else {
2250 outContentInsets.setEmpty();
2251 }
Romain Guy06882f82009-06-10 13:36:04 -07002252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002253 if (mInTouchMode) {
Jeff Brown98365d72012-08-19 20:30:52 -07002254 res |= WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002255 }
Craig Mautner764983d2012-03-22 11:37:36 -07002256 if (win.mAppToken == null || !win.mAppToken.clientHidden) {
Jeff Brown98365d72012-08-19 20:30:52 -07002257 res |= WindowManagerGlobal.ADD_FLAG_APP_VISIBLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002258 }
Romain Guy06882f82009-06-10 13:36:04 -07002259
Jeff Brown2e44b072011-01-24 15:21:56 -08002260 mInputMonitor.setUpdateInputWindowsNeededLw();
2261
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002262 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002263 if (win.canReceiveKeys()) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002264 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
2265 false /*updateInputWindows*/);
Jeff Brown349703e2010-06-22 01:27:15 -07002266 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002267 imMayMove = false;
2268 }
2269 }
Romain Guy06882f82009-06-10 13:36:04 -07002270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002271 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002272 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002273 }
Romain Guy06882f82009-06-10 13:36:04 -07002274
Craig Mautner59c00972012-07-30 12:10:24 -07002275 assignLayersLocked(displayContent.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002276 // Don't do layout here, the window must call
2277 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002279 //dump();
2280
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002281 if (focusChanged) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002282 finishUpdateFocusedWindowAfterAssignLayersLocked(false /*updateInputWindows*/);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002283 }
Jeff Brown2e44b072011-01-24 15:21:56 -08002284 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08002285
Joe Onorato8a9b2202010-02-26 18:56:32 -08002286 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002287 TAG, "New client " + client.asBinder()
2288 + ": window=" + win);
Craig Mautner9e809442012-06-22 17:13:04 -07002289
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002290 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002291 reportNewConfig = true;
2292 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002293 }
2294
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002295 if (reportNewConfig) {
2296 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002297 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07002298
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002299 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002301 return res;
2302 }
Romain Guy06882f82009-06-10 13:36:04 -07002303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002304 public void removeWindow(Session session, IWindow client) {
2305 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002306 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002307 if (win == null) {
2308 return;
2309 }
2310 removeWindowLocked(session, win);
2311 }
2312 }
Romain Guy06882f82009-06-10 13:36:04 -07002313
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002314 public void removeWindowLocked(Session session, WindowState win) {
2315
Joe Onorato8a9b2202010-02-26 18:56:32 -08002316 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002317 TAG, "Remove " + win + " client="
2318 + Integer.toHexString(System.identityHashCode(
2319 win.mClient.asBinder()))
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002320 + ", surface=" + win.mWinAnimator.mSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002321
2322 final long origId = Binder.clearCallingIdentity();
Craig Mautner764983d2012-03-22 11:37:36 -07002323
Jeff Brownc5ed5912010-07-14 18:48:53 -07002324 win.disposeInputChannel();
Romain Guy06882f82009-06-10 13:36:04 -07002325
Joe Onorato8a9b2202010-02-26 18:56:32 -08002326 if (DEBUG_APP_TRANSITIONS) Slog.v(
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002327 TAG, "Remove " + win + ": mSurface=" + win.mWinAnimator.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002328 + " mExiting=" + win.mExiting
Craig Mautnera2c77052012-03-26 12:14:43 -07002329 + " isAnimating=" + win.mWinAnimator.isAnimating()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002330 + " app-animation="
Craig Mautner59431632012-04-04 11:56:44 -07002331 + (win.mAppToken != null ? win.mAppToken.mAppAnimator.animation : null)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002332 + " inPendingTransaction="
2333 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2334 + " mDisplayFrozen=" + mDisplayFrozen);
2335 // Visibility of the removed window. Will be used later to update orientation later on.
2336 boolean wasVisible = false;
2337 // First, see if we need to run an animation. If we do, we have
2338 // to hold off on removing the window until the animation is done.
2339 // If the display is frozen, just remove immediately, since the
2340 // animation wouldn't be seen.
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002341 if (win.mHasSurface && okToDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002342 // If we are not currently running the exit animation, we
2343 // need to see about starting one.
Craig Mautner764983d2012-03-22 11:37:36 -07002344 wasVisible = win.isWinVisibleLw();
2345 if (wasVisible) {
Romain Guy06882f82009-06-10 13:36:04 -07002346
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002347 int transit = WindowManagerPolicy.TRANSIT_EXIT;
Craig Mautnerbb1449b2012-03-23 16:11:14 -07002348 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002349 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2350 }
2351 // Try starting an animation.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002352 if (win.mWinAnimator.applyAnimationLocked(transit, false)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002353 win.mExiting = true;
2354 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002355 scheduleNotifyWindowTranstionIfNeededLocked(win, transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002356 }
Craig Mautnera2c77052012-03-26 12:14:43 -07002357 if (win.mExiting || win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002358 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002359 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002360 win.mExiting = true;
2361 win.mRemoveOnExit = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07002362 win.mDisplayContent.layoutNeeded = true;
Jeff Brown3a22cd92011-01-21 13:59:04 -08002363 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2364 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002365 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08002366 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002367 if (win.mAppToken != null) {
2368 win.mAppToken.updateReportedVisibilityLocked();
2369 }
2370 //dump();
2371 Binder.restoreCallingIdentity(origId);
2372 return;
2373 }
2374 }
2375
2376 removeWindowInnerLocked(session, win);
2377 // Removing a visible window will effect the computed orientation
2378 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002379 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002380 != mForcedAppOrientation
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002381 && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002382 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002383 }
Jeff Brown3a22cd92011-01-21 13:59:04 -08002384 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002385 Binder.restoreCallingIdentity(origId);
2386 }
Romain Guy06882f82009-06-10 13:36:04 -07002387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002388 private void removeWindowInnerLocked(Session session, WindowState win) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002389 if (win.mRemoved) {
2390 // Nothing to do.
2391 return;
2392 }
2393
2394 for (int i=win.mChildWindows.size()-1; i>=0; i--) {
2395 WindowState cwin = win.mChildWindows.get(i);
2396 Slog.w(TAG, "Force-removing child win " + cwin + " from container "
2397 + win);
2398 removeWindowInnerLocked(cwin.mSession, cwin);
2399 }
2400
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002401 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002403 if (mInputMethodTarget == win) {
2404 moveInputMethodWindowsIfNeededLocked(false);
2405 }
Romain Guy06882f82009-06-10 13:36:04 -07002406
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002407 if (false) {
2408 RuntimeException e = new RuntimeException("here");
2409 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002410 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002411 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002412
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002413 mPolicy.removeWindowLw(win);
2414 win.removeLocked();
2415
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002416 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002417 mWindowMap.remove(win.mClient.asBinder());
Craig Mautner59c00972012-07-30 12:10:24 -07002418
2419 final WindowList windows = win.getWindowList();
2420 windows.remove(win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002421 mPendingRemove.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002422 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002423 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002424
2425 if (mInputMethodWindow == win) {
2426 mInputMethodWindow = null;
2427 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2428 mInputMethodDialogs.remove(win);
2429 }
Romain Guy06882f82009-06-10 13:36:04 -07002430
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002431 final WindowToken token = win.mToken;
2432 final AppWindowToken atoken = win.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002433 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + win + " from " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002434 token.windows.remove(win);
2435 if (atoken != null) {
2436 atoken.allAppWindows.remove(win);
2437 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002438 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002439 TAG, "**** Removing window " + win + ": count="
2440 + token.windows.size());
2441 if (token.windows.size() == 0) {
2442 if (!token.explicit) {
2443 mTokenMap.remove(token.token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002444 } else if (atoken != null) {
2445 atoken.firstWindowDrawn = false;
2446 }
2447 }
2448
2449 if (atoken != null) {
2450 if (atoken.startingWindow == win) {
Craig Mautner38b24782012-07-02 16:21:28 -07002451 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling startingWindow " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002452 atoken.startingWindow = null;
2453 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2454 // If this is the last window and we had requested a starting
2455 // transition window, well there is no point now.
Craig Mautner38b24782012-07-02 16:21:28 -07002456 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling last startingWindow");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002457 atoken.startingData = null;
2458 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2459 // If this is the last window except for a starting transition
2460 // window, we need to get rid of the starting transition.
2461 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002462 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002463 + ": no more real windows");
2464 }
2465 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2466 mH.sendMessage(m);
2467 }
2468 }
Romain Guy06882f82009-06-10 13:36:04 -07002469
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002470 if (win.mAttrs.type == TYPE_WALLPAPER) {
2471 mLastWallpaperTimeoutTime = 0;
2472 adjustWallpaperWindowsLocked();
2473 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002474 adjustWallpaperWindowsLocked();
2475 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002476
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002477 if (!mInLayout) {
Craig Mautner59c00972012-07-30 12:10:24 -07002478 assignLayersLocked(windows);
Craig Mautner19d59bc2012-09-04 11:15:56 -07002479 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002480 performLayoutAndPlaceSurfacesLocked();
2481 if (win.mAppToken != null) {
2482 win.mAppToken.updateReportedVisibilityLocked();
2483 }
2484 }
Craig Mautner9e809442012-06-22 17:13:04 -07002485
Jeff Brown2e44b072011-01-24 15:21:56 -08002486 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002487 }
2488
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002489 static void logSurface(WindowState w, String msg, RuntimeException where) {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002490 String str = " SURFACE " + msg + ": " + w;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002491 if (where != null) {
2492 Slog.i(TAG, str, where);
2493 } else {
2494 Slog.i(TAG, str);
2495 }
2496 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002497
2498 static void logSurface(Surface s, String title, String msg, RuntimeException where) {
2499 String str = " SURFACE " + s + ": " + msg + " / " + title;
2500 if (where != null) {
2501 Slog.i(TAG, str, where);
2502 } else {
2503 Slog.i(TAG, str);
2504 }
2505 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07002506
2507 // TODO(cmautner): Move to WindowStateAnimator.
2508 void setTransparentRegionHint(final WindowStateAnimator winAnimator, final Region region) {
2509 mH.sendMessage(mH.obtainMessage(H.SET_TRANSPARENT_REGION,
2510 new Pair<WindowStateAnimator, Region>(winAnimator, region)));
2511 }
2512
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002513 void setTransparentRegionWindow(Session session, IWindow client, Region region) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002514 long origId = Binder.clearCallingIdentity();
2515 try {
2516 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002517 WindowState w = windowForClientLocked(session, client, false);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002518 if ((w != null) && w.mHasSurface) {
Craig Mautner48ba1e72012-04-02 13:18:16 -07002519 setTransparentRegionHint(w.mWinAnimator, region);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002520 }
2521 }
2522 } finally {
2523 Binder.restoreCallingIdentity(origId);
2524 }
2525 }
2526
2527 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002528 int touchableInsets, Rect contentInsets,
Jeff Brownfbf09772011-01-16 14:06:57 -08002529 Rect visibleInsets, Region touchableRegion) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002530 long origId = Binder.clearCallingIdentity();
2531 try {
2532 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002533 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002534 if (w != null) {
2535 w.mGivenInsetsPending = false;
2536 w.mGivenContentInsets.set(contentInsets);
2537 w.mGivenVisibleInsets.set(visibleInsets);
Jeff Brownfbf09772011-01-16 14:06:57 -08002538 w.mGivenTouchableRegion.set(touchableRegion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002539 w.mTouchableInsets = touchableInsets;
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002540 if (w.mGlobalScale != 1) {
2541 w.mGivenContentInsets.scale(w.mGlobalScale);
2542 w.mGivenVisibleInsets.scale(w.mGlobalScale);
2543 w.mGivenTouchableRegion.scale(w.mGlobalScale);
2544 }
Craig Mautner19d59bc2012-09-04 11:15:56 -07002545 w.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002546 performLayoutAndPlaceSurfacesLocked();
2547 }
2548 }
2549 } finally {
2550 Binder.restoreCallingIdentity(origId);
2551 }
2552 }
Romain Guy06882f82009-06-10 13:36:04 -07002553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002554 public void getWindowDisplayFrame(Session session, IWindow client,
2555 Rect outDisplayFrame) {
2556 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002557 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002558 if (win == null) {
2559 outDisplayFrame.setEmpty();
2560 return;
2561 }
2562 outDisplayFrame.set(win.mDisplayFrame);
2563 }
2564 }
2565
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002566 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2567 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002568 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2569 window.mWallpaperX = x;
2570 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002571 window.mWallpaperXStep = xStep;
2572 window.mWallpaperYStep = yStep;
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002573 updateWallpaperOffsetLocked(window, true);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002574 }
2575 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002576
Dianne Hackborn75804932009-10-20 20:15:20 -07002577 void wallpaperCommandComplete(IBinder window, Bundle result) {
2578 synchronized (mWindowMap) {
2579 if (mWaitingOnWallpaper != null &&
2580 mWaitingOnWallpaper.mClient.asBinder() == window) {
2581 mWaitingOnWallpaper = null;
2582 mWindowMap.notifyAll();
2583 }
2584 }
2585 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002586
Dianne Hackborn75804932009-10-20 20:15:20 -07002587 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2588 String action, int x, int y, int z, Bundle extras, boolean sync) {
2589 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2590 || window == mUpperWallpaperTarget) {
2591 boolean doWait = sync;
2592 int curTokenIndex = mWallpaperTokens.size();
2593 while (curTokenIndex > 0) {
2594 curTokenIndex--;
2595 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2596 int curWallpaperIndex = token.windows.size();
2597 while (curWallpaperIndex > 0) {
2598 curWallpaperIndex--;
2599 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2600 try {
2601 wallpaper.mClient.dispatchWallpaperCommand(action,
2602 x, y, z, extras, sync);
2603 // We only want to be synchronous with one wallpaper.
2604 sync = false;
2605 } catch (RemoteException e) {
2606 }
2607 }
2608 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002609
Dianne Hackborn75804932009-10-20 20:15:20 -07002610 if (doWait) {
2611 // XXX Need to wait for result.
2612 }
2613 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002614
Dianne Hackborn75804932009-10-20 20:15:20 -07002615 return null;
2616 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002617
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002618 public void setUniverseTransformLocked(WindowState window, float alpha,
2619 float offx, float offy, float dsdx, float dtdx, float dsdy, float dtdy) {
2620 Transformation transform = window.mWinAnimator.mUniverseTransform;
2621 transform.setAlpha(alpha);
2622 Matrix matrix = transform.getMatrix();
2623 matrix.getValues(mTmpFloats);
2624 mTmpFloats[Matrix.MTRANS_X] = offx;
2625 mTmpFloats[Matrix.MTRANS_Y] = offy;
2626 mTmpFloats[Matrix.MSCALE_X] = dsdx;
2627 mTmpFloats[Matrix.MSKEW_Y] = dtdx;
2628 mTmpFloats[Matrix.MSKEW_X] = dsdy;
2629 mTmpFloats[Matrix.MSCALE_Y] = dtdy;
2630 matrix.setValues(mTmpFloats);
Craig Mautner59c00972012-07-30 12:10:24 -07002631 final DisplayInfo displayInfo = window.mDisplayContent.getDisplayInfo();
Jeff Brownfa25bf52012-07-23 19:26:30 -07002632 final RectF dispRect = new RectF(0, 0,
Craig Mautner59c00972012-07-30 12:10:24 -07002633 displayInfo.logicalWidth, displayInfo.logicalHeight);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002634 matrix.mapRect(dispRect);
Jeff Brownfa25bf52012-07-23 19:26:30 -07002635 window.mGivenTouchableRegion.set(0, 0,
Craig Mautner59c00972012-07-30 12:10:24 -07002636 displayInfo.logicalWidth, displayInfo.logicalHeight);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002637 window.mGivenTouchableRegion.op((int)dispRect.left, (int)dispRect.top,
2638 (int)dispRect.right, (int)dispRect.bottom, Region.Op.DIFFERENCE);
2639 window.mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
Craig Mautner19d59bc2012-09-04 11:15:56 -07002640 window.mDisplayContent.layoutNeeded = true;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002641 performLayoutAndPlaceSurfacesLocked();
2642 }
2643
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002644 public void onRectangleOnScreenRequested(IBinder token, Rect rectangle, boolean immediate) {
2645 synchronized (mWindowMap) {
2646 WindowState window = mWindowMap.get(token);
2647 if (window != null) {
2648 scheduleNotifyRectangleOnScreenRequestedIfNeededLocked(window, rectangle,
2649 immediate);
2650 }
2651 }
2652 }
2653
2654 private void scheduleNotifyRectangleOnScreenRequestedIfNeededLocked(WindowState window,
2655 Rect rectangle, boolean immediate) {
2656 DisplayContent displayContent = window.mDisplayContent;
2657 if (displayContent.mDisplayContentChangeListeners != null
2658 && displayContent.mDisplayContentChangeListeners.getRegisteredCallbackCount() > 0) {
2659 mH.obtainMessage(H.NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED, displayContent.getDisplayId(),
2660 immediate? 1 : 0, new Rect(rectangle)).sendToTarget();
2661 }
2662 }
2663
2664 private void handleNotifyRectangleOnScreenRequested(int displayId, Rect rectangle,
2665 boolean immediate) {
2666 RemoteCallbackList<IDisplayContentChangeListener> callbacks = null;
2667 synchronized (mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07002668 DisplayContent displayContent = getDisplayContentLocked(displayId);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002669 if (displayContent == null) {
2670 return;
2671 }
2672 callbacks = displayContent.mDisplayContentChangeListeners;
2673 if (callbacks == null) {
2674 return;
2675 }
2676 }
2677 final int callbackCount = callbacks.beginBroadcast();
2678 try {
2679 for (int i = 0; i < callbackCount; i++) {
2680 try {
2681 callbacks.getBroadcastItem(i).onRectangleOnScreenRequested(displayId,
2682 rectangle, immediate);
2683 } catch (RemoteException re) {
2684 /* ignore */
2685 }
2686 }
2687 } finally {
2688 callbacks.finishBroadcast();
2689 }
2690 }
2691
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002692 public int relayoutWindow(Session session, IWindow client, int seq,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002693 WindowManager.LayoutParams attrs, int requestedWidth,
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002694 int requestedHeight, int viewVisibility, int flags,
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07002695 Rect outFrame, Rect outContentInsets,
Dianne Hackborn5c58de32012-04-28 19:52:37 -07002696 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07002697 boolean toBeDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002698 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002699 boolean configChanged;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002700 boolean surfaceChanged = false;
Dianne Hackborn12d3a942012-04-27 14:16:30 -07002701 boolean animating;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002702
2703 // if they don't have this permission, mask out the status bar bits
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002704 int systemUiVisibility = 0;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002705 if (attrs != null) {
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002706 systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
2707 if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -07002708 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
2709 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002710 systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
Dianne Hackborna44abeb2011-08-08 19:24:01 -07002711 }
Joe Onoratoac0ee892011-01-30 15:38:30 -08002712 }
2713 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002714 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002715
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002716 synchronized(mWindowMap) {
Craig Mautner48ba1e72012-04-02 13:18:16 -07002717 // TODO(cmautner): synchronize on mAnimator or win.mWinAnimator.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002718 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002719 if (win == null) {
2720 return 0;
2721 }
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002722 WindowStateAnimator winAnimator = win.mWinAnimator;
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08002723 if (win.mRequestedWidth != requestedWidth
2724 || win.mRequestedHeight != requestedHeight) {
2725 win.mLayoutNeeded = true;
2726 win.mRequestedWidth = requestedWidth;
2727 win.mRequestedHeight = requestedHeight;
2728 }
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002729 if (attrs != null && seq == win.mSeq) {
2730 win.mSystemUiVisibility = systemUiVisibility;
2731 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002732
2733 if (attrs != null) {
2734 mPolicy.adjustWindowParamsLw(attrs);
2735 }
Romain Guy06882f82009-06-10 13:36:04 -07002736
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002737 winAnimator.mSurfaceDestroyDeferred =
Jeff Brown98365d72012-08-19 20:30:52 -07002738 (flags&WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002739
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002740 int attrChanges = 0;
2741 int flagChanges = 0;
2742 if (attrs != null) {
Dianne Hackborn0e60db22011-09-01 11:17:57 -07002743 if (win.mAttrs.type != attrs.type) {
2744 throw new IllegalArgumentException(
2745 "Window type can not be changed after the window is added.");
2746 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002747 flagChanges = win.mAttrs.flags ^= attrs.flags;
2748 attrChanges = win.mAttrs.copyFrom(attrs);
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002749 if ((attrChanges & (WindowManager.LayoutParams.LAYOUT_CHANGED
2750 | WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED)) != 0) {
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08002751 win.mLayoutNeeded = true;
2752 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002753 }
2754
Craig Mautnerc36c49e2012-09-29 16:02:43 -07002755 if (DEBUG_LAYOUT
2756 // TODO: Remove once b/7094175 is fixed
2757 || ((String)win.mAttrs.getTitle()).contains("Keyguard")
2758 ) Slog.v(TAG, "Relayout " + win + ": viewVisibility=" + viewVisibility
Craig Mautner812d2ca2012-09-27 15:35:34 -07002759 + " " + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002760
Dianne Hackborn5fd21692011-06-07 14:09:47 -07002761 win.mEnforceSizeCompat = (win.mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0;
2762
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002763 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002764 winAnimator.mAlpha = attrs.alpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002765 }
2766
2767 final boolean scaledWindow =
2768 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2769
2770 if (scaledWindow) {
2771 // requested{Width|Height} Surface's physical size
2772 // attrs.{width|height} Size on screen
2773 win.mHScale = (attrs.width != requestedWidth) ?
2774 (attrs.width / (float)requestedWidth) : 1.0f;
2775 win.mVScale = (attrs.height != requestedHeight) ?
2776 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002777 } else {
2778 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002779 }
2780
Craig Mautner65d11b32012-10-01 13:59:52 -07002781 boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002782
Craig Mautner69b08182012-09-05 13:07:13 -07002783 final boolean isDefaultDisplay = win.isDefaultDisplay();
2784 boolean focusMayChange = isDefaultDisplay && (win.mViewVisibility != viewVisibility
Craig Mautner65d11b32012-10-01 13:59:52 -07002785 || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0)
Craig Mautner69b08182012-09-05 13:07:13 -07002786 || (!win.mRelayoutCalled));
Romain Guy06882f82009-06-10 13:36:04 -07002787
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002788 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2789 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07002790 wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002791
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002792 win.mRelayoutCalled = true;
2793 final int oldVisibility = win.mViewVisibility;
2794 win.mViewVisibility = viewVisibility;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07002795 if (DEBUG_SCREEN_ON) {
2796 RuntimeException stack = new RuntimeException();
2797 stack.fillInStackTrace();
2798 Slog.i(TAG, "Relayout " + win + ": oldVis=" + oldVisibility
2799 + " newVis=" + viewVisibility, stack);
2800 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002801 if (viewVisibility == View.VISIBLE &&
2802 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07002803 toBeDisplayed = !win.isVisibleLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002804 if (win.mExiting) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002805 winAnimator.cancelExitAnimationForNextAnimationLocked();
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002806 win.mExiting = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002807 }
2808 if (win.mDestroying) {
2809 win.mDestroying = false;
2810 mDestroySurface.remove(win);
2811 }
2812 if (oldVisibility == View.GONE) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002813 winAnimator.mEnterAnimationPending = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002814 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002815 if (toBeDisplayed) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07002816 if (win.isDrawnLw() && okToDisplay()) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002817 winAnimator.applyEnterAnimationLocked();
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002818 }
2819 if ((win.mAttrs.flags
2820 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2821 if (DEBUG_VISIBILITY) Slog.v(TAG,
2822 "Relayout window turning screen on: " + win);
2823 win.mTurnOnScreen = true;
2824 }
2825 int diff = 0;
2826 if (win.mConfiguration != mCurConfiguration
2827 && (win.mConfiguration == null
2828 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2829 win.mConfiguration = mCurConfiguration;
2830 if (DEBUG_CONFIGURATION) {
2831 Slog.i(TAG, "Window " + win + " visible with new config: "
2832 + win.mConfiguration + " / 0x"
2833 + Integer.toHexString(diff));
2834 }
2835 outConfig.setTo(mCurConfiguration);
2836 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002837 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002838 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2839 // To change the format, we need to re-build the surface.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002840 winAnimator.destroySurfaceLocked();
Craig Mautnerbf08af32012-05-16 19:43:42 -07002841 toBeDisplayed = true;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002842 surfaceChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002843 }
2844 try {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002845 if (!win.mHasSurface) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002846 surfaceChanged = true;
2847 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002848 Surface surface = winAnimator.createSurfaceLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002849 if (surface != null) {
2850 outSurface.copyFrom(surface);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002851 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002852 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002853 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002854 // For some reason there isn't a surface. Clear the
2855 // caller's object so they see the same state.
2856 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002857 }
2858 } catch (Exception e) {
Jeff Brown2e44b072011-01-24 15:21:56 -08002859 mInputMonitor.updateInputWindowsLw(true /*force*/);
Craig Mautner9e809442012-06-22 17:13:04 -07002860
Joe Onorato8a9b2202010-02-26 18:56:32 -08002861 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002862 + client + " (" + win.mAttrs.getTitle() + ")",
2863 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002864 Binder.restoreCallingIdentity(origId);
2865 return 0;
2866 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002867 if (toBeDisplayed) {
Craig Mautner69b08182012-09-05 13:07:13 -07002868 focusMayChange = isDefaultDisplay;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002869 }
2870 if (win.mAttrs.type == TYPE_INPUT_METHOD
2871 && mInputMethodWindow == null) {
2872 mInputMethodWindow = win;
2873 imMayMove = true;
2874 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002875 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2876 && win.mAppToken != null
2877 && win.mAppToken.startingWindow != null) {
2878 // Special handling of starting window over the base
2879 // window of the app: propagate lock screen flags to it,
2880 // to provide the correct semantics while starting.
2881 final int mask =
2882 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002883 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2884 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002885 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2886 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2887 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002888 } else {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002889 winAnimator.mEnterAnimationPending = false;
2890 if (winAnimator.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002891 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Craig Mautnerbf08af32012-05-16 19:43:42 -07002892 + ": mExiting=" + win.mExiting);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002893 // If we are not currently running the exit animation, we
2894 // need to see about starting one.
Craig Mautnerbf08af32012-05-16 19:43:42 -07002895 if (!win.mExiting) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002896 surfaceChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002897 // Try starting an animation; if there isn't one, we
2898 // can destroy the surface right away.
2899 int transit = WindowManagerPolicy.TRANSIT_EXIT;
Craig Mautnerbb1449b2012-03-23 16:11:14 -07002900 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002901 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2902 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002903 if (win.isWinVisibleLw() &&
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002904 winAnimator.applyAnimationLocked(transit, false)) {
Craig Mautner69b08182012-09-05 13:07:13 -07002905 focusMayChange = isDefaultDisplay;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002906 win.mExiting = true;
Craig Mautnera2c77052012-03-26 12:14:43 -07002907 } else if (win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002908 // Currently in a hide animation... turn this into
2909 // an exit.
2910 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002911 } else if (win == mWallpaperTarget) {
2912 // If the wallpaper is currently behind this
2913 // window, we need to change both of them inside
2914 // of a transaction to avoid artifacts.
2915 win.mExiting = true;
Craig Mautnera2c77052012-03-26 12:14:43 -07002916 win.mWinAnimator.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002917 } else {
2918 if (mInputMethodWindow == win) {
2919 mInputMethodWindow = null;
2920 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002921 winAnimator.destroySurfaceLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002922 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002923 scheduleNotifyWindowTranstionIfNeededLocked(win, transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002924 }
2925 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002926
Craig Mautnerbf08af32012-05-16 19:43:42 -07002927 outSurface.release();
2928 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002929 }
2930
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002931 if (focusMayChange) {
2932 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
Jeff Brown3a22cd92011-01-21 13:59:04 -08002933 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2934 false /*updateInputWindows*/)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002935 imMayMove = false;
2936 }
2937 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2938 }
Romain Guy06882f82009-06-10 13:36:04 -07002939
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002940 // updateFocusedWindowLocked() already assigned layers so we only need to
2941 // reassign them at this point if the IM window state gets shuffled
2942 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002943
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002944 if (imMayMove) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07002945 if (moveInputMethodWindowsIfNeededLocked(false) || toBeDisplayed) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002946 // Little hack here -- we -should- be able to rely on the
2947 // function to return true if the IME has moved and needs
2948 // its layer recomputed. However, if the IME was hidden
2949 // and isn't actually moved in the list, its layer may be
2950 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002951 assignLayers = true;
2952 }
2953 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002954 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002955 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002956 assignLayers = true;
2957 }
2958 }
Romain Guy06882f82009-06-10 13:36:04 -07002959
Craig Mautner19d59bc2012-09-04 11:15:56 -07002960 win.mDisplayContent.layoutNeeded = true;
Jeff Brown98365d72012-08-19 20:30:52 -07002961 win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002962 if (assignLayers) {
Craig Mautner59c00972012-07-30 12:10:24 -07002963 assignLayersLocked(win.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002964 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002965 configChanged = updateOrientationFromAppTokensLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002966 performLayoutAndPlaceSurfacesLocked();
Craig Mautnerbf08af32012-05-16 19:43:42 -07002967 if (toBeDisplayed && win.mIsWallpaper) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07002968 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Jeff Brownfa25bf52012-07-23 19:26:30 -07002969 updateWallpaperOffsetLocked(win,
Craig Mautner59c00972012-07-30 12:10:24 -07002970 displayInfo.appWidth, displayInfo.appHeight, false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002971 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002972 if (win.mAppToken != null) {
2973 win.mAppToken.updateReportedVisibilityLocked();
2974 }
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002975 outFrame.set(win.mCompatFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002976 outContentInsets.set(win.mContentInsets);
2977 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002978 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002979 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002980 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002981 + ", requestedHeight=" + requestedHeight
2982 + ", viewVisibility=" + viewVisibility
2983 + "\nRelayout returning frame=" + outFrame
2984 + ", surface=" + outSurface);
2985
Joe Onorato8a9b2202010-02-26 18:56:32 -08002986 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002987 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
2988
2989 inTouchMode = mInTouchMode;
Dianne Hackborn12d3a942012-04-27 14:16:30 -07002990 animating = mAnimator.mAnimating;
2991 if (animating && !mRelayoutWhileAnimating.contains(win)) {
2992 mRelayoutWhileAnimating.add(win);
2993 }
2994
Jeff Brown2e44b072011-01-24 15:21:56 -08002995 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002996 }
2997
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002998 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002999 sendNewConfiguration();
3000 }
Romain Guy06882f82009-06-10 13:36:04 -07003001
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003002 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07003003
Jeff Brown98365d72012-08-19 20:30:52 -07003004 return (inTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0)
3005 | (toBeDisplayed ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0)
3006 | (surfaceChanged ? WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED : 0)
3007 | (animating ? WindowManagerGlobal.RELAYOUT_RES_ANIMATING : 0);
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003008 }
3009
3010 public void performDeferredDestroyWindow(Session session, IWindow client) {
3011 long origId = Binder.clearCallingIdentity();
3012
3013 try {
3014 synchronized(mWindowMap) {
3015 WindowState win = windowForClientLocked(session, client, false);
3016 if (win == null) {
3017 return;
3018 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003019 win.mWinAnimator.destroyDeferredSurfaceLocked();
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003020 }
3021 } finally {
3022 Binder.restoreCallingIdentity(origId);
3023 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003024 }
3025
Dianne Hackborn64825172011-03-02 21:32:58 -08003026 public boolean outOfMemoryWindow(Session session, IWindow client) {
3027 long origId = Binder.clearCallingIdentity();
3028
3029 try {
3030 synchronized(mWindowMap) {
3031 WindowState win = windowForClientLocked(session, client, false);
3032 if (win == null) {
3033 return false;
3034 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003035 return reclaimSomeSurfaceMemoryLocked(win.mWinAnimator, "from-client", false);
Dianne Hackborn64825172011-03-02 21:32:58 -08003036 }
3037 } finally {
3038 Binder.restoreCallingIdentity(origId);
3039 }
3040 }
3041
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003042 public void finishDrawingWindow(Session session, IWindow client) {
3043 final long origId = Binder.clearCallingIdentity();
3044 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003045 WindowState win = windowForClientLocked(session, client, false);
Craig Mautnera608b882012-03-30 13:03:49 -07003046 if (win != null && win.mWinAnimator.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07003047 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
3048 adjustWallpaperWindowsLocked();
3049 }
Craig Mautner19d59bc2012-09-04 11:15:56 -07003050 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003051 performLayoutAndPlaceSurfacesLocked();
3052 }
3053 }
3054 Binder.restoreCallingIdentity(origId);
3055 }
3056
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003057 @Override
Svetoslav Ganov7961be72011-06-21 12:31:56 -07003058 public float getWindowCompatibilityScale(IBinder windowToken) {
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07003059 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
3060 "getWindowCompatibilityScale()")) {
3061 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
3062 }
Svetoslav Ganov7961be72011-06-21 12:31:56 -07003063 synchronized (mWindowMap) {
3064 WindowState windowState = mWindowMap.get(windowToken);
3065 return (windowState != null) ? windowState.mGlobalScale : 1.0f;
3066 }
3067 }
3068
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003069 @Override
3070 public WindowInfo getWindowInfo(IBinder token) {
3071 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
3072 "getWindowInfo()")) {
3073 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
3074 }
3075 synchronized (mWindowMap) {
3076 WindowState window = mWindowMap.get(token);
3077 if (window != null) {
3078 return getWindowInfoForWindowStateLocked(window);
3079 }
3080 return null;
3081 }
3082 }
3083
3084 @Override
3085 public void getVisibleWindowsForDisplay(int displayId, List<WindowInfo> outInfos) {
3086 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
3087 "getWindowInfos()")) {
3088 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
3089 }
3090 synchronized (mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003091 DisplayContent displayContent = getDisplayContentLocked(displayId);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003092 if (displayContent == null) {
3093 return;
3094 }
3095 WindowList windows = displayContent.getWindowList();
3096 final int windowCount = windows.size();
3097 for (int i = 0; i < windowCount; i++) {
3098 WindowState window = windows.get(i);
Craig Mautner65d11b32012-10-01 13:59:52 -07003099 if (window.isVisibleLw() || window.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003100 WindowInfo info = getWindowInfoForWindowStateLocked(window);
3101 outInfos.add(info);
3102 }
3103 }
3104 }
3105 }
3106
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003107 @Override
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003108 public void magnifyDisplay(int displayId, float scale, float offsetX, float offsetY) {
3109 if (!checkCallingPermission(
3110 android.Manifest.permission.MAGNIFY_DISPLAY, "magnifyDisplay()")) {
3111 throw new SecurityException("Requires MAGNIFY_DISPLAY permission");
3112 }
3113 synchronized (mWindowMap) {
3114 MagnificationSpec spec = getDisplayMagnificationSpecLocked(displayId);
3115 if (spec != null) {
3116 final boolean scaleChanged = spec.mScale != scale;
3117 final boolean offsetChanged = spec.mOffsetX != offsetX || spec.mOffsetY != offsetY;
3118 if (!scaleChanged && !offsetChanged) {
3119 return;
3120 }
3121 spec.initialize(scale, offsetX, offsetY);
3122 // If the offset has changed we need to re-add the input windows
3123 // since the offsets have to be propagated to the input system.
3124 if (offsetChanged) {
3125 // TODO(multidisplay): Input only occurs on the default display.
3126 if (displayId == Display.DEFAULT_DISPLAY) {
3127 mInputMonitor.updateInputWindowsLw(true);
3128 }
3129 }
3130 scheduleAnimationLocked();
3131 }
3132 }
3133 }
3134
3135 MagnificationSpec getDisplayMagnificationSpecLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003136 DisplayContent displayContent = getDisplayContentLocked(displayId);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003137 if (displayContent != null) {
3138 if (displayContent.mMagnificationSpec == null) {
3139 displayContent.mMagnificationSpec = new MagnificationSpec();
3140 }
3141 return displayContent.mMagnificationSpec;
3142 }
3143 return null;
3144 }
3145
3146 private WindowInfo getWindowInfoForWindowStateLocked(WindowState window) {
3147 WindowInfo info = WindowInfo.obtain();
3148 info.token = window.mToken.token;
3149 info.frame.set(window.mFrame);
3150 info.type = window.mAttrs.type;
3151 info.displayId = window.getDisplayId();
3152 info.compatibilityScale = window.mGlobalScale;
Craig Mautner65d11b32012-10-01 13:59:52 -07003153 info.visible = window.isVisibleLw() || info.type == TYPE_UNIVERSE_BACKGROUND;
Svetoslav Ganov9b4125e2012-09-11 15:36:44 -07003154 info.layer = window.mLayer;
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003155 window.getTouchableRegion(mTempRegion);
3156 mTempRegion.getBounds(info.touchableRegion);
3157 return info;
3158 }
3159
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003160 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Dianne Hackborn08121bc2011-01-17 17:54:31 -08003161 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: layout params pkg="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003162 + (lp != null ? lp.packageName : null)
3163 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
3164 if (lp != null && lp.windowAnimations != 0) {
3165 // If this is a system resource, don't try to load it from the
3166 // application resources. It is nice to avoid loading application
3167 // resources if we can.
3168 String packageName = lp.packageName != null ? lp.packageName : "android";
3169 int resId = lp.windowAnimations;
3170 if ((resId&0xFF000000) == 0x01000000) {
3171 packageName = "android";
3172 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003173 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003174 + packageName);
3175 return AttributeCache.instance().get(packageName, resId,
3176 com.android.internal.R.styleable.WindowAnimation);
3177 }
3178 return null;
3179 }
Romain Guy06882f82009-06-10 13:36:04 -07003180
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003181 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Dianne Hackborn08121bc2011-01-17 17:54:31 -08003182 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003183 + packageName + " resId=0x" + Integer.toHexString(resId));
3184 if (packageName != null) {
3185 if ((resId&0xFF000000) == 0x01000000) {
3186 packageName = "android";
3187 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003188 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003189 + packageName);
3190 return AttributeCache.instance().get(packageName, resId,
3191 com.android.internal.R.styleable.WindowAnimation);
3192 }
3193 return null;
3194 }
3195
Craig Mautnere7ae2502012-03-26 17:11:19 -07003196 Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003197 int anim = 0;
3198 Context context = mContext;
3199 if (animAttr >= 0) {
3200 AttributeCache.Entry ent = getCachedAnimations(lp);
3201 if (ent != null) {
3202 context = ent.context;
3203 anim = ent.array.getResourceId(animAttr, 0);
3204 }
3205 }
3206 if (anim != 0) {
3207 return AnimationUtils.loadAnimation(context, anim);
3208 }
3209 return null;
3210 }
Romain Guy06882f82009-06-10 13:36:04 -07003211
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003212 private Animation loadAnimation(String packageName, int resId) {
3213 int anim = 0;
3214 Context context = mContext;
3215 if (resId >= 0) {
3216 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
3217 if (ent != null) {
3218 context = ent.context;
3219 anim = resId;
3220 }
3221 }
3222 if (anim != 0) {
3223 return AnimationUtils.loadAnimation(context, anim);
3224 }
3225 return null;
3226 }
3227
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003228 private Animation createExitAnimationLocked(int transit, int duration) {
3229 if (transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN ||
3230 transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE) {
3231 // If we are on top of the wallpaper, we need an animation that
3232 // correctly handles the wallpaper staying static behind all of
3233 // the animated elements. To do this, will just have the existing
3234 // element fade out.
3235 Animation a = new AlphaAnimation(1, 0);
3236 a.setDetachWallpaper(true);
3237 a.setDuration(duration);
3238 return a;
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003239 }
Craig Mautner01cd0e72012-06-18 10:19:11 -07003240 // For normal animations, the exiting element just holds in place.
3241 Animation a = new AlphaAnimation(1, 1);
3242 a.setDuration(duration);
3243 return a;
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003244 }
3245
3246 /**
3247 * Compute the pivot point for an animation that is scaling from a small
3248 * rect on screen to a larger rect. The pivot point varies depending on
3249 * the distance between the inner and outer edges on both sides. This
3250 * function computes the pivot point for one dimension.
3251 * @param startPos Offset from left/top edge of outer rectangle to
3252 * left/top edge of inner rectangle.
3253 * @param finalScale The scaling factor between the size of the outer
3254 * and inner rectangles.
3255 */
3256 private static float computePivot(int startPos, float finalScale) {
3257 final float denom = finalScale-1;
3258 if (Math.abs(denom) < .0001f) {
3259 return startPos;
3260 }
3261 return -startPos / denom;
3262 }
3263
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003264 private Animation createScaleUpAnimationLocked(int transit, boolean enter) {
3265 Animation a;
3266 // Pick the desired duration. If this is an inter-activity transition,
3267 // it is the standard duration for that. Otherwise we use the longer
3268 // task transition duration.
3269 int duration;
3270 switch (transit) {
3271 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3272 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3273 duration = mContext.getResources().getInteger(
3274 com.android.internal.R.integer.config_shortAnimTime);
3275 break;
3276 default:
Winson Chungdc6f79b2012-04-17 17:27:31 -07003277 duration = 300;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003278 break;
3279 }
Craig Mautner59c00972012-07-30 12:10:24 -07003280 // TODO(multidisplay): For now assume all app animation is on main display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003281 final DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003282 if (enter) {
3283 // Entering app zooms out from the center of the initial rect.
Craig Mautner59c00972012-07-30 12:10:24 -07003284 float scaleW = mNextAppTransitionStartWidth / (float) displayInfo.appWidth;
3285 float scaleH = mNextAppTransitionStartHeight / (float) displayInfo.appHeight;
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003286 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
3287 computePivot(mNextAppTransitionStartX, scaleW),
3288 computePivot(mNextAppTransitionStartY, scaleH));
3289 scale.setDuration(duration);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003290 AnimationSet set = new AnimationSet(true);
3291 Animation alpha = new AlphaAnimation(0, 1);
3292 scale.setDuration(duration);
3293 set.addAnimation(scale);
3294 alpha.setDuration(duration);
3295 set.addAnimation(alpha);
Craig Mautnera8033712012-06-12 15:50:45 -07003296 set.setDetachWallpaper(true);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003297 a = set;
3298 } else {
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003299 a = createExitAnimationLocked(transit, duration);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003300 }
3301 a.setFillAfter(true);
3302 final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
Winson Chungdc6f79b2012-04-17 17:27:31 -07003303 com.android.internal.R.interpolator.decelerate_cubic);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003304 a.setInterpolator(interpolator);
Craig Mautner59c00972012-07-30 12:10:24 -07003305 a.initialize(displayInfo.appWidth, displayInfo.appHeight,
3306 displayInfo.appWidth, displayInfo.appHeight);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003307 return a;
3308 }
3309
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003310 private Animation createThumbnailAnimationLocked(int transit,
Michael Jurka832cb222012-04-13 09:32:47 -07003311 boolean enter, boolean thumb, boolean scaleUp) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003312 Animation a;
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003313 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
3314 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
3315 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
3316 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003317 // Pick the desired duration. If this is an inter-activity transition,
3318 // it is the standard duration for that. Otherwise we use the longer
3319 // task transition duration.
3320 int duration;
3321 switch (transit) {
3322 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3323 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3324 duration = mContext.getResources().getInteger(
3325 com.android.internal.R.integer.config_shortAnimTime);
3326 break;
3327 default:
Michael Jurka832cb222012-04-13 09:32:47 -07003328 duration = 250;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003329 break;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003330 }
Craig Mautner59c00972012-07-30 12:10:24 -07003331 // TOOD(multidisplay): For now assume all app animation is on the main screen.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003332 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003333 if (thumb) {
3334 // Animation for zooming thumbnail from its initial size to
3335 // filling the screen.
Michael Jurka832cb222012-04-13 09:32:47 -07003336 if (scaleUp) {
3337 float scaleW = displayInfo.appWidth / thumbWidth;
3338 float scaleH = displayInfo.appHeight / thumbHeight;
Michael Jurka21385cd2012-05-03 10:57:31 -07003339
Michael Jurka832cb222012-04-13 09:32:47 -07003340 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
3341 computePivot(mNextAppTransitionStartX, 1 / scaleW),
3342 computePivot(mNextAppTransitionStartY, 1 / scaleH));
3343 AnimationSet set = new AnimationSet(true);
3344 Animation alpha = new AlphaAnimation(1, 0);
3345 scale.setDuration(duration);
3346 scale.setInterpolator(
3347 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
3348 set.addAnimation(scale);
3349 alpha.setDuration(duration);
3350 set.addAnimation(alpha);
3351 set.setFillBefore(true);
3352 a = set;
3353 } else {
3354 float scaleW = displayInfo.appWidth / thumbWidth;
3355 float scaleH = displayInfo.appHeight / thumbHeight;
3356
3357 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
3358 computePivot(mNextAppTransitionStartX, 1 / scaleW),
3359 computePivot(mNextAppTransitionStartY, 1 / scaleH));
3360 AnimationSet set = new AnimationSet(true);
3361 Animation alpha = new AlphaAnimation(1, 1);
3362 scale.setDuration(duration);
3363 scale.setInterpolator(
3364 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
3365 set.addAnimation(scale);
3366 alpha.setDuration(duration);
3367 set.addAnimation(alpha);
3368 set.setFillBefore(true);
3369
3370 a = set;
Michael Jurka21385cd2012-05-03 10:57:31 -07003371 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003372 } else if (enter) {
3373 // Entering app zooms out from the center of the thumbnail.
Michael Jurka832cb222012-04-13 09:32:47 -07003374 if (scaleUp) {
3375 float scaleW = thumbWidth / displayInfo.appWidth;
3376 float scaleH = thumbHeight / displayInfo.appHeight;
3377 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
3378 computePivot(mNextAppTransitionStartX, scaleW),
3379 computePivot(mNextAppTransitionStartY, scaleH));
3380 scale.setDuration(duration);
3381 scale.setInterpolator(
3382 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
3383 scale.setFillBefore(true);
3384 a = scale;
Michael Jurkad5895a72012-05-12 13:24:58 -07003385 } else {
Michael Jurka832cb222012-04-13 09:32:47 -07003386 // noop animation
3387 a = new AlphaAnimation(1, 1);
3388 a.setDuration(duration);
3389 }
3390 } else {
3391 // Exiting app
3392 if (scaleUp) {
3393 // noop animation
Craig Mautner8863cca2012-09-18 15:04:34 -07003394 a = new AlphaAnimation(1, 0);
Michael Jurka832cb222012-04-13 09:32:47 -07003395 a.setDuration(duration);
3396 } else {
3397 float scaleW = thumbWidth / displayInfo.appWidth;
3398 float scaleH = thumbHeight / displayInfo.appHeight;
3399 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
3400 computePivot(mNextAppTransitionStartX, scaleW),
3401 computePivot(mNextAppTransitionStartY, scaleH));
3402 scale.setDuration(duration);
3403 scale.setInterpolator(
3404 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
3405 scale.setFillBefore(true);
3406 AnimationSet set = new AnimationSet(true);
3407 Animation alpha = new AlphaAnimation(1, 0);
3408 set.addAnimation(scale);
3409 alpha.setDuration(duration);
3410 alpha.setInterpolator(new DecelerateInterpolator(
3411 THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
3412 set.addAnimation(alpha);
3413 set.setFillBefore(true);
3414 set.setZAdjustment(Animation.ZORDER_TOP);
3415 a = set;
Michael Jurka21385cd2012-05-03 10:57:31 -07003416 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003417 }
3418 a.setFillAfter(true);
3419 final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003420 com.android.internal.R.interpolator.decelerate_quad);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003421 a.setInterpolator(interpolator);
Craig Mautner59c00972012-07-30 12:10:24 -07003422 a.initialize(displayInfo.appWidth, displayInfo.appHeight,
3423 displayInfo.appWidth, displayInfo.appHeight);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003424 return a;
3425 }
3426
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003427 private boolean applyAnimationLocked(AppWindowToken atoken,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07003428 WindowManager.LayoutParams lp, int transit, boolean enter) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003429 // Only apply an animation if the display isn't frozen. If it is
3430 // frozen, there is no reason to animate and it can cause strange
3431 // artifacts when we unfreeze the display if some different animation
3432 // is running.
Craig Mautner2fb98b12012-03-20 17:24:00 -07003433 if (okToDisplay()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003434 Animation a;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003435 boolean initialized = false;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003436 if (mNextAppTransitionType == ActivityOptions.ANIM_CUSTOM) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003437 a = loadAnimation(mNextAppTransitionPackage, enter ?
3438 mNextAppTransitionEnter : mNextAppTransitionExit);
Daniel Sandlerab886f52012-06-04 14:36:25 -04003439 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003440 "applyAnimation: atoken=" + atoken
Craig Mautner83339b42012-05-01 22:13:23 -07003441 + " anim=" + a + " nextAppTransition=ANIM_CUSTOM"
Craig Mautnerdc5a6382012-09-13 16:34:41 -07003442 + " transit=" + transit + " isEntrance=" + enter
Craig Mautner8863cca2012-09-18 15:04:34 -07003443 + " Callers=" + Debug.getCallers(3));
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003444 } else if (mNextAppTransitionType == ActivityOptions.ANIM_SCALE_UP) {
3445 a = createScaleUpAnimationLocked(transit, enter);
3446 initialized = true;
Daniel Sandlerab886f52012-06-04 14:36:25 -04003447 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003448 "applyAnimation: atoken=" + atoken
Craig Mautner83339b42012-05-01 22:13:23 -07003449 + " anim=" + a + " nextAppTransition=ANIM_SCALE_UP"
Craig Mautnerdc5a6382012-09-13 16:34:41 -07003450 + " transit=" + transit + " isEntrance=" + enter
Craig Mautner8863cca2012-09-18 15:04:34 -07003451 + " Callers=" + Debug.getCallers(3));
Michael Jurka832cb222012-04-13 09:32:47 -07003452 } else if (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_SCALE_UP ||
3453 mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN) {
3454 boolean scaleUp = (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_SCALE_UP);
3455 a = createThumbnailAnimationLocked(transit, enter, false, scaleUp);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003456 initialized = true;
Daniel Sandlerab886f52012-06-04 14:36:25 -04003457 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
Michael Jurka832cb222012-04-13 09:32:47 -07003458 String animName = scaleUp ? "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN";
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003459 Slog.v(TAG, "applyAnimation: atoken=" + atoken
Michael Jurka21385cd2012-05-03 10:57:31 -07003460 + " anim=" + a + " nextAppTransition=" + animName
Craig Mautnerdc5a6382012-09-13 16:34:41 -07003461 + " transit=" + transit + " isEntrance=" + enter
Craig Mautner8863cca2012-09-18 15:04:34 -07003462 + " Callers=" + Debug.getCallers(3));
Michael Jurka21385cd2012-05-03 10:57:31 -07003463 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003464 } else {
3465 int animAttr = 0;
3466 switch (transit) {
3467 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3468 animAttr = enter
3469 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
3470 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
3471 break;
3472 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3473 animAttr = enter
3474 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
3475 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
3476 break;
3477 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
3478 animAttr = enter
3479 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
3480 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
3481 break;
3482 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
3483 animAttr = enter
3484 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
3485 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
3486 break;
3487 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
3488 animAttr = enter
3489 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
3490 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
3491 break;
3492 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
3493 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07003494 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003495 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
3496 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003497 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003498 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003499 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
3500 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003501 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003502 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003503 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003504 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
3505 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
3506 break;
3507 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
3508 animAttr = enter
3509 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
3510 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
3511 break;
3512 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
3513 animAttr = enter
3514 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
3515 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003516 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003517 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003518 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Daniel Sandlerab886f52012-06-04 14:36:25 -04003519 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003520 "applyAnimation: atoken=" + atoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003521 + " anim=" + a
3522 + " animAttr=0x" + Integer.toHexString(animAttr)
Craig Mautnerdc5a6382012-09-13 16:34:41 -07003523 + " transit=" + transit + " isEntrance=" + enter
Craig Mautner8863cca2012-09-18 15:04:34 -07003524 + " Callers=" + Debug.getCallers(3));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003525 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003526 if (a != null) {
3527 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003528 RuntimeException e = null;
3529 if (!HIDE_STACK_CRAWLS) {
3530 e = new RuntimeException();
3531 e.fillInStackTrace();
3532 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003533 Slog.v(TAG, "Loaded animation " + a + " for " + atoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003534 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003535 atoken.mAppAnimator.setAnimation(a, initialized);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003536 }
3537 } else {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003538 atoken.mAppAnimator.clearAnimation();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003539 }
3540
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003541 return atoken.mAppAnimator.animation != null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003542 }
3543
3544 // -------------------------------------------------------------
3545 // Application Window Tokens
3546 // -------------------------------------------------------------
3547
Dianne Hackbornbe707852011-11-11 14:32:10 -08003548 public void validateAppTokens(List<IBinder> tokens) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003549 int v = tokens.size()-1;
3550 int m = mAppTokens.size()-1;
3551 while (v >= 0 && m >= 0) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003552 AppWindowToken atoken = mAppTokens.get(m);
3553 if (atoken.removed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003554 m--;
3555 continue;
3556 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003557 if (tokens.get(v) != atoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003558 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003559 + " @ " + v + ", internal is " + atoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003560 }
3561 v--;
3562 m--;
3563 }
3564 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003565 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003566 v--;
3567 }
3568 while (m >= 0) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003569 AppWindowToken atoken = mAppTokens.get(m);
3570 if (!atoken.removed) {
3571 Slog.w(TAG, "Invalid internal atoken: " + atoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003572 }
3573 m--;
3574 }
3575 }
3576
3577 boolean checkCallingPermission(String permission, String func) {
3578 // Quick check: if the calling permission is me, it's all okay.
3579 if (Binder.getCallingPid() == Process.myPid()) {
3580 return true;
3581 }
Romain Guy06882f82009-06-10 13:36:04 -07003582
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003583 if (mContext.checkCallingPermission(permission)
3584 == PackageManager.PERMISSION_GRANTED) {
3585 return true;
3586 }
3587 String msg = "Permission Denial: " + func + " from pid="
3588 + Binder.getCallingPid()
3589 + ", uid=" + Binder.getCallingUid()
3590 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003591 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003592 return false;
3593 }
Craig Mautner9e809442012-06-22 17:13:04 -07003594
Craig Mautner2fb98b12012-03-20 17:24:00 -07003595 boolean okToDisplay() {
3596 return !mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully();
3597 }
Romain Guy06882f82009-06-10 13:36:04 -07003598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003599 AppWindowToken findAppWindowToken(IBinder token) {
3600 WindowToken wtoken = mTokenMap.get(token);
3601 if (wtoken == null) {
3602 return null;
3603 }
3604 return wtoken.appWindowToken;
3605 }
Romain Guy06882f82009-06-10 13:36:04 -07003606
Craig Mautnercf8cbbe2012-03-25 21:54:36 -07003607 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003608 public void addWindowToken(IBinder token, int type) {
3609 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3610 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003611 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003612 }
Romain Guy06882f82009-06-10 13:36:04 -07003613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003614 synchronized(mWindowMap) {
3615 WindowToken wtoken = mTokenMap.get(token);
3616 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003617 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003618 return;
3619 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003620 wtoken = new WindowToken(this, token, type, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003621 mTokenMap.put(token, wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003622 if (type == TYPE_WALLPAPER) {
3623 mWallpaperTokens.add(wtoken);
Craig Mautner918b53b2012-07-09 14:15:54 -07003624 updateLayoutToAnimWallpaperTokens();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003625 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003626 }
3627 }
Romain Guy06882f82009-06-10 13:36:04 -07003628
Craig Mautner9e809442012-06-22 17:13:04 -07003629 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003630 public void removeWindowToken(IBinder token) {
3631 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3632 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003633 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003634 }
3635
3636 final long origId = Binder.clearCallingIdentity();
3637 synchronized(mWindowMap) {
3638 WindowToken wtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003639 if (wtoken != null) {
3640 boolean delayed = false;
3641 if (!wtoken.hidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003642 final int N = wtoken.windows.size();
3643 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003644
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003645 for (int i=0; i<N; i++) {
3646 WindowState win = wtoken.windows.get(i);
3647
Craig Mautnera2c77052012-03-26 12:14:43 -07003648 if (win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003649 delayed = true;
3650 }
Romain Guy06882f82009-06-10 13:36:04 -07003651
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003652 if (win.isVisibleNow()) {
Craig Mautner59c00972012-07-30 12:10:24 -07003653 win.mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT,
3654 false);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003655 scheduleNotifyWindowTranstionIfNeededLocked(win,
3656 WindowManagerPolicy.TRANSIT_EXIT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003657 changed = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07003658 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003659 }
3660 }
3661
Craig Mautner4b5aa782012-10-02 18:11:25 -07003662 wtoken.hidden = true;
3663
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003664 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003665 performLayoutAndPlaceSurfacesLocked();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003666 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
3667 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003668 }
Romain Guy06882f82009-06-10 13:36:04 -07003669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003670 if (delayed) {
3671 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003672 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3673 mWallpaperTokens.remove(wtoken);
Craig Mautner918b53b2012-07-09 14:15:54 -07003674 updateLayoutToAnimWallpaperTokens();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003675 }
3676 }
Romain Guy06882f82009-06-10 13:36:04 -07003677
Jeff Brown2e44b072011-01-24 15:21:56 -08003678 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003679 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003680 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003681 }
3682 }
3683 Binder.restoreCallingIdentity(origId);
3684 }
3685
Craig Mautneref25d7a2012-05-15 23:01:47 -07003686 /**
3687 * Find the location to insert a new AppWindowToken into the window-ordered app token list.
3688 * Note that mAppTokens.size() == mAnimatingAppTokens.size() + 1.
3689 * @param addPos The location the token was inserted into in mAppTokens.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003690 * @param atoken The token to insert.
Craig Mautneref25d7a2012-05-15 23:01:47 -07003691 */
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003692 private void addAppTokenToAnimating(final int addPos, final AppWindowToken atoken) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07003693 if (addPos == 0 || addPos == mAnimatingAppTokens.size()) {
3694 // It was inserted into the beginning or end of mAppTokens. Honor that.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003695 mAnimatingAppTokens.add(addPos, atoken);
Craig Mautneref25d7a2012-05-15 23:01:47 -07003696 return;
3697 }
3698 // Find the item immediately above the mAppTokens insertion point and put the token
3699 // immediately below that one in mAnimatingAppTokens.
3700 final AppWindowToken aboveAnchor = mAppTokens.get(addPos + 1);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003701 mAnimatingAppTokens.add(mAnimatingAppTokens.indexOf(aboveAnchor), atoken);
Craig Mautneref25d7a2012-05-15 23:01:47 -07003702 }
3703
3704 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003705 public void addAppToken(int addPos, IApplicationToken token,
Craig Mautner5962b122012-10-05 14:45:52 -07003706 int groupId, int requestedOrientation, boolean fullscreen, boolean showWhenLocked) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003707 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3708 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003709 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003710 }
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07003711
Jeff Brown349703e2010-06-22 01:27:15 -07003712 // Get the dispatching timeout here while we are not holding any locks so that it
3713 // can be cached by the AppWindowToken. The timeout value is used later by the
3714 // input dispatcher in code that does hold locks. If we did not cache the value
3715 // here we would run the chance of introducing a deadlock between the window manager
3716 // (which holds locks while updating the input dispatcher state) and the activity manager
3717 // (which holds locks while querying the application token).
3718 long inputDispatchingTimeoutNanos;
3719 try {
3720 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3721 } catch (RemoteException ex) {
3722 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3723 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3724 }
Romain Guy06882f82009-06-10 13:36:04 -07003725
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003726 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003727 AppWindowToken atoken = findAppWindowToken(token.asBinder());
3728 if (atoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003729 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003730 return;
3731 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003732 atoken = new AppWindowToken(this, token);
3733 atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
3734 atoken.groupId = groupId;
3735 atoken.appFullscreen = fullscreen;
Craig Mautner5962b122012-10-05 14:45:52 -07003736 atoken.showWhenLocked = showWhenLocked;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003737 atoken.requestedOrientation = requestedOrientation;
3738 if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + atoken
Craig Mautner06a94f72012-05-29 10:46:00 -07003739 + " at " + addPos);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003740 mAppTokens.add(addPos, atoken);
3741 addAppTokenToAnimating(addPos, atoken);
3742 mTokenMap.put(token.asBinder(), atoken);
Romain Guy06882f82009-06-10 13:36:04 -07003743
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003744 // Application tokens start out hidden.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003745 atoken.hidden = true;
3746 atoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003748 //dump();
3749 }
3750 }
Romain Guy06882f82009-06-10 13:36:04 -07003751
Craig Mautner9e809442012-06-22 17:13:04 -07003752 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003753 public void setAppGroupId(IBinder token, int groupId) {
3754 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner6fbda632012-07-03 09:26:39 -07003755 "setAppGroupId()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003756 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003757 }
3758
3759 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003760 AppWindowToken atoken = findAppWindowToken(token);
3761 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003762 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003763 return;
3764 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003765 atoken.groupId = groupId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003766 }
3767 }
Romain Guy06882f82009-06-10 13:36:04 -07003768
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003769 public int getOrientationFromWindowsLocked() {
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003770 if (mDisplayFrozen || mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
3771 // If the display is frozen, some activities may be in the middle
3772 // of restarting, and thus have removed their old window. If the
3773 // window has the flag to hide the lock screen, then the lock screen
3774 // can re-appear and inflict its own orientation on us. Keep the
3775 // orientation stable until this all settles down.
3776 return mLastWindowForcedOrientation;
3777 }
3778
Craig Mautner59c00972012-07-30 12:10:24 -07003779 // TODO(multidisplay): Change to the correct display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003780 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07003781 int pos = windows.size() - 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003782 while (pos >= 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07003783 WindowState wtoken = windows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003784 pos--;
3785 if (wtoken.mAppToken != null) {
3786 // We hit an application window. so the orientation will be determined by the
3787 // app window. No point in continuing further.
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003788 return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003789 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003790 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003791 continue;
3792 }
3793 int req = wtoken.mAttrs.screenOrientation;
3794 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3795 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3796 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003797 }
Craig Mautner9e809442012-06-22 17:13:04 -07003798
3799 return (mLastWindowForcedOrientation=req);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003800 }
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003801 return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003802 }
Romain Guy06882f82009-06-10 13:36:04 -07003803
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003804 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003805 int curGroup = 0;
3806 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3807 boolean findingBehind = false;
3808 boolean haveGroup = false;
3809 boolean lastFullscreen = false;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07003810 for (int pos = mAppTokens.size() - 1; pos >= 0; pos--) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003811 AppWindowToken atoken = mAppTokens.get(pos);
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003812
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003813 if (DEBUG_APP_ORIENTATION) Slog.v(TAG, "Checking app orientation: " + atoken);
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003814
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003815 // if we're about to tear down this window and not seek for
3816 // the behind activity, don't use it for orientation
3817 if (!findingBehind
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003818 && (!atoken.hidden && atoken.hiddenRequested)) {
3819 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003820 + " -- going to hide");
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003821 continue;
3822 }
3823
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003824 if (haveGroup == true && curGroup != atoken.groupId) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003825 // If we have hit a new application group, and the bottom
3826 // of the previous group didn't explicitly say to use
3827 // the orientation behind it, and the last app was
3828 // full screen, then we'll stick with the
3829 // user's orientation.
3830 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3831 && lastFullscreen) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003832 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003833 + " -- end of group, return " + lastOrientation);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003834 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003835 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003836 }
p134510445bc62012-04-18 15:13:26 +09003837
3838 // We ignore any hidden applications on the top.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003839 if (atoken.hiddenRequested || atoken.willBeHidden) {
3840 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
p134510445bc62012-04-18 15:13:26 +09003841 + " -- hidden on top");
3842 continue;
3843 }
3844
3845 if (!haveGroup) {
3846 haveGroup = true;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003847 curGroup = atoken.groupId;
3848 lastOrientation = atoken.requestedOrientation;
Craig Mautner918b53b2012-07-09 14:15:54 -07003849 }
p134510445bc62012-04-18 15:13:26 +09003850
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003851 int or = atoken.requestedOrientation;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003852 // If this application is fullscreen, and didn't explicitly say
3853 // to use the orientation behind it, then just take whatever
3854 // orientation it has and ignores whatever is under it.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003855 lastFullscreen = atoken.appFullscreen;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003856 if (lastFullscreen
3857 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003858 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003859 + " -- full screen, return " + or);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003860 return or;
3861 }
3862 // If this application has requested an explicit orientation,
3863 // then use it.
Dianne Hackborne5439f22010-10-02 16:53:50 -07003864 if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
3865 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003866 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003867 + " -- explicitly set, return " + or);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003868 return or;
3869 }
3870 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3871 }
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003872 if (DEBUG_ORIENTATION) Slog.v(TAG, "No app is requesting an orientation");
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003873 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003874 }
Romain Guy06882f82009-06-10 13:36:04 -07003875
Craig Mautner711f90a2012-07-03 18:43:52 -07003876 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003877 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003878 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003879 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3880 "updateOrientationFromAppTokens()")) {
3881 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3882 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003883
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003884 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003885 long ident = Binder.clearCallingIdentity();
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003886
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003887 synchronized(mWindowMap) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003888 config = updateOrientationFromAppTokensLocked(currentConfig,
3889 freezeThisOneIfNeeded);
3890 }
3891
3892 Binder.restoreCallingIdentity(ident);
3893 return config;
3894 }
3895
3896 private Configuration updateOrientationFromAppTokensLocked(
3897 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
3898 Configuration config = null;
3899
3900 if (updateOrientationFromAppTokensLocked(false)) {
3901 if (freezeThisOneIfNeeded != null) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003902 AppWindowToken atoken = findAppWindowToken(
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003903 freezeThisOneIfNeeded);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003904 if (atoken != null) {
3905 startAppFreezingScreenLocked(atoken,
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003906 ActivityInfo.CONFIG_ORIENTATION);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003907 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003908 }
3909 config = computeNewConfigurationLocked();
3910
3911 } else if (currentConfig != null) {
3912 // No obvious action we need to take, but if our current
3913 // state mismatches the activity manager's, update it,
3914 // disregarding font scale, which should remain set to
3915 // the value of the previous configuration.
3916 mTempConfiguration.setToDefaults();
3917 mTempConfiguration.fontScale = currentConfig.fontScale;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08003918 if (computeScreenConfigurationLocked(mTempConfiguration)) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003919 if (currentConfig.diff(mTempConfiguration) != 0) {
3920 mWaitingForConfig = true;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003921 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07003922 startFreezingDisplayLocked(false, 0, 0);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003923 config = new Configuration(mTempConfiguration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003924 }
3925 }
3926 }
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003927
Dianne Hackborncfaef692009-06-15 14:24:44 -07003928 return config;
3929 }
3930
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003931 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003932 * Determine the new desired orientation of the display, returning
3933 * a non-null new Configuration if it has changed from the current
3934 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3935 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3936 * SCREEN. This will typically be done for you if you call
3937 * sendNewConfiguration().
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003938 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003939 * The orientation is computed from non-application windows first. If none of
3940 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003941 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003942 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3943 * android.os.IBinder)
3944 */
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003945 boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003946 long ident = Binder.clearCallingIdentity();
3947 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003948 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003949
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003950 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003951 mForcedAppOrientation = req;
3952 //send a message to Policy indicating orientation change to take
3953 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003954 mPolicy.setCurrentOrientationLw(req);
Jeff Brown01a98dd2011-09-20 15:08:29 -07003955 if (updateRotationUncheckedLocked(inTransaction)) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003956 // changed
3957 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003958 }
3959 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003960
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003961 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003962 } finally {
3963 Binder.restoreCallingIdentity(ident);
3964 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003965 }
Romain Guy06882f82009-06-10 13:36:04 -07003966
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003967 int computeForcedAppOrientationLocked() {
3968 int req = getOrientationFromWindowsLocked();
3969 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3970 req = getOrientationFromAppTokensLocked();
3971 }
3972 return req;
3973 }
Romain Guy06882f82009-06-10 13:36:04 -07003974
Craig Mautner918b53b2012-07-09 14:15:54 -07003975 @Override
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003976 public void setNewConfiguration(Configuration config) {
3977 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3978 "setNewConfiguration()")) {
3979 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3980 }
3981
3982 synchronized(mWindowMap) {
3983 mCurConfiguration = new Configuration(config);
3984 mWaitingForConfig = false;
3985 performLayoutAndPlaceSurfacesLocked();
3986 }
3987 }
Craig Mautner918b53b2012-07-09 14:15:54 -07003988
3989 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003990 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3991 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3992 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003993 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003994 }
Romain Guy06882f82009-06-10 13:36:04 -07003995
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003996 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003997 AppWindowToken atoken = findAppWindowToken(token.asBinder());
3998 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003999 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004000 return;
4001 }
Romain Guy06882f82009-06-10 13:36:04 -07004002
Craig Mautner5c0e78c2012-09-12 16:45:36 -07004003 atoken.requestedOrientation = requestedOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004004 }
4005 }
Romain Guy06882f82009-06-10 13:36:04 -07004006
Craig Mautner76a71652012-09-03 23:23:58 -07004007 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004008 public int getAppOrientation(IApplicationToken token) {
4009 synchronized(mWindowMap) {
4010 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
4011 if (wtoken == null) {
4012 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4013 }
Romain Guy06882f82009-06-10 13:36:04 -07004014
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004015 return wtoken.requestedOrientation;
4016 }
4017 }
Romain Guy06882f82009-06-10 13:36:04 -07004018
Craig Mautner76a71652012-09-03 23:23:58 -07004019 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004020 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
4021 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4022 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004023 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004024 }
4025
4026 synchronized(mWindowMap) {
4027 boolean changed = false;
4028 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004029 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004030 changed = mFocusedApp != null;
4031 mFocusedApp = null;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004032 if (changed) {
4033 mInputMonitor.setFocusedAppLw(null);
Jeff Brown349703e2010-06-22 01:27:15 -07004034 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004035 } else {
4036 AppWindowToken newFocus = findAppWindowToken(token);
4037 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004038 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004039 return;
4040 }
4041 changed = mFocusedApp != newFocus;
4042 mFocusedApp = newFocus;
Craig Mautner812d2ca2012-09-27 15:35:34 -07004043 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp
4044 + " moveFocusNow=" + moveFocusNow);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004045 if (changed) {
4046 mInputMonitor.setFocusedAppLw(newFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07004047 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004048 }
4049
4050 if (moveFocusNow && changed) {
4051 final long origId = Binder.clearCallingIdentity();
Jeff Brown3a22cd92011-01-21 13:59:04 -08004052 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004053 Binder.restoreCallingIdentity(origId);
4054 }
4055 }
4056 }
4057
Craig Mautner76a71652012-09-03 23:23:58 -07004058 @Override
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08004059 public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004060 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4061 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004062 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004063 }
Romain Guy06882f82009-06-10 13:36:04 -07004064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004065 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004066 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004067 TAG, "Prepare app transition: transit=" + transit
Craig Mautner0afddcb2012-05-08 15:38:00 -07004068 + " mNextAppTransition=" + mNextAppTransition
Craig Mautner1d961d42012-05-27 12:02:11 -07004069 + " alwaysKeepCurrent=" + alwaysKeepCurrent
Craig Mautneref25d7a2012-05-15 23:01:47 -07004070 + " Callers=" + Debug.getCallers(3));
Craig Mautner2fb98b12012-03-20 17:24:00 -07004071 if (okToDisplay()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004072 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
4073 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004074 mNextAppTransition = transit;
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08004075 } else if (!alwaysKeepCurrent) {
4076 if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
4077 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
4078 // Opening a new task always supersedes a close for the anim.
4079 mNextAppTransition = transit;
4080 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
4081 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
4082 // Opening a new activity always supersedes a close for the anim.
4083 mNextAppTransition = transit;
4084 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004085 }
4086 mAppTransitionReady = false;
4087 mAppTransitionTimeout = false;
4088 mStartingIconInTransition = false;
4089 mSkipAppTransitionAnimation = false;
4090 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
4091 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
4092 5000);
4093 }
4094 }
4095 }
4096
Craig Mautner5c0e78c2012-09-12 16:45:36 -07004097 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004098 public int getPendingAppTransition() {
4099 return mNextAppTransition;
4100 }
Romain Guy06882f82009-06-10 13:36:04 -07004101
Dianne Hackborn84375872012-06-01 19:03:50 -07004102 private void scheduleAnimationCallback(IRemoteCallback cb) {
4103 if (cb != null) {
4104 mH.sendMessage(mH.obtainMessage(H.DO_ANIMATION_CALLBACK, cb));
4105 }
4106 }
4107
Craig Mautner5c0e78c2012-09-12 16:45:36 -07004108 @Override
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07004109 public void overridePendingAppTransition(String packageName,
Dianne Hackborn84375872012-06-01 19:03:50 -07004110 int enterAnim, int exitAnim, IRemoteCallback startedCallback) {
4111 synchronized(mWindowMap) {
4112 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
4113 mNextAppTransitionType = ActivityOptions.ANIM_CUSTOM;
4114 mNextAppTransitionPackage = packageName;
4115 mNextAppTransitionThumbnail = null;
4116 mNextAppTransitionEnter = enterAnim;
4117 mNextAppTransitionExit = exitAnim;
4118 scheduleAnimationCallback(mNextAppTransitionCallback);
4119 mNextAppTransitionCallback = startedCallback;
4120 } else {
4121 scheduleAnimationCallback(startedCallback);
4122 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07004123 }
4124 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004125
Craig Mautnera91f9e22012-09-14 16:22:08 -07004126 @Override
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07004127 public void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
4128 int startHeight) {
Dianne Hackborn84375872012-06-01 19:03:50 -07004129 synchronized(mWindowMap) {
4130 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
4131 mNextAppTransitionType = ActivityOptions.ANIM_SCALE_UP;
4132 mNextAppTransitionPackage = null;
4133 mNextAppTransitionThumbnail = null;
4134 mNextAppTransitionStartX = startX;
4135 mNextAppTransitionStartY = startY;
4136 mNextAppTransitionStartWidth = startWidth;
4137 mNextAppTransitionStartHeight = startHeight;
4138 scheduleAnimationCallback(mNextAppTransitionCallback);
4139 mNextAppTransitionCallback = null;
4140 }
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07004141 }
4142 }
4143
Craig Mautnera91f9e22012-09-14 16:22:08 -07004144 @Override
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004145 public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX,
Michael Jurka832cb222012-04-13 09:32:47 -07004146 int startY, IRemoteCallback startedCallback, boolean scaleUp) {
Dianne Hackborn84375872012-06-01 19:03:50 -07004147 synchronized(mWindowMap) {
4148 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Michael Jurka832cb222012-04-13 09:32:47 -07004149 mNextAppTransitionType = scaleUp
4150 ? ActivityOptions.ANIM_THUMBNAIL_SCALE_UP : ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN;
Dianne Hackborn84375872012-06-01 19:03:50 -07004151 mNextAppTransitionPackage = null;
4152 mNextAppTransitionThumbnail = srcThumb;
Michael Jurka832cb222012-04-13 09:32:47 -07004153 mNextAppTransitionScaleUp = scaleUp;
Dianne Hackborn84375872012-06-01 19:03:50 -07004154 mNextAppTransitionStartX = startX;
4155 mNextAppTransitionStartY = startY;
4156 scheduleAnimationCallback(mNextAppTransitionCallback);
4157 mNextAppTransitionCallback = startedCallback;
4158 } else {
4159 scheduleAnimationCallback(startedCallback);
4160 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004161 }
4162 }
4163
Craig Mautnera91f9e22012-09-14 16:22:08 -07004164 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004165 public void executeAppTransition() {
4166 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4167 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004168 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004169 }
Romain Guy06882f82009-06-10 13:36:04 -07004170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004171 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07004172 if (DEBUG_APP_TRANSITIONS) {
4173 RuntimeException e = new RuntimeException("here");
4174 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004175 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07004176 + mNextAppTransition, e);
4177 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004178 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004179 mAppTransitionReady = true;
4180 final long origId = Binder.clearCallingIdentity();
4181 performLayoutAndPlaceSurfacesLocked();
4182 Binder.restoreCallingIdentity(origId);
4183 }
4184 }
4185 }
4186
4187 public void setAppStartingWindow(IBinder token, String pkg,
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07004188 int theme, CompatibilityInfo compatInfo,
4189 CharSequence nonLocalizedLabel, int labelRes, int icon,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08004190 int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004191 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner6fbda632012-07-03 09:26:39 -07004192 "setAppStartingWindow()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004193 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004194 }
4195
4196 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004197 if (DEBUG_STARTING_WINDOW) Slog.v(
Craig Mautner8863cca2012-09-18 15:04:34 -07004198 TAG, "setAppStartingWindow: token=" + token + " pkg=" + pkg
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004199 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07004200
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004201 AppWindowToken wtoken = findAppWindowToken(token);
4202 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004203 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004204 return;
4205 }
4206
4207 // If the display is frozen, we won't do anything until the
4208 // actual window is displayed so there is no reason to put in
4209 // the starting window.
Craig Mautner2fb98b12012-03-20 17:24:00 -07004210 if (!okToDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004211 return;
4212 }
Romain Guy06882f82009-06-10 13:36:04 -07004213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004214 if (wtoken.startingData != null) {
4215 return;
4216 }
Romain Guy06882f82009-06-10 13:36:04 -07004217
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004218 if (transferFrom != null) {
4219 AppWindowToken ttoken = findAppWindowToken(transferFrom);
4220 if (ttoken != null) {
4221 WindowState startingWindow = ttoken.startingWindow;
4222 if (startingWindow != null) {
4223 if (mStartingIconInTransition) {
4224 // In this case, the starting icon has already
4225 // been displayed, so start letting windows get
4226 // shown immediately without any more transitions.
4227 mSkipAppTransitionAnimation = true;
4228 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004229 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
Craig Mautner8863cca2012-09-18 15:04:34 -07004230 "Moving existing starting " + startingWindow + " from " + ttoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004231 + " to " + wtoken);
4232 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07004233
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004234 // Transfer the starting window over to the new
4235 // token.
4236 wtoken.startingData = ttoken.startingData;
4237 wtoken.startingView = ttoken.startingView;
Craig Mautnerf4120952012-06-21 18:25:39 -07004238 wtoken.startingDisplayed = ttoken.startingDisplayed;
Craig Mautner8863cca2012-09-18 15:04:34 -07004239 ttoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004240 wtoken.startingWindow = startingWindow;
Craig Mautnerf4120952012-06-21 18:25:39 -07004241 wtoken.reportedVisible = ttoken.reportedVisible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004242 ttoken.startingData = null;
4243 ttoken.startingView = null;
4244 ttoken.startingWindow = null;
4245 ttoken.startingMoved = true;
4246 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07004247 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004248 startingWindow.mAppToken = wtoken;
Craig Mautner8863cca2012-09-18 15:04:34 -07004249 startingWindow.mWinAnimator.mAppAnimator = wtoken.mAppAnimator;
4250
Craig Mautner6fbda632012-07-03 09:26:39 -07004251 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) {
4252 Slog.v(TAG, "Removing starting window: " + startingWindow);
4253 }
Craig Mautner59c00972012-07-30 12:10:24 -07004254 startingWindow.getWindowList().remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004255 mWindowsChanged = true;
Craig Mautner6fbda632012-07-03 09:26:39 -07004256 if (DEBUG_ADD_REMOVE) Slog.v(TAG,
4257 "Removing starting " + startingWindow + " from " + ttoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004258 ttoken.windows.remove(startingWindow);
4259 ttoken.allAppWindows.remove(startingWindow);
4260 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07004261
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004262 // Propagate other interesting state between the
4263 // tokens. If the old token is displayed, we should
4264 // immediately force the new one to be displayed. If
4265 // it is animating, we need to move that animation to
4266 // the new one.
4267 if (ttoken.allDrawn) {
4268 wtoken.allDrawn = true;
4269 }
4270 if (ttoken.firstWindowDrawn) {
4271 wtoken.firstWindowDrawn = true;
4272 }
4273 if (!ttoken.hidden) {
4274 wtoken.hidden = false;
4275 wtoken.hiddenRequested = false;
4276 wtoken.willBeHidden = false;
4277 }
4278 if (wtoken.clientHidden != ttoken.clientHidden) {
4279 wtoken.clientHidden = ttoken.clientHidden;
4280 wtoken.sendAppVisibilityToClients();
4281 }
Craig Mautner59431632012-04-04 11:56:44 -07004282 final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
4283 final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
4284 if (tAppAnimator.animation != null) {
4285 wAppAnimator.animation = tAppAnimator.animation;
4286 wAppAnimator.animating = tAppAnimator.animating;
4287 wAppAnimator.animLayerAdjustment = tAppAnimator.animLayerAdjustment;
4288 tAppAnimator.animation = null;
4289 tAppAnimator.animLayerAdjustment = 0;
4290 wAppAnimator.updateLayers();
4291 tAppAnimator.updateLayers();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004292 }
Romain Guy06882f82009-06-10 13:36:04 -07004293
Jeff Brown3a22cd92011-01-21 13:59:04 -08004294 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4295 true /*updateInputWindows*/);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07004296 getDefaultDisplayContentLocked().layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004297 performLayoutAndPlaceSurfacesLocked();
4298 Binder.restoreCallingIdentity(origId);
4299 return;
4300 } else if (ttoken.startingData != null) {
4301 // The previous app was getting ready to show a
4302 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004303 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004304 "Moving pending starting from " + ttoken
4305 + " to " + wtoken);
4306 wtoken.startingData = ttoken.startingData;
4307 ttoken.startingData = null;
4308 ttoken.startingMoved = true;
4309 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
4310 // Note: we really want to do sendMessageAtFrontOfQueue() because we
4311 // want to process the message ASAP, before any other queued
4312 // messages.
4313 mH.sendMessageAtFrontOfQueue(m);
4314 return;
4315 }
Craig Mautner59431632012-04-04 11:56:44 -07004316 final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
4317 final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
4318 if (tAppAnimator.thumbnail != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004319 // The old token is animating with a thumbnail, transfer
4320 // that to the new token.
Craig Mautner59431632012-04-04 11:56:44 -07004321 if (wAppAnimator.thumbnail != null) {
4322 wAppAnimator.thumbnail.destroy();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004323 }
Craig Mautner59431632012-04-04 11:56:44 -07004324 wAppAnimator.thumbnail = tAppAnimator.thumbnail;
4325 wAppAnimator.thumbnailX = tAppAnimator.thumbnailX;
4326 wAppAnimator.thumbnailY = tAppAnimator.thumbnailY;
4327 wAppAnimator.thumbnailLayer = tAppAnimator.thumbnailLayer;
4328 wAppAnimator.thumbnailAnimation = tAppAnimator.thumbnailAnimation;
4329 tAppAnimator.thumbnail = null;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004330 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004331 }
4332 }
4333
4334 // There is no existing starting window, and the caller doesn't
4335 // want us to create one, so that's it!
4336 if (!createIfNeeded) {
4337 return;
4338 }
Romain Guy06882f82009-06-10 13:36:04 -07004339
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08004340 // If this is a translucent window, then don't
Dianne Hackborn284ac932009-08-28 10:34:25 -07004341 // show a starting window -- the current effect (a full-screen
4342 // opaque starting window that fades away to the real contents
4343 // when it is ready) does not work for this.
Craig Mautner6fbda632012-07-03 09:26:39 -07004344 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Checking theme of starting window: 0x"
4345 + Integer.toHexString(theme));
Dianne Hackborn284ac932009-08-28 10:34:25 -07004346 if (theme != 0) {
4347 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
4348 com.android.internal.R.styleable.Window);
Dianne Hackborn0b800192012-06-21 15:29:36 -07004349 if (ent == null) {
4350 // Whoops! App doesn't exist. Um. Okay. We'll just
4351 // pretend like we didn't see that.
4352 return;
4353 }
Craig Mautner6fbda632012-07-03 09:26:39 -07004354 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Translucent="
4355 + ent.array.getBoolean(
4356 com.android.internal.R.styleable.Window_windowIsTranslucent, false)
4357 + " Floating="
4358 + ent.array.getBoolean(
4359 com.android.internal.R.styleable.Window_windowIsFloating, false)
4360 + " ShowWallpaper="
4361 + ent.array.getBoolean(
4362 com.android.internal.R.styleable.Window_windowShowWallpaper, false));
Dianne Hackborn284ac932009-08-28 10:34:25 -07004363 if (ent.array.getBoolean(
4364 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
4365 return;
4366 }
4367 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07004368 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
4369 return;
4370 }
4371 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07004372 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08004373 if (mWallpaperTarget == null) {
4374 // If this theme is requesting a wallpaper, and the wallpaper
4375 // is not curently visible, then this effectively serves as
4376 // an opaque window and our starting window transition animation
4377 // can still work. We just need to make sure the starting window
4378 // is also showing the wallpaper.
Craig Mautner65d11b32012-10-01 13:59:52 -07004379 windowFlags |= FLAG_SHOW_WALLPAPER;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08004380 } else {
4381 return;
4382 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07004383 }
4384 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004385
Craig Mautner6fbda632012-07-03 09:26:39 -07004386 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Creating StartingData");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004387 mStartingIconInTransition = true;
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07004388 wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08004389 labelRes, icon, windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004390 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
4391 // Note: we really want to do sendMessageAtFrontOfQueue() because we
4392 // want to process the message ASAP, before any other queued
4393 // messages.
Craig Mautner6fbda632012-07-03 09:26:39 -07004394 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Enqueueing ADD_STARTING");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004395 mH.sendMessageAtFrontOfQueue(m);
4396 }
4397 }
4398
4399 public void setAppWillBeHidden(IBinder token) {
4400 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4401 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004402 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004403 }
4404
4405 AppWindowToken wtoken;
4406
4407 synchronized(mWindowMap) {
4408 wtoken = findAppWindowToken(token);
4409 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004410 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 -08004411 return;
4412 }
4413 wtoken.willBeHidden = true;
4414 }
4415 }
Romain Guy06882f82009-06-10 13:36:04 -07004416
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004417 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004418 boolean visible, int transit, boolean performLayout) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004419 boolean delayed = false;
4420
4421 if (wtoken.clientHidden == visible) {
4422 wtoken.clientHidden = !visible;
4423 wtoken.sendAppVisibilityToClients();
4424 }
Romain Guy06882f82009-06-10 13:36:04 -07004425
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004426 wtoken.willBeHidden = false;
4427 if (wtoken.hidden == visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004428 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004429 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004430 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
4431 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07004432
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004433 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07004434
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004435 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
Craig Mautnerfbf378c2012-04-23 17:24:21 -07004436 if (wtoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) {
Craig Mautner59431632012-04-04 11:56:44 -07004437 wtoken.mAppAnimator.animation = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004438 }
Craig Mautnerf20588f2012-04-11 17:06:21 -07004439 if (applyAnimationLocked(wtoken, lp, transit, visible)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004440 delayed = runningAppAnimation = true;
4441 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07004442 WindowState window = wtoken.findMainWindow();
4443 if (window != null) {
4444 scheduleNotifyWindowTranstionIfNeededLocked(window, transit);
4445 }
Craig Mautnerf20588f2012-04-11 17:06:21 -07004446 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004447 }
Romain Guy06882f82009-06-10 13:36:04 -07004448
Craig Mautnerf20588f2012-04-11 17:06:21 -07004449 final int N = wtoken.allAppWindows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004450 for (int i=0; i<N; i++) {
4451 WindowState win = wtoken.allAppWindows.get(i);
4452 if (win == wtoken.startingWindow) {
4453 continue;
4454 }
4455
Joe Onorato8a9b2202010-02-26 18:56:32 -08004456 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004457 //win.dump(" ");
4458 if (visible) {
4459 if (!win.isVisibleNow()) {
4460 if (!runningAppAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07004461 win.mWinAnimator.applyAnimationLocked(
4462 WindowManagerPolicy.TRANSIT_ENTER, true);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07004463 scheduleNotifyWindowTranstionIfNeededLocked(win,
4464 WindowManagerPolicy.TRANSIT_ENTER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004465 }
4466 changed = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07004467 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004468 }
4469 } else if (win.isVisibleNow()) {
4470 if (!runningAppAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07004471 win.mWinAnimator.applyAnimationLocked(
4472 WindowManagerPolicy.TRANSIT_EXIT, false);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07004473 scheduleNotifyWindowTranstionIfNeededLocked(win,
4474 WindowManagerPolicy.TRANSIT_EXIT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004475 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004476 changed = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07004477 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004478 }
4479 }
4480
4481 wtoken.hidden = wtoken.hiddenRequested = !visible;
4482 if (!visible) {
4483 unsetAppFreezingScreenLocked(wtoken, true, true);
4484 } else {
4485 // If we are being set visible, and the starting window is
4486 // not yet displayed, then make sure it doesn't get displayed.
4487 WindowState swin = wtoken.startingWindow;
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07004488 if (swin != null && !swin.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004489 swin.mPolicyVisibility = false;
4490 swin.mPolicyVisibilityAfterAnim = false;
4491 }
4492 }
Romain Guy06882f82009-06-10 13:36:04 -07004493
Joe Onorato8a9b2202010-02-26 18:56:32 -08004494 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004495 + ": hidden=" + wtoken.hidden + " hiddenRequested="
4496 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07004497
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004498 if (changed) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08004499 mInputMonitor.setUpdateInputWindowsNeededLw();
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004500 if (performLayout) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08004501 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4502 false /*updateInputWindows*/);
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004503 performLayoutAndPlaceSurfacesLocked();
4504 }
Jeff Brown2e44b072011-01-24 15:21:56 -08004505 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004506 }
4507 }
4508
Craig Mautner59431632012-04-04 11:56:44 -07004509 if (wtoken.mAppAnimator.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004510 delayed = true;
4511 }
Romain Guy06882f82009-06-10 13:36:04 -07004512
Craig Mautnerf20588f2012-04-11 17:06:21 -07004513 for (int i = wtoken.allAppWindows.size() - 1; i >= 0 && !delayed; i--) {
4514 if (wtoken.allAppWindows.get(i).mWinAnimator.isWindowAnimating()) {
4515 delayed = true;
4516 }
4517 }
4518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004519 return delayed;
4520 }
4521
4522 public void setAppVisibility(IBinder token, boolean visible) {
4523 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4524 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004525 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004526 }
4527
4528 AppWindowToken wtoken;
4529
4530 synchronized(mWindowMap) {
4531 wtoken = findAppWindowToken(token);
4532 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004533 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004534 return;
4535 }
4536
4537 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004538 RuntimeException e = null;
4539 if (!HIDE_STACK_CRAWLS) {
4540 e = new RuntimeException();
4541 e.fillInStackTrace();
4542 }
Craig Mautner0afddcb2012-05-08 15:38:00 -07004543 Slog.v(TAG, "setAppVisibility(" + token + ", visible=" + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004544 + "): mNextAppTransition=" + mNextAppTransition
4545 + " hidden=" + wtoken.hidden
4546 + " hiddenRequested=" + wtoken.hiddenRequested, e);
4547 }
Romain Guy06882f82009-06-10 13:36:04 -07004548
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004549 // If we are preparing an app transition, then delay changing
4550 // the visibility of this token until we execute that transition.
Craig Mautner2fb98b12012-03-20 17:24:00 -07004551 if (okToDisplay() && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004552 // Already in requested state, don't do anything more.
4553 if (wtoken.hiddenRequested != visible) {
4554 return;
4555 }
4556 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07004557
Craig Mautnerf4120952012-06-21 18:25:39 -07004558 if (!wtoken.startingDisplayed) {
Craig Mautner8863cca2012-09-18 15:04:34 -07004559 if (DEBUG_APP_TRANSITIONS) Slog.v(
4560 TAG, "Setting dummy animation on: " + wtoken);
Craig Mautnerf4120952012-06-21 18:25:39 -07004561 wtoken.mAppAnimator.setDummyAnimation();
4562 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004563 mOpeningApps.remove(wtoken);
4564 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004565 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004566 wtoken.inPendingTransaction = true;
4567 if (visible) {
4568 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004569 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004570
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004571 // If the token is currently hidden (should be the
4572 // common case), then we need to set up to wait for
4573 // its windows to be ready.
4574 if (wtoken.hidden) {
4575 wtoken.allDrawn = false;
4576 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004577
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004578 if (wtoken.clientHidden) {
4579 // In the case where we are making an app visible
4580 // but holding off for a transition, we still need
4581 // to tell the client to make its windows visible so
4582 // they get drawn. Otherwise, we will wait on
4583 // performing the transition until all windows have
4584 // been drawn, they never will be, and we are sad.
4585 wtoken.clientHidden = false;
4586 wtoken.sendAppVisibilityToClients();
4587 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004588 }
4589 } else {
4590 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004591
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004592 // If the token is currently visible (should be the
4593 // common case), then set up to wait for it to be hidden.
4594 if (!wtoken.hidden) {
4595 wtoken.waitingToHide = true;
4596 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004597 }
4598 return;
4599 }
Romain Guy06882f82009-06-10 13:36:04 -07004600
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004601 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004602 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004603 true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004604 wtoken.updateReportedVisibilityLocked();
4605 Binder.restoreCallingIdentity(origId);
4606 }
4607 }
4608
4609 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
4610 boolean unfreezeSurfaceNow, boolean force) {
Craig Mautner59431632012-04-04 11:56:44 -07004611 if (wtoken.mAppAnimator.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004612 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004613 + " force=" + force);
4614 final int N = wtoken.allAppWindows.size();
4615 boolean unfrozeWindows = false;
4616 for (int i=0; i<N; i++) {
4617 WindowState w = wtoken.allAppWindows.get(i);
4618 if (w.mAppFreezing) {
4619 w.mAppFreezing = false;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07004620 if (w.mHasSurface && !w.mOrientationChanging) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07004621 if (DEBUG_ORIENTATION) Slog.v(TAG, "set mOrientationChanging of " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004622 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07004623 mInnerFields.mOrientationChangeComplete = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004624 }
4625 unfrozeWindows = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07004626 w.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004627 }
4628 }
4629 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004630 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
Craig Mautner59431632012-04-04 11:56:44 -07004631 wtoken.mAppAnimator.freezingScreen = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004632 mAppsFreezingScreen--;
4633 }
4634 if (unfreezeSurfaceNow) {
4635 if (unfrozeWindows) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004636 performLayoutAndPlaceSurfacesLocked();
4637 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004638 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004639 }
4640 }
4641 }
Romain Guy06882f82009-06-10 13:36:04 -07004642
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004643 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
4644 int configChanges) {
4645 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004646 RuntimeException e = null;
4647 if (!HIDE_STACK_CRAWLS) {
4648 e = new RuntimeException();
4649 e.fillInStackTrace();
4650 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004651 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004652 + ": hidden=" + wtoken.hidden + " freezing="
Craig Mautner59431632012-04-04 11:56:44 -07004653 + wtoken.mAppAnimator.freezingScreen, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004654 }
4655 if (!wtoken.hiddenRequested) {
Craig Mautner59431632012-04-04 11:56:44 -07004656 if (!wtoken.mAppAnimator.freezingScreen) {
4657 wtoken.mAppAnimator.freezingScreen = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004658 mAppsFreezingScreen++;
4659 if (mAppsFreezingScreen == 1) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07004660 startFreezingDisplayLocked(false, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004661 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
4662 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
4663 5000);
4664 }
4665 }
4666 final int N = wtoken.allAppWindows.size();
4667 for (int i=0; i<N; i++) {
4668 WindowState w = wtoken.allAppWindows.get(i);
4669 w.mAppFreezing = true;
4670 }
4671 }
4672 }
Romain Guy06882f82009-06-10 13:36:04 -07004673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004674 public void startAppFreezingScreen(IBinder token, int configChanges) {
4675 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4676 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004677 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004678 }
4679
4680 synchronized(mWindowMap) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07004681 if (configChanges == 0 && okToDisplay()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004682 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004683 return;
4684 }
Romain Guy06882f82009-06-10 13:36:04 -07004685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004686 AppWindowToken wtoken = findAppWindowToken(token);
4687 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004688 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004689 return;
4690 }
4691 final long origId = Binder.clearCallingIdentity();
4692 startAppFreezingScreenLocked(wtoken, configChanges);
4693 Binder.restoreCallingIdentity(origId);
4694 }
4695 }
Romain Guy06882f82009-06-10 13:36:04 -07004696
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004697 public void stopAppFreezingScreen(IBinder token, boolean force) {
4698 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4699 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004700 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004701 }
4702
4703 synchronized(mWindowMap) {
4704 AppWindowToken wtoken = findAppWindowToken(token);
4705 if (wtoken == null || wtoken.appToken == null) {
4706 return;
4707 }
4708 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004709 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
Craig Mautner59431632012-04-04 11:56:44 -07004710 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.mAppAnimator.freezingScreen);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004711 unsetAppFreezingScreenLocked(wtoken, true, force);
4712 Binder.restoreCallingIdentity(origId);
4713 }
4714 }
Romain Guy06882f82009-06-10 13:36:04 -07004715
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004716 public void removeAppToken(IBinder token) {
4717 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4718 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004719 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004720 }
4721
4722 AppWindowToken wtoken = null;
4723 AppWindowToken startingToken = null;
4724 boolean delayed = false;
4725
4726 final long origId = Binder.clearCallingIdentity();
4727 synchronized(mWindowMap) {
4728 WindowToken basewtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004729 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004730 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004731 delayed = setTokenVisibilityLocked(wtoken, null, false,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004732 WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004733 wtoken.inPendingTransaction = false;
4734 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004735 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004736 if (mClosingApps.contains(wtoken)) {
4737 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004738 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004739 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004740 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004741 delayed = true;
4742 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004743 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004744 TAG, "Removing app " + wtoken + " delayed=" + delayed
Craig Mautner59431632012-04-04 11:56:44 -07004745 + " animation=" + wtoken.mAppAnimator.animation
4746 + " animating=" + wtoken.mAppAnimator.animating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004747 if (delayed) {
4748 // set the token aside because it has an active animation to be finished
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004749 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4750 "removeAppToken make exiting: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004751 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004752 } else {
4753 // Make sure there is no animation running on this token,
4754 // so any windows associated with it will be removed as
4755 // soon as their animations are complete
Craig Mautner59431632012-04-04 11:56:44 -07004756 wtoken.mAppAnimator.clearAnimation();
4757 wtoken.mAppAnimator.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004758 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004759 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4760 "removeAppToken: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004761 mAppTokens.remove(wtoken);
Craig Mautneref25d7a2012-05-15 23:01:47 -07004762 mAnimatingAppTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004763 wtoken.removed = true;
4764 if (wtoken.startingData != null) {
4765 startingToken = wtoken;
4766 }
4767 unsetAppFreezingScreenLocked(wtoken, true, true);
4768 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004769 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004770 mFocusedApp = null;
Jeff Brown3a22cd92011-01-21 13:59:04 -08004771 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004772 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004773 }
4774 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004775 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004776 }
Romain Guy06882f82009-06-10 13:36:04 -07004777
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004778 if (!delayed && wtoken != null) {
4779 wtoken.updateReportedVisibilityLocked();
4780 }
4781 }
4782 Binder.restoreCallingIdentity(origId);
4783
4784 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004785 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004786 + startingToken + ": app token removed");
4787 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
4788 mH.sendMessage(m);
4789 }
4790 }
4791
4792 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
4793 final int NW = token.windows.size();
Craig Mautneref25d7a2012-05-15 23:01:47 -07004794 if (NW > 0) {
4795 mWindowsChanged = true;
4796 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004797 for (int i=0; i<NW; i++) {
4798 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004799 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
Craig Mautner59c00972012-07-30 12:10:24 -07004800 win.getWindowList().remove(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004801 int j = win.mChildWindows.size();
4802 while (j > 0) {
4803 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004804 WindowState cwin = win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004805 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004806 "Tmp removing child window " + cwin);
Craig Mautner59c00972012-07-30 12:10:24 -07004807 cwin.getWindowList().remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004808 }
4809 }
4810 return NW > 0;
4811 }
4812
4813 void dumpAppTokensLocked() {
4814 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004815 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004816 }
4817 }
Romain Guy06882f82009-06-10 13:36:04 -07004818
Craig Mautneref25d7a2012-05-15 23:01:47 -07004819 void dumpAnimatingAppTokensLocked() {
4820 for (int i=mAnimatingAppTokens.size()-1; i>=0; i--) {
4821 Slog.v(TAG, " #" + i + ": " + mAnimatingAppTokens.get(i).token);
4822 }
4823 }
4824
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004825 void dumpWindowsLocked() {
Craig Mautner59c00972012-07-30 12:10:24 -07004826 int i = 0;
4827 final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
4828 while (iterator.hasNext()) {
4829 final WindowState w = iterator.next();
4830 Slog.v(TAG, " #" + i++ + ": " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004831 }
4832 }
Romain Guy06882f82009-06-10 13:36:04 -07004833
Craig Mautner59c00972012-07-30 12:10:24 -07004834 private int findWindowOffsetLocked(WindowList windows, int tokenPos) {
4835 final int NW = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004836
Craig Mautneref25d7a2012-05-15 23:01:47 -07004837 if (tokenPos >= mAnimatingAppTokens.size()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004838 int i = NW;
4839 while (i > 0) {
4840 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07004841 WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004842 if (win.getAppToken() != null) {
4843 return i+1;
4844 }
4845 }
4846 }
4847
4848 while (tokenPos > 0) {
4849 // Find the first app token below the new position that has
4850 // a window displayed.
Craig Mautner59c00972012-07-30 12:10:24 -07004851 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004852 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004853 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004854 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004855 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07004856 "Skipping token -- currently sending to bottom");
4857 tokenPos--;
4858 continue;
4859 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004860 int i = wtoken.windows.size();
4861 while (i > 0) {
4862 i--;
4863 WindowState win = wtoken.windows.get(i);
4864 int j = win.mChildWindows.size();
4865 while (j > 0) {
4866 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004867 WindowState cwin = win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004868 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004869 for (int pos=NW-1; pos>=0; pos--) {
Craig Mautner59c00972012-07-30 12:10:24 -07004870 if (windows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004871 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004872 "Found child win @" + (pos+1));
4873 return pos+1;
4874 }
4875 }
4876 }
4877 }
4878 for (int pos=NW-1; pos>=0; pos--) {
Craig Mautner59c00972012-07-30 12:10:24 -07004879 if (windows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004880 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004881 return pos+1;
4882 }
4883 }
4884 }
4885 tokenPos--;
4886 }
4887
4888 return 0;
4889 }
4890
4891 private final int reAddWindowLocked(int index, WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -07004892 final WindowList windows = win.getWindowList();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004893 final int NCW = win.mChildWindows.size();
4894 boolean added = false;
4895 for (int j=0; j<NCW; j++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004896 WindowState cwin = win.mChildWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004897 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004898 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004899 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004900 win.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004901 windows.add(index, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004902 index++;
4903 added = true;
4904 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004905 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004906 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004907 cwin.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004908 windows.add(index, cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004909 index++;
4910 }
4911 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004912 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004913 + index + ": " + win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004914 win.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004915 windows.add(index, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004916 index++;
4917 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004918 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004919 return index;
4920 }
Romain Guy06882f82009-06-10 13:36:04 -07004921
Craig Mautner59c00972012-07-30 12:10:24 -07004922 private final int reAddAppWindowsLocked(final DisplayContent displayContent, int index,
4923 WindowToken token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004924 final int NW = token.windows.size();
4925 for (int i=0; i<NW; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07004926 final WindowState win = token.windows.get(i);
4927 if (win.mDisplayContent == displayContent) {
Craig Mautner69b08182012-09-05 13:07:13 -07004928 index = reAddWindowLocked(index, win);
Craig Mautner59c00972012-07-30 12:10:24 -07004929 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004930 }
4931 return index;
4932 }
4933
4934 public void moveAppToken(int index, IBinder token) {
4935 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4936 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004937 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004938 }
4939
4940 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004941 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004942 if (DEBUG_REORDER) dumpAppTokensLocked();
4943 final AppWindowToken wtoken = findAppWindowToken(token);
Craig Mautneref25d7a2012-05-15 23:01:47 -07004944 final int oldIndex = mAppTokens.indexOf(wtoken);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004945 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
4946 "Start moving token " + wtoken + " initially at "
Craig Mautneref25d7a2012-05-15 23:01:47 -07004947 + oldIndex);
4948 if (oldIndex > index && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET
4949 && !mAppTransitionRunning) {
4950 // animation towards back has not started, copy old list for duration of animation.
4951 mAnimatingAppTokens.clear();
4952 mAnimatingAppTokens.addAll(mAppTokens);
4953 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004954 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004955 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004956 + token + " (" + wtoken + ")");
4957 return;
4958 }
4959 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004960 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004961 else if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "Moved " + token + " to " + index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004962 if (DEBUG_REORDER) dumpAppTokensLocked();
Craig Mautneref25d7a2012-05-15 23:01:47 -07004963 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET && !mAppTransitionRunning) {
4964 // Not animating, bring animating app list in line with mAppTokens.
4965 mAnimatingAppTokens.clear();
4966 mAnimatingAppTokens.addAll(mAppTokens);
Romain Guy06882f82009-06-10 13:36:04 -07004967
Craig Mautneref25d7a2012-05-15 23:01:47 -07004968 // Bring window ordering, window focus and input window in line with new app token
4969 final long origId = Binder.clearCallingIdentity();
4970 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004971 if (DEBUG_REORDER) dumpWindowsLocked();
Craig Mautneref25d7a2012-05-15 23:01:47 -07004972 if (tmpRemoveAppWindowsLocked(wtoken)) {
4973 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
4974 if (DEBUG_REORDER) dumpWindowsLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07004975 DisplayContentsIterator iterator = new DisplayContentsIterator();
4976 while(iterator.hasNext()) {
4977 final DisplayContent displayContent = iterator.next();
4978 final WindowList windows = displayContent.getWindowList();
4979 final int pos = findWindowOffsetLocked(windows, index);
Craig Mautner19d59bc2012-09-04 11:15:56 -07004980 final int newPos = reAddAppWindowsLocked(displayContent, pos, wtoken);
4981 if (pos != newPos) {
4982 displayContent.layoutNeeded = true;
4983 }
Craig Mautner59c00972012-07-30 12:10:24 -07004984 }
Craig Mautneref25d7a2012-05-15 23:01:47 -07004985 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
4986 if (DEBUG_REORDER) dumpWindowsLocked();
4987 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4988 false /*updateInputWindows*/);
Craig Mautneref25d7a2012-05-15 23:01:47 -07004989 mInputMonitor.setUpdateInputWindowsNeededLw();
4990 performLayoutAndPlaceSurfacesLocked();
4991 mInputMonitor.updateInputWindowsLw(false /*force*/);
4992 }
4993 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004994 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004995 }
4996 }
4997
4998 private void removeAppTokensLocked(List<IBinder> tokens) {
4999 // XXX This should be done more efficiently!
5000 // (take advantage of the fact that both lists should be
5001 // ordered in the same way.)
5002 int N = tokens.size();
5003 for (int i=0; i<N; i++) {
5004 IBinder token = tokens.get(i);
5005 final AppWindowToken wtoken = findAppWindowToken(token);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08005006 if (DEBUG_REORDER || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
5007 "Temporarily removing " + wtoken + " from " + mAppTokens.indexOf(wtoken));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005008 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005009 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005010 + token + " (" + wtoken + ")");
5011 i--;
5012 N--;
5013 }
5014 }
5015 }
5016
Dianne Hackborna8f60182009-09-01 19:01:50 -07005017 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
5018 boolean updateFocusAndLayout) {
5019 // First remove all of the windows from the list.
5020 tmpRemoveAppWindowsLocked(wtoken);
5021
Dianne Hackborna8f60182009-09-01 19:01:50 -07005022 // And now add them back at the correct place.
Craig Mautner59c00972012-07-30 12:10:24 -07005023 DisplayContentsIterator iterator = new DisplayContentsIterator();
5024 while (iterator.hasNext()) {
5025 final DisplayContent displayContent = iterator.next();
5026 final WindowList windows = displayContent.getWindowList();
5027 final int pos = findWindowOffsetLocked(windows, tokenPos);
Craig Mautner19d59bc2012-09-04 11:15:56 -07005028 final int newPos = reAddAppWindowsLocked(displayContent, pos, wtoken);
5029 if (pos != newPos) {
5030 displayContent.layoutNeeded = true;
5031 }
Craig Mautner59c00972012-07-30 12:10:24 -07005032
Craig Mautner4f67ba62012-08-02 11:23:00 -07005033 if (updateFocusAndLayout && !updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
Craig Mautner59c00972012-07-30 12:10:24 -07005034 false /*updateInputWindows*/)) {
5035 assignLayersLocked(windows);
5036 }
5037 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07005038
5039 if (updateFocusAndLayout) {
Jeff Brown2e44b072011-01-24 15:21:56 -08005040 mInputMonitor.setUpdateInputWindowsNeededLw();
Craig Mautner59c00972012-07-30 12:10:24 -07005041
5042 // Note that the above updateFocusedWindowLocked conditional used to sit here.
5043
Craig Mautneref25d7a2012-05-15 23:01:47 -07005044 if (!mInLayout) {
5045 performLayoutAndPlaceSurfacesLocked();
5046 }
Jeff Brown2e44b072011-01-24 15:21:56 -08005047 mInputMonitor.updateInputWindowsLw(false /*force*/);
Dianne Hackborna8f60182009-09-01 19:01:50 -07005048 }
5049 }
5050
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005051 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
5052 // First remove all of the windows from the list.
5053 final int N = tokens.size();
5054 int i;
5055 for (i=0; i<N; i++) {
5056 WindowToken token = mTokenMap.get(tokens.get(i));
5057 if (token != null) {
5058 tmpRemoveAppWindowsLocked(token);
5059 }
5060 }
5061
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005062 // And now add them back at the correct place.
Craig Mautner59c00972012-07-30 12:10:24 -07005063 DisplayContentsIterator iterator = new DisplayContentsIterator();
5064 while (iterator.hasNext()) {
5065 final DisplayContent displayContent = iterator.next();
5066 final WindowList windows = displayContent.getWindowList();
5067 // Where to start adding?
5068 int pos = findWindowOffsetLocked(windows, tokenPos);
5069 for (i=0; i<N; i++) {
5070 WindowToken token = mTokenMap.get(tokens.get(i));
5071 if (token != null) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07005072 final int newPos = reAddAppWindowsLocked(displayContent, pos, token);
5073 if (newPos != pos) {
5074 displayContent.layoutNeeded = true;
5075 }
5076 pos = newPos;
Craig Mautner59c00972012-07-30 12:10:24 -07005077 }
5078 }
5079 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
5080 false /*updateInputWindows*/)) {
5081 assignLayersLocked(windows);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005082 }
5083 }
5084
Jeff Brown2e44b072011-01-24 15:21:56 -08005085 mInputMonitor.setUpdateInputWindowsNeededLw();
Craig Mautner59c00972012-07-30 12:10:24 -07005086
Craig Mautner4f67ba62012-08-02 11:23:00 -07005087 // Note that the above updateFocusedWindowLocked used to sit here.
Craig Mautner59c00972012-07-30 12:10:24 -07005088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005089 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08005090 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005091
5092 //dump();
5093 }
5094
5095 public void moveAppTokensToTop(List<IBinder> tokens) {
5096 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5097 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005098 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005099 }
5100
5101 final long origId = Binder.clearCallingIdentity();
5102 synchronized(mWindowMap) {
5103 removeAppTokensLocked(tokens);
5104 final int N = tokens.size();
5105 for (int i=0; i<N; i++) {
5106 AppWindowToken wt = findAppWindowToken(tokens.get(i));
5107 if (wt != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08005108 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
5109 "Adding next to top: " + wt);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005110 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07005111 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07005112 wt.sendingToBottom = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -07005113 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005114 }
5115 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005116
Craig Mautner06a94f72012-05-29 10:46:00 -07005117 if (!mAppTransitionRunning) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07005118 mAnimatingAppTokens.clear();
5119 mAnimatingAppTokens.addAll(mAppTokens);
Dianne Hackborna8f60182009-09-01 19:01:50 -07005120 moveAppWindowsLocked(tokens, mAppTokens.size());
5121 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005122 }
5123 Binder.restoreCallingIdentity(origId);
5124 }
5125
Craig Mautneref25d7a2012-05-15 23:01:47 -07005126 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005127 public void moveAppTokensToBottom(List<IBinder> tokens) {
5128 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5129 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005130 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005131 }
5132
5133 final long origId = Binder.clearCallingIdentity();
5134 synchronized(mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005135 final int N = tokens.size();
Craig Mautner06a94f72012-05-29 10:46:00 -07005136 if (N > 0 && !mAppTransitionRunning) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07005137 // animating towards back, hang onto old list for duration of animation.
5138 mAnimatingAppTokens.clear();
5139 mAnimatingAppTokens.addAll(mAppTokens);
5140 }
5141 removeAppTokensLocked(tokens);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005142 int pos = 0;
5143 for (int i=0; i<N; i++) {
5144 AppWindowToken wt = findAppWindowToken(tokens.get(i));
5145 if (wt != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08005146 if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
5147 "Adding next to bottom: " + wt + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005148 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07005149 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07005150 wt.sendingToBottom = true;
5151 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005152 pos++;
5153 }
5154 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005155
Craig Mautner06a94f72012-05-29 10:46:00 -07005156 if (!mAppTransitionRunning) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07005157 mAnimatingAppTokens.clear();
5158 mAnimatingAppTokens.addAll(mAppTokens);
Dianne Hackborna8f60182009-09-01 19:01:50 -07005159 moveAppWindowsLocked(tokens, 0);
5160 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005161 }
5162 Binder.restoreCallingIdentity(origId);
5163 }
5164
5165 // -------------------------------------------------------------
5166 // Misc IWindowSession methods
5167 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07005168
Craig Mautner5642a482012-08-23 12:16:53 -07005169 @Override
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07005170 public void startFreezingScreen(int exitAnim, int enterAnim) {
5171 if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
5172 "startFreezingScreen()")) {
5173 throw new SecurityException("Requires FREEZE_SCREEN permission");
5174 }
5175
5176 synchronized(mWindowMap) {
5177 if (!mClientFreezingScreen) {
5178 mClientFreezingScreen = true;
5179 final long origId = Binder.clearCallingIdentity();
5180 try {
5181 startFreezingDisplayLocked(false, exitAnim, enterAnim);
5182 mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
5183 mH.sendMessageDelayed(mH.obtainMessage(H.CLIENT_FREEZE_TIMEOUT),
5184 5000);
5185 } finally {
5186 Binder.restoreCallingIdentity(origId);
5187 }
5188 }
5189 }
5190 }
5191
5192 @Override
5193 public void stopFreezingScreen() {
5194 if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
5195 "stopFreezingScreen()")) {
5196 throw new SecurityException("Requires FREEZE_SCREEN permission");
5197 }
5198
5199 synchronized(mWindowMap) {
5200 if (mClientFreezingScreen) {
5201 mClientFreezingScreen = false;
5202 final long origId = Binder.clearCallingIdentity();
5203 try {
5204 stopFreezingDisplayLocked();
5205 } finally {
5206 Binder.restoreCallingIdentity(origId);
5207 }
5208 }
5209 }
5210 }
5211
5212 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005213 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04005214 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005215 != PackageManager.PERMISSION_GRANTED) {
5216 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5217 }
Jim Millerd6b57052010-06-07 17:52:42 -07005218
Craig Mautner5642a482012-08-23 12:16:53 -07005219 mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage(
5220 KeyguardDisableHandler.KEYGUARD_DISABLE, new Pair<IBinder, String>(token, tag)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005221 }
5222
Craig Mautner5642a482012-08-23 12:16:53 -07005223 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005224 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04005225 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005226 != PackageManager.PERMISSION_GRANTED) {
5227 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5228 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005229
Craig Mautner5642a482012-08-23 12:16:53 -07005230 mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage(
5231 KeyguardDisableHandler.KEYGUARD_REENABLE, token));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005232 }
5233
5234 /**
5235 * @see android.app.KeyguardManager#exitKeyguardSecurely
5236 */
5237 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04005238 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005239 != PackageManager.PERMISSION_GRANTED) {
5240 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5241 }
5242 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
5243 public void onKeyguardExitResult(boolean success) {
5244 try {
5245 callback.onKeyguardExitResult(success);
5246 } catch (RemoteException e) {
5247 // Client has died, we don't care.
5248 }
5249 }
5250 });
5251 }
5252
5253 public boolean inKeyguardRestrictedInputMode() {
5254 return mPolicy.inKeyguardRestrictedKeyInputMode();
5255 }
Romain Guy06882f82009-06-10 13:36:04 -07005256
Mike Lockwood520d8bc2011-02-18 13:23:13 -05005257 public boolean isKeyguardLocked() {
5258 return mPolicy.isKeyguardLocked();
5259 }
5260
5261 public boolean isKeyguardSecure() {
5262 return mPolicy.isKeyguardSecure();
5263 }
5264
Dianne Hackborn90c52de2011-09-23 12:57:44 -07005265 public void dismissKeyguard() {
5266 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
5267 != PackageManager.PERMISSION_GRANTED) {
5268 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5269 }
5270 synchronized(mWindowMap) {
5271 mPolicy.dismissKeyguardLw();
5272 }
5273 }
5274
Dianne Hackbornffa42482009-09-23 22:20:11 -07005275 public void closeSystemDialogs(String reason) {
5276 synchronized(mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -07005277 final AllWindowsIterator iterator = new AllWindowsIterator();
5278 while (iterator.hasNext()) {
5279 final WindowState w = iterator.next();
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07005280 if (w.mHasSurface) {
Dianne Hackbornffa42482009-09-23 22:20:11 -07005281 try {
5282 w.mClient.closeSystemDialogs(reason);
5283 } catch (RemoteException e) {
5284 }
5285 }
5286 }
5287 }
5288 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005290 static float fixScale(float scale) {
5291 if (scale < 0) scale = 0;
5292 else if (scale > 20) scale = 20;
5293 return Math.abs(scale);
5294 }
Romain Guy06882f82009-06-10 13:36:04 -07005295
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005296 public void setAnimationScale(int which, float scale) {
5297 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
5298 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005299 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005300 }
5301
5302 if (scale < 0) scale = 0;
5303 else if (scale > 20) scale = 20;
5304 scale = Math.abs(scale);
5305 switch (which) {
5306 case 0: mWindowAnimationScale = fixScale(scale); break;
5307 case 1: mTransitionAnimationScale = fixScale(scale); break;
Chet Haasec38fa1f2012-02-01 16:37:46 -08005308 case 2: mAnimatorDurationScale = fixScale(scale); break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005309 }
Romain Guy06882f82009-06-10 13:36:04 -07005310
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005311 // Persist setting
5312 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
5313 }
Romain Guy06882f82009-06-10 13:36:04 -07005314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005315 public void setAnimationScales(float[] scales) {
5316 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
5317 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005318 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005319 }
5320
5321 if (scales != null) {
5322 if (scales.length >= 1) {
5323 mWindowAnimationScale = fixScale(scales[0]);
5324 }
5325 if (scales.length >= 2) {
5326 mTransitionAnimationScale = fixScale(scales[1]);
5327 }
Chet Haasec38fa1f2012-02-01 16:37:46 -08005328 if (scales.length >= 3) {
Jeff Brownff7e6ef2012-08-15 02:05:18 -07005329 setAnimatorDurationScale(fixScale(scales[2]));
Chet Haasec38fa1f2012-02-01 16:37:46 -08005330 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005331 }
Romain Guy06882f82009-06-10 13:36:04 -07005332
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005333 // Persist setting
5334 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
5335 }
Romain Guy06882f82009-06-10 13:36:04 -07005336
Jeff Brownff7e6ef2012-08-15 02:05:18 -07005337 private void setAnimatorDurationScale(float scale) {
5338 mAnimatorDurationScale = scale;
5339 ValueAnimator.setDurationScale(scale);
5340 }
5341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005342 public float getAnimationScale(int which) {
5343 switch (which) {
5344 case 0: return mWindowAnimationScale;
5345 case 1: return mTransitionAnimationScale;
Chet Haasec38fa1f2012-02-01 16:37:46 -08005346 case 2: return mAnimatorDurationScale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005347 }
5348 return 0;
5349 }
Romain Guy06882f82009-06-10 13:36:04 -07005350
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005351 public float[] getAnimationScales() {
Chet Haasec38fa1f2012-02-01 16:37:46 -08005352 return new float[] { mWindowAnimationScale, mTransitionAnimationScale,
5353 mAnimatorDurationScale };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005354 }
Romain Guy06882f82009-06-10 13:36:04 -07005355
Jeff Brownac143512012-04-05 18:57:33 -07005356 // Called by window manager policy. Not exposed externally.
5357 @Override
5358 public int getLidState() {
Jeff Brownc458ce92012-04-30 14:58:40 -07005359 int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY,
5360 InputManagerService.SW_LID);
Jeff Brownac143512012-04-05 18:57:33 -07005361 if (sw > 0) {
Jeff Brown27fd3422012-04-09 11:05:16 -07005362 // Switch state: AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL.
Jeff Brownac143512012-04-05 18:57:33 -07005363 return LID_CLOSED;
Jeff Brown27fd3422012-04-09 11:05:16 -07005364 } else if (sw == 0) {
5365 // Switch state: AKEY_STATE_UP.
5366 return LID_OPEN;
Jeff Brownac143512012-04-05 18:57:33 -07005367 } else {
Jeff Brown27fd3422012-04-09 11:05:16 -07005368 // Switch state: AKEY_STATE_UNKNOWN.
Jeff Brownac143512012-04-05 18:57:33 -07005369 return LID_ABSENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005370 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005371 }
Romain Guy06882f82009-06-10 13:36:04 -07005372
Jeff Brownac143512012-04-05 18:57:33 -07005373 // Called by window manager policy. Not exposed externally.
5374 @Override
Jeff Browna41ca772010-08-11 14:46:32 -07005375 public InputChannel monitorInput(String inputChannelName) {
Jeff Browna41ca772010-08-11 14:46:32 -07005376 return mInputManager.monitorInput(inputChannelName);
5377 }
5378
Jeff Brown7304c342012-05-11 18:42:42 -07005379 // Called by window manager policy. Not exposed externally.
5380 @Override
Jeff Browncf39bdf2012-05-18 14:41:19 -07005381 public void switchKeyboardLayout(int deviceId, int direction) {
5382 mInputManager.switchKeyboardLayout(deviceId, direction);
5383 }
5384
5385 // Called by window manager policy. Not exposed externally.
5386 @Override
Jeff Brown9a538ee2012-08-20 14:56:57 -07005387 public void shutdown(boolean confirm) {
5388 ShutdownThread.shutdown(mContext, confirm);
Jeff Brown7304c342012-05-11 18:42:42 -07005389 }
5390
5391 // Called by window manager policy. Not exposed externally.
5392 @Override
Jeff Brown9a538ee2012-08-20 14:56:57 -07005393 public void rebootSafeMode(boolean confirm) {
5394 ShutdownThread.rebootSafeMode(mContext, confirm);
Jeff Brown7304c342012-05-11 18:42:42 -07005395 }
5396
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07005397 public void setInputFilter(IInputFilter filter) {
5398 if (!checkCallingPermission(android.Manifest.permission.FILTER_EVENTS, "setInputFilter()")) {
5399 throw new SecurityException("Requires FILTER_EVENTS permission");
5400 }
Jeff Brown0029c662011-03-30 02:25:18 -07005401 mInputManager.setInputFilter(filter);
5402 }
5403
Craig Mautnerf1b67412012-09-19 13:18:29 -07005404 public void setCurrentUser(final int newUserId) {
5405 synchronized (mWindowMap) {
5406 mCurrentUserId = newUserId;
5407 mPolicy.setCurrentUserLw(newUserId);
Craig Mautner88400d32012-09-30 12:35:45 -07005408
5409 // Hide windows that should not be seen by the new user.
5410 DisplayContentsIterator iterator = new DisplayContentsIterator();
5411 while (iterator.hasNext()) {
5412 final WindowList windows = iterator.next().getWindowList();
5413 for (int i = 0; i < windows.size(); i++) {
5414 final WindowState win = windows.get(i);
Craig Mautner5962b122012-10-05 14:45:52 -07005415 if (win.isHiddenFromUserLocked()) {
Craig Mautner88400d32012-09-30 12:35:45 -07005416 Slog.w(TAG, "current user violation " + newUserId + " hiding "
5417 + win + ", attrs=" + win.mAttrs.type + ", belonging to "
5418 + win.mOwnerUid);
5419 win.hideLw(false);
5420 }
5421 }
5422 }
5423 performLayoutAndPlaceSurfacesLocked();
Craig Mautnerf1b67412012-09-19 13:18:29 -07005424 }
5425 }
5426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005427 public void enableScreenAfterBoot() {
5428 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005429 if (DEBUG_BOOT) {
5430 RuntimeException here = new RuntimeException("here");
5431 here.fillInStackTrace();
5432 Slog.i(TAG, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled
5433 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5434 + " mShowingBootMessages=" + mShowingBootMessages
5435 + " mSystemBooted=" + mSystemBooted, here);
5436 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005437 if (mSystemBooted) {
5438 return;
5439 }
5440 mSystemBooted = true;
Dianne Hackborn661cd522011-08-22 00:26:20 -07005441 hideBootMessagesLocked();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005442 // If the screen still doesn't come up after 30 seconds, give
5443 // up and turn it on.
5444 Message msg = mH.obtainMessage(H.BOOT_TIMEOUT);
5445 mH.sendMessageDelayed(msg, 30*1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005446 }
Romain Guy06882f82009-06-10 13:36:04 -07005447
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07005448 mPolicy.systemBooted();
5449
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005450 performEnableScreen();
5451 }
Romain Guy06882f82009-06-10 13:36:04 -07005452
Dianne Hackborn661cd522011-08-22 00:26:20 -07005453 void enableScreenIfNeededLocked() {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005454 if (DEBUG_BOOT) {
5455 RuntimeException here = new RuntimeException("here");
5456 here.fillInStackTrace();
5457 Slog.i(TAG, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled
5458 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5459 + " mShowingBootMessages=" + mShowingBootMessages
5460 + " mSystemBooted=" + mSystemBooted, here);
5461 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005462 if (mDisplayEnabled) {
5463 return;
5464 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005465 if (!mSystemBooted && !mShowingBootMessages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005466 return;
5467 }
5468 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
5469 }
Romain Guy06882f82009-06-10 13:36:04 -07005470
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005471 public void performBootTimeout() {
5472 synchronized(mWindowMap) {
Mike Lockwoodd747dc82011-09-13 16:28:22 -04005473 if (mDisplayEnabled || mHeadless) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005474 return;
5475 }
5476 Slog.w(TAG, "***** BOOT TIMEOUT: forcing display enabled");
5477 mForceDisplayEnabled = true;
5478 }
5479 performEnableScreen();
5480 }
5481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005482 public void performEnableScreen() {
5483 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005484 if (DEBUG_BOOT) {
5485 RuntimeException here = new RuntimeException("here");
5486 here.fillInStackTrace();
5487 Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
5488 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5489 + " mShowingBootMessages=" + mShowingBootMessages
Jeff Brown780c46f2012-06-24 12:15:38 -07005490 + " mSystemBooted=" + mSystemBooted
5491 + " mOnlyCore=" + mOnlyCore, here);
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005492 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005493 if (mDisplayEnabled) {
5494 return;
5495 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005496 if (!mSystemBooted && !mShowingBootMessages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005497 return;
5498 }
Romain Guy06882f82009-06-10 13:36:04 -07005499
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005500 if (!mForceDisplayEnabled) {
5501 // Don't enable the screen until all existing windows
5502 // have been drawn.
5503 boolean haveBootMsg = false;
5504 boolean haveApp = false;
Justin Mattson4233f262012-04-09 18:23:16 -07005505 // if the wallpaper service is disabled on the device, we're never going to have
5506 // wallpaper, don't bother waiting for it
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005507 boolean haveWallpaper = false;
Justin Mattson4233f262012-04-09 18:23:16 -07005508 boolean wallpaperEnabled = mContext.getResources().getBoolean(
Jeff Brown780c46f2012-06-24 12:15:38 -07005509 com.android.internal.R.bool.config_enableWallpaperService)
5510 && !mOnlyCore;
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005511 boolean haveKeyguard = true;
Craig Mautner59c00972012-07-30 12:10:24 -07005512 // TODO(multidisplay): Expand to all displays?
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005513 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07005514 final int N = windows.size();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005515 for (int i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07005516 WindowState w = windows.get(i);
Craig Mautner65d11b32012-10-01 13:59:52 -07005517 if (w.mAttrs.type == TYPE_KEYGUARD) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005518 // Only if there is a keyguard attached to the window manager
5519 // will we consider ourselves as having a keyguard. If it
5520 // isn't attached, we don't know if it wants to be shown or
5521 // hidden. If it is attached, we will say we have a keyguard
5522 // if the window doesn't want to be visible, because in that
5523 // case it explicitly doesn't want to be shown so we should
5524 // not delay turning the screen on for it.
5525 boolean vis = w.mViewVisibility == View.VISIBLE
5526 && w.mPolicyVisibility;
5527 haveKeyguard = !vis;
5528 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005529 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
5530 return;
5531 }
5532 if (w.isDrawnLw()) {
Craig Mautner65d11b32012-10-01 13:59:52 -07005533 if (w.mAttrs.type == TYPE_BOOT_PROGRESS) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005534 haveBootMsg = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005535 } else if (w.mAttrs.type == TYPE_APPLICATION) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005536 haveApp = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005537 } else if (w.mAttrs.type == TYPE_WALLPAPER) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005538 haveWallpaper = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005539 } else if (w.mAttrs.type == TYPE_KEYGUARD) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005540 haveKeyguard = true;
5541 }
5542 }
5543 }
5544
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005545 if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005546 Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
5547 + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
Justin Mattson4233f262012-04-09 18:23:16 -07005548 + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled
5549 + " haveKeyguard=" + haveKeyguard);
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005550 }
5551
5552 // If we are turning on the screen to show the boot message,
5553 // don't do it until the boot message is actually displayed.
5554 if (!mSystemBooted && !haveBootMsg) {
5555 return;
5556 }
5557
5558 // If we are turning on the screen after the boot is completed
5559 // normally, don't do so until we have the application and
5560 // wallpaper.
Justin Mattson4233f262012-04-09 18:23:16 -07005561 if (mSystemBooted && ((!haveApp && !haveKeyguard) ||
5562 (wallpaperEnabled && !haveWallpaper))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005563 return;
5564 }
5565 }
Romain Guy06882f82009-06-10 13:36:04 -07005566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005567 mDisplayEnabled = true;
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005568 if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005569 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005570 StringWriter sw = new StringWriter();
5571 PrintWriter pw = new PrintWriter(sw);
5572 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005573 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005574 }
5575 try {
5576 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
5577 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005578 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005579 Parcel data = Parcel.obtain();
5580 data.writeInterfaceToken("android.ui.ISurfaceComposer");
Jeff Brownc042ee22012-05-08 13:03:42 -07005581 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005582 data, null, 0);
5583 data.recycle();
5584 }
5585 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005586 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005587 }
Jeff Brown08a746a2012-06-24 12:14:49 -07005588
5589 // Enable input dispatch.
5590 mInputMonitor.setEventDispatchingLw(mEventDispatchingEnabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005591 }
Romain Guy06882f82009-06-10 13:36:04 -07005592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005593 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07005594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005595 // Make sure the last requested orientation has been applied.
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005596 updateRotationUnchecked(false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005597 }
Romain Guy06882f82009-06-10 13:36:04 -07005598
Dianne Hackborn661cd522011-08-22 00:26:20 -07005599 public void showBootMessage(final CharSequence msg, final boolean always) {
5600 boolean first = false;
5601 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005602 if (DEBUG_BOOT) {
5603 RuntimeException here = new RuntimeException("here");
5604 here.fillInStackTrace();
5605 Slog.i(TAG, "showBootMessage: msg=" + msg + " always=" + always
5606 + " mAllowBootMessages=" + mAllowBootMessages
5607 + " mShowingBootMessages=" + mShowingBootMessages
5608 + " mSystemBooted=" + mSystemBooted, here);
5609 }
Dianne Hackborn58f42a52011-10-10 13:46:34 -07005610 if (!mAllowBootMessages) {
5611 return;
5612 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005613 if (!mShowingBootMessages) {
5614 if (!always) {
5615 return;
5616 }
5617 first = true;
5618 }
5619 if (mSystemBooted) {
5620 return;
5621 }
5622 mShowingBootMessages = true;
5623 mPolicy.showBootMessage(msg, always);
5624 }
5625 if (first) {
5626 performEnableScreen();
5627 }
5628 }
5629
5630 public void hideBootMessagesLocked() {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005631 if (DEBUG_BOOT) {
5632 RuntimeException here = new RuntimeException("here");
5633 here.fillInStackTrace();
5634 Slog.i(TAG, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled
5635 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5636 + " mShowingBootMessages=" + mShowingBootMessages
5637 + " mSystemBooted=" + mSystemBooted, here);
5638 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005639 if (mShowingBootMessages) {
5640 mShowingBootMessages = false;
5641 mPolicy.hideBootMessages();
5642 }
5643 }
5644
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005645 public void setInTouchMode(boolean mode) {
5646 synchronized(mWindowMap) {
5647 mInTouchMode = mode;
5648 }
5649 }
5650
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005651 // TODO: more accounting of which pid(s) turned it on, keep count,
5652 // only allow disables from pids which have count on, etc.
Craig Mautner0447a812012-05-22 16:01:31 -07005653 @Override
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005654 public void showStrictModeViolation(boolean on) {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07005655 if (mHeadless) return;
Craig Mautner0447a812012-05-22 16:01:31 -07005656 mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, on ? 1 : 0, 0));
5657 }
Mike Lockwood3a74bd32011-08-12 13:55:22 -07005658
Craig Mautner0447a812012-05-22 16:01:31 -07005659 private void showStrictModeViolation(int arg) {
5660 final boolean on = arg != 0;
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005661 int pid = Binder.getCallingPid();
5662 synchronized(mWindowMap) {
5663 // Ignoring requests to enable the red border from clients
5664 // which aren't on screen. (e.g. Broadcast Receivers in
5665 // the background..)
5666 if (on) {
5667 boolean isVisible = false;
Craig Mautner59c00972012-07-30 12:10:24 -07005668 final AllWindowsIterator iterator = new AllWindowsIterator();
5669 while (iterator.hasNext()) {
5670 final WindowState ws = iterator.next();
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005671 if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
5672 isVisible = true;
5673 break;
5674 }
5675 }
5676 if (!isVisible) {
5677 return;
5678 }
5679 }
5680
Dianne Hackborn36991742011-10-11 21:35:26 -07005681 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
5682 ">>> OPEN TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005683 Surface.openTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005684 try {
Jeff Browne215f262012-09-10 16:01:14 -07005685 // TODO(multi-display): support multiple displays
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005686 if (mStrictModeFlash == null) {
Jeff Browne215f262012-09-10 16:01:14 -07005687 mStrictModeFlash = new StrictModeFlash(
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005688 getDefaultDisplayContentLocked().getDisplay(), mFxSession);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005689 }
5690 mStrictModeFlash.setVisibility(on);
5691 } finally {
5692 Surface.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -07005693 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
5694 "<<< CLOSE TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005695 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005696 }
5697 }
5698
Brad Fitzpatrickc1a968a2010-11-24 08:56:40 -08005699 public void setStrictModeVisualIndicatorPreference(String value) {
5700 SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
5701 }
5702
Jim Millere70d5062011-03-08 21:38:39 -08005703 /**
5704 * Takes a snapshot of the screen. In landscape mode this grabs the whole screen.
5705 * In portrait mode, it grabs the upper region of the screen based on the vertical dimension
5706 * of the target image.
5707 *
Craig Mautner59c00972012-07-30 12:10:24 -07005708 * @param displayId the Display to take a screenshot of.
Jim Millere70d5062011-03-08 21:38:39 -08005709 * @param width the width of the target bitmap
5710 * @param height the height of the target bitmap
5711 */
Craig Mautner59c00972012-07-30 12:10:24 -07005712 public Bitmap screenshotApplications(IBinder appToken, int displayId, int width, int height) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005713 if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5714 "screenshotApplications()")) {
5715 throw new SecurityException("Requires READ_FRAME_BUFFER permission");
5716 }
5717
5718 Bitmap rawss;
5719
Dianne Hackbornd2835932010-12-13 16:28:46 -08005720 int maxLayer = 0;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005721 final Rect frame = new Rect();
5722
5723 float scale;
Jim Millere70d5062011-03-08 21:38:39 -08005724 int dw, dh;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005725 int rot;
5726
5727 synchronized(mWindowMap) {
5728 long ident = Binder.clearCallingIdentity();
5729
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005730 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner59c00972012-07-30 12:10:24 -07005731 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
5732 dw = displayInfo.logicalWidth;
5733 dh = displayInfo.logicalHeight;
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005734
Craig Mautner65d11b32012-10-01 13:59:52 -07005735 int aboveAppLayer = mPolicy.windowTypeToLayerLw(TYPE_APPLICATION)
5736 * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005737 aboveAppLayer += TYPE_LAYER_MULTIPLIER;
5738
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005739 boolean isImeTarget = mInputMethodTarget != null
5740 && mInputMethodTarget.mAppToken != null
5741 && mInputMethodTarget.mAppToken.appToken != null
5742 && mInputMethodTarget.mAppToken.appToken.asBinder() == appToken;
5743
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005744 // Figure out the part of the screen that is actually the app.
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005745 boolean including = false;
Craig Mautner59c00972012-07-30 12:10:24 -07005746 final WindowList windows = displayContent.getWindowList();
5747 for (int i = windows.size() - 1; i >= 0; i--) {
5748 WindowState ws = windows.get(i);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07005749 if (!ws.mHasSurface) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005750 continue;
5751 }
5752 if (ws.mLayer >= aboveAppLayer) {
Dianne Hackbornd2835932010-12-13 16:28:46 -08005753 continue;
5754 }
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005755 // When we will skip windows: when we are not including
5756 // ones behind a window we didn't skip, and we are actually
5757 // taking a screenshot of a specific app.
5758 if (!including && appToken != null) {
5759 // Also, we can possibly skip this window if it is not
5760 // an IME target or the application for the screenshot
5761 // is not the current IME target.
5762 if (!ws.mIsImWindow || !isImeTarget) {
5763 // And finally, this window is of no interest if it
5764 // is not associated with the screenshot app.
5765 if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
5766 continue;
5767 }
5768 }
5769 }
5770
5771 // We keep on including windows until we go past a full-screen
5772 // window.
5773 including = !ws.mIsImWindow && !ws.isFullscreen(dw, dh);
5774
Craig Mautner88165682012-05-31 14:25:31 -07005775 if (maxLayer < ws.mWinAnimator.mSurfaceLayer) {
5776 maxLayer = ws.mWinAnimator.mSurfaceLayer;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005777 }
Jim Miller2aded182011-03-08 15:32:42 -08005778
5779 // Don't include wallpaper in bounds calculation
5780 if (!ws.mIsWallpaper) {
Dianne Hackbornffb3d932011-05-17 17:44:51 -07005781 final Rect wf = ws.mFrame;
Jim Miller2aded182011-03-08 15:32:42 -08005782 final Rect cr = ws.mContentInsets;
5783 int left = wf.left + cr.left;
5784 int top = wf.top + cr.top;
5785 int right = wf.right - cr.right;
5786 int bottom = wf.bottom - cr.bottom;
5787 frame.union(left, top, right, bottom);
5788 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005789 }
5790 Binder.restoreCallingIdentity(ident);
5791
Dianne Hackborndd962ee2011-02-02 11:11:50 -08005792 // Constrain frame to the screen size.
5793 frame.intersect(0, 0, dw, dh);
Jim Millere70d5062011-03-08 21:38:39 -08005794
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005795 if (frame.isEmpty() || maxLayer == 0) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005796 return null;
5797 }
5798
5799 // The screenshot API does not apply the current screen rotation.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005800 rot = getDefaultDisplayContentLocked().getDisplay().getRotation();
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005801 int fw = frame.width();
5802 int fh = frame.height();
5803
Jim Miller28637ba2011-07-06 19:57:05 -07005804 // Constrain thumbnail to smaller of screen width or height. Assumes aspect
5805 // of thumbnail is the same as the screen (in landscape) or square.
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005806 float targetWidthScale = width / (float) fw;
5807 float targetHeightScale = height / (float) fh;
Jim Miller28637ba2011-07-06 19:57:05 -07005808 if (dw <= dh) {
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005809 scale = targetWidthScale;
5810 // If aspect of thumbnail is the same as the screen (in landscape),
5811 // select the slightly larger value so we fill the entire bitmap
5812 if (targetHeightScale > scale && (int) (targetHeightScale * fw) == width) {
5813 scale = targetHeightScale;
5814 }
Jim Miller28637ba2011-07-06 19:57:05 -07005815 } else {
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005816 scale = targetHeightScale;
5817 // If aspect of thumbnail is the same as the screen (in landscape),
5818 // select the slightly larger value so we fill the entire bitmap
5819 if (targetWidthScale > scale && (int) (targetWidthScale * fh) == height) {
5820 scale = targetWidthScale;
5821 }
Jim Miller28637ba2011-07-06 19:57:05 -07005822 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005823
5824 // The screen shot will contain the entire screen.
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005825 dw = (int)(dw*scale);
5826 dh = (int)(dh*scale);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005827 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
5828 int tmp = dw;
5829 dw = dh;
5830 dh = tmp;
5831 rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
5832 }
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -07005833 if (DEBUG_SCREENSHOT) {
5834 Slog.i(TAG, "Screenshot: " + dw + "x" + dh + " from 0 to " + maxLayer);
Craig Mautner59c00972012-07-30 12:10:24 -07005835 for (int i = 0; i < windows.size(); i++) {
5836 WindowState win = windows.get(i);
5837 Slog.i(TAG, win + ": " + win.mLayer
5838 + " animLayer=" + win.mWinAnimator.mAnimLayer
5839 + " surfaceLayer=" + win.mWinAnimator.mSurfaceLayer);
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -07005840 }
5841 }
Dianne Hackbornd2835932010-12-13 16:28:46 -08005842 rawss = Surface.screenshot(dw, dh, 0, maxLayer);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005843 }
5844
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005845 if (rawss == null) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07005846 Slog.w(TAG, "Failure taking screenshot for (" + dw + "x" + dh
Dianne Hackborn88b03bd2010-12-16 11:15:18 -08005847 + ") to layer " + maxLayer);
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005848 return null;
5849 }
Jim Millere70d5062011-03-08 21:38:39 -08005850
5851 Bitmap bm = Bitmap.createBitmap(width, height, rawss.getConfig());
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005852 Matrix matrix = new Matrix();
5853 ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
Michael Jurka4accb6a2012-03-26 09:18:46 -07005854 matrix.postTranslate(-FloatMath.ceil(frame.left*scale), -FloatMath.ceil(frame.top*scale));
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005855 Canvas canvas = new Canvas(bm);
5856 canvas.drawBitmap(rawss, matrix, null);
Dianne Hackborn6311d0a2011-08-02 16:37:58 -07005857 canvas.setBitmap(null);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005858
5859 rawss.recycle();
5860 return bm;
5861 }
5862
Jeff Brown01a98dd2011-09-20 15:08:29 -07005863 /**
5864 * Freeze rotation changes. (Enable "rotation lock".)
5865 * Persists across reboots.
Jeff Brown4dfce202011-10-05 12:00:10 -07005866 * @param rotation The desired rotation to freeze to, or -1 to use the
5867 * current rotation.
Jeff Brown01a98dd2011-09-20 15:08:29 -07005868 */
Jeff Brown4dfce202011-10-05 12:00:10 -07005869 public void freezeRotation(int rotation) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005870 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005871 "freezeRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005872 throw new SecurityException("Requires SET_ORIENTATION permission");
5873 }
Jeff Brown4dfce202011-10-05 12:00:10 -07005874 if (rotation < -1 || rotation > Surface.ROTATION_270) {
5875 throw new IllegalArgumentException("Rotation argument must be -1 or a valid "
5876 + "rotation constant.");
5877 }
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005878
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005879 if (DEBUG_ORIENTATION) Slog.v(TAG, "freezeRotation: mRotation=" + mRotation);
5880
Jeff Brown4dfce202011-10-05 12:00:10 -07005881 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED,
5882 rotation == -1 ? mRotation : rotation);
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005883 updateRotationUnchecked(false, false);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005884 }
5885
Jeff Brown01a98dd2011-09-20 15:08:29 -07005886 /**
5887 * Thaw rotation changes. (Disable "rotation lock".)
5888 * Persists across reboots.
5889 */
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005890 public void thawRotation() {
5891 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005892 "thawRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005893 throw new SecurityException("Requires SET_ORIENTATION permission");
5894 }
5895
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005896 if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation);
5897
5898 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 777); // rot not used
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005899 updateRotationUnchecked(false, false);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005900 }
5901
Jeff Brown01a98dd2011-09-20 15:08:29 -07005902 /**
5903 * Recalculate the current rotation.
5904 *
5905 * Called by the window manager policy whenever the state of the system changes
5906 * such that the current rotation might need to be updated, such as when the
5907 * device is docked or rotated into a new posture.
5908 */
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005909 public void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
5910 updateRotationUnchecked(alwaysSendConfiguration, forceRelayout);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005911 }
5912
5913 /**
5914 * Temporarily pauses rotation changes until resumed.
5915 *
5916 * This can be used to prevent rotation changes from occurring while the user is
5917 * performing certain operations, such as drag and drop.
5918 *
5919 * This call nests and must be matched by an equal number of calls to {@link #resumeRotation}.
5920 */
5921 void pauseRotationLocked() {
5922 mDeferredRotationPauseCount += 1;
5923 }
5924
5925 /**
5926 * Resumes normal rotation changes after being paused.
5927 */
5928 void resumeRotationLocked() {
5929 if (mDeferredRotationPauseCount > 0) {
5930 mDeferredRotationPauseCount -= 1;
5931 if (mDeferredRotationPauseCount == 0) {
5932 boolean changed = updateRotationUncheckedLocked(false);
5933 if (changed) {
5934 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
5935 }
5936 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005937 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005938 }
Romain Guy06882f82009-06-10 13:36:04 -07005939
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005940 public void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005941 if(DEBUG_ORIENTATION) Slog.v(TAG, "updateRotationUnchecked("
5942 + "alwaysSendConfiguration=" + alwaysSendConfiguration + ")");
Romain Guy06882f82009-06-10 13:36:04 -07005943
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005944 long origId = Binder.clearCallingIdentity();
5945 boolean changed;
5946 synchronized(mWindowMap) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005947 changed = updateRotationUncheckedLocked(false);
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005948 if (!changed || forceRelayout) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005949 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005950 performLayoutAndPlaceSurfacesLocked();
5951 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005952 }
Romain Guy06882f82009-06-10 13:36:04 -07005953
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005954 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005955 sendNewConfiguration();
5956 }
Romain Guy06882f82009-06-10 13:36:04 -07005957
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005958 Binder.restoreCallingIdentity(origId);
5959 }
Romain Guy06882f82009-06-10 13:36:04 -07005960
Craig Mautner59c00972012-07-30 12:10:24 -07005961 // TODO(multidisplay): Rotate any display?
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005962 /**
Jeff Brown01a98dd2011-09-20 15:08:29 -07005963 * Updates the current rotation.
5964 *
5965 * Returns true if the rotation has been changed. In this case YOU
5966 * MUST CALL sendNewConfiguration() TO UNFREEZE THE SCREEN.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005967 */
Jeff Brown01a98dd2011-09-20 15:08:29 -07005968 public boolean updateRotationUncheckedLocked(boolean inTransaction) {
5969 if (mDeferredRotationPauseCount > 0) {
5970 // Rotation updates have been paused temporarily. Defer the update until
5971 // updates have been resumed.
5972 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, rotation is paused.");
Christopher Tateccd24de2011-01-12 15:02:55 -08005973 return false;
5974 }
5975
Craig Mautnera91f9e22012-09-14 16:22:08 -07005976 ScreenRotationAnimation screenRotationAnimation =
5977 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
5978 if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005979 // Rotation updates cannot be performed while the previous rotation change
5980 // animation is still in progress. Skip this update. We will try updating
5981 // again after the animation is finished and the display is unfrozen.
5982 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, animation in progress.");
5983 return false;
5984 }
5985
5986 if (!mDisplayEnabled) {
5987 // No point choosing a rotation if the display is not enabled.
5988 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, display is not enabled.");
5989 return false;
5990 }
5991
5992 // TODO: Implement forced rotation changes.
5993 // Set mAltOrientation to indicate that the application is receiving
5994 // an orientation that has different metrics than it expected.
5995 // eg. Portrait instead of Landscape.
5996
5997 int rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, mRotation);
5998 boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
5999 mForcedAppOrientation, rotation);
6000
6001 if (DEBUG_ORIENTATION) {
6002 Slog.v(TAG, "Application requested orientation "
6003 + mForcedAppOrientation + ", got rotation " + rotation
6004 + " which has " + (altOrientation ? "incompatible" : "compatible")
6005 + " metrics");
6006 }
6007
6008 if (mRotation == rotation && mAltOrientation == altOrientation) {
6009 // No change.
6010 return false;
6011 }
6012
6013 if (DEBUG_ORIENTATION) {
6014 Slog.v(TAG,
6015 "Rotation changed to " + rotation + (altOrientation ? " (alt)" : "")
6016 + " from " + mRotation + (mAltOrientation ? " (alt)" : "")
6017 + ", forceApp=" + mForcedAppOrientation);
6018 }
6019
6020 mRotation = rotation;
6021 mAltOrientation = altOrientation;
Jeff Brownc0347aa2011-09-23 17:26:09 -07006022 mPolicy.setRotationLw(mRotation);
Jeff Brown01a98dd2011-09-20 15:08:29 -07006023
6024 mWindowsFreezingScreen = true;
6025 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
6026 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT), 2000);
6027 mWaitingForConfig = true;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006028 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07006029 startFreezingDisplayLocked(inTransaction, 0, 0);
Craig Mautnera91f9e22012-09-14 16:22:08 -07006030 // startFreezingDisplayLocked can reset the ScreenRotationAnimation.
6031 screenRotationAnimation =
6032 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
Jeff Brown01a98dd2011-09-20 15:08:29 -07006033
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006034 // We need to update our screen size information to match the new
6035 // rotation. Note that this is redundant with the later call to
6036 // sendNewConfiguration() that must be called after this function
6037 // returns... however we need to do the screen size part of that
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006038 // before then so we have the correct size to use when initializing
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006039 // the rotation animation for the new rotation.
6040 computeScreenConfigurationLocked(null);
6041
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006042 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07006043 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006044 if (!inTransaction) {
6045 if (SHOW_TRANSACTIONS) {
6046 Slog.i(TAG, ">>> OPEN TRANSACTION setRotationUnchecked");
6047 }
6048 Surface.openTransaction();
6049 }
Jamie Gennise2909e12011-10-10 15:48:06 -07006050 try {
6051 // NOTE: We disable the rotation in the emulator because
6052 // it doesn't support hardware OpenGL emulation yet.
Craig Mautnera91f9e22012-09-14 16:22:08 -07006053 if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
6054 && screenRotationAnimation.hasScreenshot()) {
6055 if (screenRotationAnimation.setRotationInTransaction(
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006056 rotation, mFxSession,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006057 MAX_ANIMATION_DURATION, mTransitionAnimationScale,
Craig Mautner59c00972012-07-30 12:10:24 -07006058 displayInfo.logicalWidth, displayInfo.logicalHeight)) {
Craig Mautner711f90a2012-07-03 18:43:52 -07006059 updateLayoutToAnimationLocked();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006060 }
Jamie Gennise2909e12011-10-10 15:48:06 -07006061 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006062
6063 mDisplayManagerService.performTraversalInTransactionFromWindowManager();
Jamie Gennise2909e12011-10-10 15:48:06 -07006064 } finally {
6065 if (!inTransaction) {
6066 Surface.closeTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006067 if (SHOW_LIGHT_TRANSACTIONS) {
6068 Slog.i(TAG, "<<< CLOSE TRANSACTION setRotationUnchecked");
6069 }
Jamie Gennise2909e12011-10-10 15:48:06 -07006070 }
6071 }
6072
Craig Mautner59c00972012-07-30 12:10:24 -07006073 final WindowList windows = displayContent.getWindowList();
6074 for (int i = windows.size() - 1; i >= 0; i--) {
6075 WindowState w = windows.get(i);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07006076 if (w.mHasSurface) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07006077 if (DEBUG_ORIENTATION) Slog.v(TAG, "Set mOrientationChanging of " + w);
Jeff Brown01a98dd2011-09-20 15:08:29 -07006078 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07006079 mInnerFields.mOrientationChangeComplete = false;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006080 }
6081 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006082
Jeff Brown01a98dd2011-09-20 15:08:29 -07006083 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
6084 try {
6085 mRotationWatchers.get(i).onRotationChanged(rotation);
6086 } catch (RemoteException e) {
6087 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006088 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006089
6090 scheduleNotifyRotationChangedIfNeededLocked(displayContent, rotation);
6091
Jeff Brown01a98dd2011-09-20 15:08:29 -07006092 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006093 }
Romain Guy06882f82009-06-10 13:36:04 -07006094
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006095 public int getRotation() {
6096 return mRotation;
6097 }
6098
6099 public int watchRotation(IRotationWatcher watcher) {
6100 final IBinder watcherBinder = watcher.asBinder();
6101 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
6102 public void binderDied() {
6103 synchronized (mWindowMap) {
6104 for (int i=0; i<mRotationWatchers.size(); i++) {
6105 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07006106 IRotationWatcher removed = mRotationWatchers.remove(i);
6107 if (removed != null) {
6108 removed.asBinder().unlinkToDeath(this, 0);
6109 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006110 i--;
6111 }
6112 }
6113 }
6114 }
6115 };
Romain Guy06882f82009-06-10 13:36:04 -07006116
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006117 synchronized (mWindowMap) {
6118 try {
6119 watcher.asBinder().linkToDeath(dr, 0);
6120 mRotationWatchers.add(watcher);
6121 } catch (RemoteException e) {
6122 // Client died, no cleanup needed.
6123 }
Romain Guy06882f82009-06-10 13:36:04 -07006124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006125 return mRotation;
6126 }
6127 }
6128
6129 /**
Adam Powelldfee59a2011-08-05 20:48:30 -07006130 * Apps that use the compact menu panel (as controlled by the panelMenuIsCompact
6131 * theme attribute) on devices that feature a physical options menu key attempt to position
6132 * their menu panel window along the edge of the screen nearest the physical menu key.
6133 * This lowers the travel distance between invoking the menu panel and selecting
6134 * a menu option.
6135 *
6136 * This method helps control where that menu is placed. Its current implementation makes
6137 * assumptions about the menu key and its relationship to the screen based on whether
6138 * the device's natural orientation is portrait (width < height) or landscape.
6139 *
6140 * The menu key is assumed to be located along the bottom edge of natural-portrait
6141 * devices and along the right edge of natural-landscape devices. If these assumptions
6142 * do not hold for the target device, this method should be changed to reflect that.
6143 *
6144 * @return A {@link Gravity} value for placing the options menu window
6145 */
6146 public int getPreferredOptionsPanelGravity() {
6147 synchronized (mWindowMap) {
6148 final int rotation = getRotation();
6149
Craig Mautner59c00972012-07-30 12:10:24 -07006150 // TODO(multidisplay): Assume that such devices physical keys are on the main screen.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006151 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07006152 if (displayContent.mInitialDisplayWidth < displayContent.mInitialDisplayHeight) {
Adam Powelldfee59a2011-08-05 20:48:30 -07006153 // On devices with a natural orientation of portrait
6154 switch (rotation) {
6155 default:
6156 case Surface.ROTATION_0:
6157 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
6158 case Surface.ROTATION_90:
Adam Powell67ed6c72011-08-28 13:21:56 -07006159 return Gravity.RIGHT | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006160 case Surface.ROTATION_180:
Adam Powell67ed6c72011-08-28 13:21:56 -07006161 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006162 case Surface.ROTATION_270:
Fabrice Di Meglioaac0d4e2012-07-19 19:21:26 -07006163 return Gravity.START | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006164 }
6165 } else {
6166 // On devices with a natural orientation of landscape
6167 switch (rotation) {
6168 default:
6169 case Surface.ROTATION_0:
Adam Powell67ed6c72011-08-28 13:21:56 -07006170 return Gravity.RIGHT | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006171 case Surface.ROTATION_90:
6172 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
6173 case Surface.ROTATION_180:
Fabrice Di Meglioaac0d4e2012-07-19 19:21:26 -07006174 return Gravity.START | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006175 case Surface.ROTATION_270:
Adam Powell67ed6c72011-08-28 13:21:56 -07006176 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006177 }
6178 }
6179 }
6180 }
6181
6182 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006183 * Starts the view server on the specified port.
6184 *
6185 * @param port The port to listener to.
6186 *
6187 * @return True if the server was successfully started, false otherwise.
6188 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08006189 * @see com.android.server.wm.ViewServer
6190 * @see com.android.server.wm.ViewServer#VIEW_SERVER_DEFAULT_PORT
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006191 */
6192 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07006193 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006194 return false;
6195 }
6196
6197 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
6198 return false;
6199 }
6200
6201 if (port < 1024) {
6202 return false;
6203 }
6204
6205 if (mViewServer != null) {
6206 if (!mViewServer.isRunning()) {
6207 try {
6208 return mViewServer.start();
6209 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006210 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006211 }
6212 }
6213 return false;
6214 }
6215
6216 try {
6217 mViewServer = new ViewServer(this, port);
6218 return mViewServer.start();
6219 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006220 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006221 }
6222 return false;
6223 }
6224
Romain Guy06882f82009-06-10 13:36:04 -07006225 private boolean isSystemSecure() {
6226 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
6227 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6228 }
6229
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006230 /**
6231 * Stops the view server if it exists.
6232 *
6233 * @return True if the server stopped, false if it wasn't started or
6234 * couldn't be stopped.
6235 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08006236 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006237 */
6238 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07006239 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006240 return false;
6241 }
6242
6243 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
6244 return false;
6245 }
6246
6247 if (mViewServer != null) {
6248 return mViewServer.stop();
6249 }
6250 return false;
6251 }
6252
6253 /**
6254 * Indicates whether the view server is running.
6255 *
6256 * @return True if the server is running, false otherwise.
6257 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08006258 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006259 */
6260 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07006261 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006262 return false;
6263 }
6264
6265 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
6266 return false;
6267 }
6268
6269 return mViewServer != null && mViewServer.isRunning();
6270 }
6271
6272 /**
6273 * Lists all availble windows in the system. The listing is written in the
6274 * specified Socket's output stream with the following syntax:
6275 * windowHashCodeInHexadecimal windowName
6276 * Each line of the ouput represents a different window.
6277 *
6278 * @param client The remote client to send the listing to.
6279 * @return False if an error occured, true otherwise.
6280 */
6281 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07006282 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006283 return false;
6284 }
6285
6286 boolean result = true;
6287
Craig Mautner59c00972012-07-30 12:10:24 -07006288 WindowList windows = new WindowList();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006289 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006290 //noinspection unchecked
Craig Mautner59c00972012-07-30 12:10:24 -07006291 DisplayContentsIterator iterator = new DisplayContentsIterator();
6292 while(iterator.hasNext()) {
6293 windows.addAll(iterator.next().getWindowList());
6294 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006295 }
6296
6297 BufferedWriter out = null;
6298
6299 // Any uncaught exception will crash the system process
6300 try {
6301 OutputStream clientStream = client.getOutputStream();
6302 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
6303
Craig Mautner59c00972012-07-30 12:10:24 -07006304 final int count = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006305 for (int i = 0; i < count; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07006306 final WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006307 out.write(Integer.toHexString(System.identityHashCode(w)));
6308 out.write(' ');
6309 out.append(w.mAttrs.getTitle());
6310 out.write('\n');
6311 }
6312
6313 out.write("DONE.\n");
6314 out.flush();
6315 } catch (Exception e) {
6316 result = false;
6317 } finally {
6318 if (out != null) {
6319 try {
6320 out.close();
6321 } catch (IOException e) {
6322 result = false;
6323 }
6324 }
6325 }
6326
6327 return result;
6328 }
6329
Craig Mautner59c00972012-07-30 12:10:24 -07006330 // TODO(multidisplay): Extend to multiple displays.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006331 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07006332 * Returns the focused window in the following format:
6333 * windowHashCodeInHexadecimal windowName
6334 *
6335 * @param client The remote client to send the listing to.
6336 * @return False if an error occurred, true otherwise.
6337 */
6338 boolean viewServerGetFocusedWindow(Socket client) {
6339 if (isSystemSecure()) {
6340 return false;
6341 }
6342
6343 boolean result = true;
6344
6345 WindowState focusedWindow = getFocusedWindow();
6346
6347 BufferedWriter out = null;
6348
6349 // Any uncaught exception will crash the system process
6350 try {
6351 OutputStream clientStream = client.getOutputStream();
6352 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
6353
6354 if(focusedWindow != null) {
6355 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
6356 out.write(' ');
6357 out.append(focusedWindow.mAttrs.getTitle());
6358 }
6359 out.write('\n');
6360 out.flush();
6361 } catch (Exception e) {
6362 result = false;
6363 } finally {
6364 if (out != null) {
6365 try {
6366 out.close();
6367 } catch (IOException e) {
6368 result = false;
6369 }
6370 }
6371 }
6372
6373 return result;
6374 }
6375
6376 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006377 * Sends a command to a target window. The result of the command, if any, will be
6378 * written in the output stream of the specified socket.
6379 *
6380 * The parameters must follow this syntax:
6381 * windowHashcode extra
6382 *
6383 * Where XX is the length in characeters of the windowTitle.
6384 *
6385 * The first parameter is the target window. The window with the specified hashcode
6386 * will be the target. If no target can be found, nothing happens. The extra parameters
6387 * will be delivered to the target window and as parameters to the command itself.
6388 *
6389 * @param client The remote client to sent the result, if any, to.
6390 * @param command The command to execute.
6391 * @param parameters The command parameters.
6392 *
6393 * @return True if the command was successfully delivered, false otherwise. This does
6394 * not indicate whether the command itself was successful.
6395 */
6396 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07006397 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006398 return false;
6399 }
6400
6401 boolean success = true;
6402 Parcel data = null;
6403 Parcel reply = null;
6404
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006405 BufferedWriter out = null;
6406
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006407 // Any uncaught exception will crash the system process
6408 try {
6409 // Find the hashcode of the window
6410 int index = parameters.indexOf(' ');
6411 if (index == -1) {
6412 index = parameters.length();
6413 }
6414 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08006415 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006416
6417 // Extract the command's parameter after the window description
6418 if (index < parameters.length()) {
6419 parameters = parameters.substring(index + 1);
6420 } else {
6421 parameters = "";
6422 }
6423
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006424 final WindowState window = findWindow(hashCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006425 if (window == null) {
6426 return false;
6427 }
6428
6429 data = Parcel.obtain();
6430 data.writeInterfaceToken("android.view.IWindow");
6431 data.writeString(command);
6432 data.writeString(parameters);
6433 data.writeInt(1);
6434 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
6435
6436 reply = Parcel.obtain();
6437
6438 final IBinder binder = window.mClient.asBinder();
6439 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
6440 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
6441
6442 reply.readException();
6443
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006444 if (!client.isOutputShutdown()) {
6445 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
6446 out.write("DONE\n");
6447 out.flush();
6448 }
6449
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006450 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006451 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006452 success = false;
6453 } finally {
6454 if (data != null) {
6455 data.recycle();
6456 }
6457 if (reply != null) {
6458 reply.recycle();
6459 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006460 if (out != null) {
6461 try {
6462 out.close();
6463 } catch (IOException e) {
6464
6465 }
6466 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006467 }
6468
6469 return success;
6470 }
6471
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006472 public void addDisplayContentChangeListener(int displayId,
6473 IDisplayContentChangeListener listener) {
6474 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
6475 "addDisplayContentChangeListener()")) {
6476 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission");
6477 }
6478 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006479 DisplayContent displayContent = getDisplayContentLocked(displayId);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006480 if (displayContent.mDisplayContentChangeListeners == null) {
6481 displayContent.mDisplayContentChangeListeners =
6482 new RemoteCallbackList<IDisplayContentChangeListener>();
6483 displayContent.mDisplayContentChangeListeners.register(listener);
6484 }
6485 }
6486 }
6487
6488 public void removeDisplayContentChangeListener(int displayId,
6489 IDisplayContentChangeListener listener) {
6490 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
6491 "removeDisplayContentChangeListener()")) {
6492 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission");
6493 }
6494 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006495 DisplayContent displayContent = getDisplayContentLocked(displayId);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006496 if (displayContent.mDisplayContentChangeListeners != null) {
6497 displayContent.mDisplayContentChangeListeners.unregister(listener);
6498 if (displayContent.mDisplayContentChangeListeners
6499 .getRegisteredCallbackCount() == 0) {
6500 displayContent.mDisplayContentChangeListeners = null;
6501 }
6502 }
6503 }
6504 }
6505
6506 void scheduleNotifyWindowTranstionIfNeededLocked(WindowState window, int transition) {
6507 DisplayContent displayContent = window.mDisplayContent;
6508 if (displayContent.mDisplayContentChangeListeners != null) {
6509 WindowInfo info = getWindowInfoForWindowStateLocked(window);
6510 mH.obtainMessage(H.NOTIFY_WINDOW_TRANSITION, transition, 0, info).sendToTarget();
6511 }
6512 }
6513
6514 private void handleNotifyWindowTranstion(int transition, WindowInfo info) {
6515 RemoteCallbackList<IDisplayContentChangeListener> callbacks = null;
6516 synchronized (mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006517 DisplayContent displayContent = getDisplayContentLocked(info.displayId);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006518 if (displayContent == null) {
6519 return;
6520 }
6521 callbacks = displayContent.mDisplayContentChangeListeners;
6522 if (callbacks == null) {
6523 return;
6524 }
6525 }
6526 final int callbackCount = callbacks.beginBroadcast();
6527 try {
6528 for (int i = 0; i < callbackCount; i++) {
6529 try {
6530 callbacks.getBroadcastItem(i).onWindowTransition(info.displayId,
6531 transition, info);
6532 } catch (RemoteException re) {
6533 /* ignore */
6534 }
6535 }
6536 } finally {
6537 callbacks.finishBroadcast();
6538 }
6539 }
6540
6541 private void scheduleNotifyRotationChangedIfNeededLocked(DisplayContent displayContent,
6542 int rotation) {
6543 if (displayContent.mDisplayContentChangeListeners != null
6544 && displayContent.mDisplayContentChangeListeners.getRegisteredCallbackCount() > 0) {
6545 mH.obtainMessage(H.NOTIFY_ROTATION_CHANGED, displayContent.getDisplayId(),
6546 rotation).sendToTarget();
6547 }
6548 }
6549
6550 private void handleNotifyRotationChanged(int displayId, int rotation) {
6551 RemoteCallbackList<IDisplayContentChangeListener> callbacks = null;
6552 synchronized (mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006553 DisplayContent displayContent = getDisplayContentLocked(displayId);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006554 if (displayContent == null) {
6555 return;
6556 }
6557 callbacks = displayContent.mDisplayContentChangeListeners;
6558 if (callbacks == null) {
6559 return;
6560 }
6561 }
6562 try {
6563 final int watcherCount = callbacks.beginBroadcast();
6564 for (int i = 0; i < watcherCount; i++) {
6565 try {
6566 callbacks.getBroadcastItem(i).onRotationChanged(rotation);
6567 } catch (RemoteException re) {
6568 /* ignore */
6569 }
6570 }
6571 } finally {
6572 callbacks.finishBroadcast();
6573 }
6574 }
6575
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07006576 public void addWindowChangeListener(WindowChangeListener listener) {
6577 synchronized(mWindowMap) {
6578 mWindowChangeListeners.add(listener);
6579 }
6580 }
6581
6582 public void removeWindowChangeListener(WindowChangeListener listener) {
6583 synchronized(mWindowMap) {
6584 mWindowChangeListeners.remove(listener);
6585 }
6586 }
6587
6588 private void notifyWindowsChanged() {
6589 WindowChangeListener[] windowChangeListeners;
6590 synchronized(mWindowMap) {
6591 if(mWindowChangeListeners.isEmpty()) {
6592 return;
6593 }
6594 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
6595 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
6596 }
6597 int N = windowChangeListeners.length;
6598 for(int i = 0; i < N; i++) {
6599 windowChangeListeners[i].windowsChanged();
6600 }
6601 }
6602
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07006603 private void notifyFocusChanged() {
6604 WindowChangeListener[] windowChangeListeners;
6605 synchronized(mWindowMap) {
6606 if(mWindowChangeListeners.isEmpty()) {
6607 return;
6608 }
6609 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
6610 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
6611 }
6612 int N = windowChangeListeners.length;
6613 for(int i = 0; i < N; i++) {
6614 windowChangeListeners[i].focusChanged();
6615 }
6616 }
6617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006618 private WindowState findWindow(int hashCode) {
6619 if (hashCode == -1) {
Craig Mautner59c00972012-07-30 12:10:24 -07006620 // TODO(multidisplay): Extend to multiple displays.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006621 return getFocusedWindow();
6622 }
6623
6624 synchronized (mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -07006625 final AllWindowsIterator iterator = new AllWindowsIterator();
6626 while (iterator.hasNext()) {
6627 final WindowState w = iterator.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006628 if (System.identityHashCode(w) == hashCode) {
6629 return w;
6630 }
6631 }
6632 }
6633
6634 return null;
6635 }
6636
6637 /*
6638 * Instruct the Activity Manager to fetch the current configuration and broadcast
6639 * that to config-changed listeners if appropriate.
6640 */
6641 void sendNewConfiguration() {
6642 try {
6643 mActivityManager.updateConfiguration(null);
6644 } catch (RemoteException e) {
6645 }
6646 }
Romain Guy06882f82009-06-10 13:36:04 -07006647
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006648 public Configuration computeNewConfiguration() {
6649 synchronized (mWindowMap) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006650 Configuration config = computeNewConfigurationLocked();
6651 if (config == null && mWaitingForConfig) {
6652 // Nothing changed but we are waiting for something... stop that!
6653 mWaitingForConfig = false;
6654 performLayoutAndPlaceSurfacesLocked();
6655 }
6656 return config;
Dianne Hackbornc485a602009-03-24 22:39:49 -07006657 }
6658 }
Romain Guy06882f82009-06-10 13:36:04 -07006659
Dianne Hackbornc485a602009-03-24 22:39:49 -07006660 Configuration computeNewConfigurationLocked() {
6661 Configuration config = new Configuration();
Dianne Hackborn09e5b9d2011-10-04 16:32:01 -07006662 config.fontScale = 0;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006663 if (!computeScreenConfigurationLocked(config)) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07006664 return null;
6665 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07006666 return config;
6667 }
Romain Guy06882f82009-06-10 13:36:04 -07006668
Craig Mautner59c00972012-07-30 12:10:24 -07006669 private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation, int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006670 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006671 final int width = mPolicy.getConfigDisplayWidth(dw, dh, rotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006672 if (width < displayInfo.smallestNominalAppWidth) {
6673 displayInfo.smallestNominalAppWidth = width;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006674 }
Craig Mautner59c00972012-07-30 12:10:24 -07006675 if (width > displayInfo.largestNominalAppWidth) {
6676 displayInfo.largestNominalAppWidth = width;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006677 }
6678 final int height = mPolicy.getConfigDisplayHeight(dw, dh, rotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006679 if (height < displayInfo.smallestNominalAppHeight) {
6680 displayInfo.smallestNominalAppHeight = height;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006681 }
Craig Mautner59c00972012-07-30 12:10:24 -07006682 if (height > displayInfo.largestNominalAppHeight) {
6683 displayInfo.largestNominalAppHeight = height;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006684 }
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006685 }
6686
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006687 private int reduceConfigLayout(int curLayout, int rotation, float density,
6688 int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006689 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006690 // Get the app screen size at this rotation.
6691 int w = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
6692 int h = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
6693
6694 // Compute the screen layout size class for this rotation.
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006695 int longSize = w;
6696 int shortSize = h;
6697 if (longSize < shortSize) {
6698 int tmp = longSize;
6699 longSize = shortSize;
6700 shortSize = tmp;
6701 }
6702 longSize = (int)(longSize/density);
6703 shortSize = (int)(shortSize/density);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006704 return Configuration.reduceScreenLayout(curLayout, longSize, shortSize);
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006705 }
6706
Craig Mautner59c00972012-07-30 12:10:24 -07006707 private void computeSizeRangesAndScreenLayout(DisplayInfo displayInfo, boolean rotated,
6708 int dw, int dh, float density, Configuration outConfig) {
Craig Mautner69b08182012-09-05 13:07:13 -07006709 // TODO: Multidisplay: for now only use with default display.
6710
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006711 // We need to determine the smallest width that will occur under normal
6712 // operation. To this, start with the base screen size and compute the
6713 // width under the different possible rotations. We need to un-rotate
6714 // the current screen dimensions before doing this.
6715 int unrotDw, unrotDh;
6716 if (rotated) {
6717 unrotDw = dh;
6718 unrotDh = dw;
6719 } else {
6720 unrotDw = dw;
6721 unrotDh = dh;
6722 }
Craig Mautner59c00972012-07-30 12:10:24 -07006723 displayInfo.smallestNominalAppWidth = 1<<30;
6724 displayInfo.smallestNominalAppHeight = 1<<30;
6725 displayInfo.largestNominalAppWidth = 0;
6726 displayInfo.largestNominalAppHeight = 0;
6727 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, unrotDw, unrotDh);
6728 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, unrotDh, unrotDw);
6729 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, unrotDw, unrotDh);
6730 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, unrotDh, unrotDw);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006731 int sl = Configuration.resetScreenLayout(outConfig.screenLayout);
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006732 sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh);
6733 sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw);
6734 sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh);
6735 sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw);
Craig Mautner59c00972012-07-30 12:10:24 -07006736 outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006737 outConfig.screenLayout = sl;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006738 }
6739
Dianne Hackborn48a76512011-06-08 21:51:44 -07006740 private int reduceCompatConfigWidthSize(int curSize, int rotation, DisplayMetrics dm,
6741 int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006742 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn1f903c32011-09-13 19:18:06 -07006743 dm.noncompatWidthPixels = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
6744 dm.noncompatHeightPixels = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006745 float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
Dianne Hackborn2b31d532011-06-23 11:58:50 -07006746 int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006747 if (curSize == 0 || size < curSize) {
6748 curSize = size;
6749 }
6750 return curSize;
6751 }
6752
6753 private int computeCompatSmallestWidth(boolean rotated, DisplayMetrics dm, int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006754 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn48a76512011-06-08 21:51:44 -07006755 mTmpDisplayMetrics.setTo(dm);
Craig Mautner69b08182012-09-05 13:07:13 -07006756 final DisplayMetrics tmpDm = mTmpDisplayMetrics;
6757 final int unrotDw, unrotDh;
Dianne Hackborn48a76512011-06-08 21:51:44 -07006758 if (rotated) {
6759 unrotDw = dh;
6760 unrotDh = dw;
6761 } else {
6762 unrotDw = dw;
6763 unrotDh = dh;
6764 }
Craig Mautner69b08182012-09-05 13:07:13 -07006765 int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, tmpDm, unrotDw, unrotDh);
6766 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, tmpDm, unrotDh, unrotDw);
6767 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, tmpDm, unrotDw, unrotDh);
6768 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, tmpDm, unrotDh, unrotDw);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006769 return sw;
6770 }
6771
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006772 boolean computeScreenConfigurationLocked(Configuration config) {
Jeff Browne215f262012-09-10 16:01:14 -07006773 if (!mDisplayReady) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07006774 return false;
6775 }
Christopher Tateb696aee2010-04-02 19:08:30 -07006776
Craig Mautner59c00972012-07-30 12:10:24 -07006777 // TODO(multidisplay): For now, apply Configuration to main screen only.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006778 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07006779
Christopher Tateb696aee2010-04-02 19:08:30 -07006780 // Use the effective "visual" dimensions based on current rotation
6781 final boolean rotated = (mRotation == Surface.ROTATION_90
6782 || mRotation == Surface.ROTATION_270);
Craig Mautner59c00972012-07-30 12:10:24 -07006783 final int realdw = rotated ?
6784 displayContent.mBaseDisplayHeight : displayContent.mBaseDisplayWidth;
6785 final int realdh = rotated ?
6786 displayContent.mBaseDisplayWidth : displayContent.mBaseDisplayHeight;
Jeff Brownfa25bf52012-07-23 19:26:30 -07006787 int dw = realdw;
6788 int dh = realdh;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006789
Jeff Brownfa25bf52012-07-23 19:26:30 -07006790 if (mAltOrientation) {
6791 if (realdw > realdh) {
6792 // Turn landscape into portrait.
6793 int maxw = (int)(realdh/1.3f);
6794 if (maxw < realdw) {
6795 dw = maxw;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006796 }
6797 } else {
Jeff Brownfa25bf52012-07-23 19:26:30 -07006798 // Turn portrait into landscape.
6799 int maxh = (int)(realdw/1.3f);
6800 if (maxh < realdh) {
6801 dh = maxh;
6802 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006803 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006804 }
6805
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006806 if (config != null) {
Jeff Browne215f262012-09-10 16:01:14 -07006807 config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
6808 Configuration.ORIENTATION_LANDSCAPE;
Dianne Hackbornc485a602009-03-24 22:39:49 -07006809 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006810
Jeff Brownbc68a592011-07-25 12:58:12 -07006811 // Update application display metrics.
Dianne Hackborn1fbee792011-11-30 11:29:58 -08006812 final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation);
6813 final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006814 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
6815 synchronized(displayContent.mDisplaySizeLock) {
6816 displayInfo.rotation = mRotation;
6817 displayInfo.logicalWidth = dw;
6818 displayInfo.logicalHeight = dh;
Dianne Hackborndde331c2012-08-03 14:01:57 -07006819 displayInfo.logicalDensityDpi = displayContent.mBaseDisplayDensity;
Craig Mautner59c00972012-07-30 12:10:24 -07006820 displayInfo.appWidth = appWidth;
6821 displayInfo.appHeight = appHeight;
6822 displayInfo.getLogicalMetrics(mRealDisplayMetrics, null);
6823 displayInfo.getAppMetrics(mDisplayMetrics, null);
Jeff Brownbd6e1502012-08-28 03:27:37 -07006824 mDisplayManagerService.setDisplayInfoOverrideFromWindowManager(
6825 displayContent.getDisplayId(), displayInfo);
Jeff Brownfa25bf52012-07-23 19:26:30 -07006826
6827 mAnimator.setDisplayDimensions(dw, dh, appWidth, appHeight);
Dianne Hackborn1fbee792011-11-30 11:29:58 -08006828 }
Dianne Hackborn36991742011-10-11 21:35:26 -07006829 if (false) {
Jeff Brownfa25bf52012-07-23 19:26:30 -07006830 Slog.i(TAG, "Set app display size: " + appWidth + " x " + appHeight);
Dianne Hackborn36991742011-10-11 21:35:26 -07006831 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006832
Jeff Brownfa25bf52012-07-23 19:26:30 -07006833 final DisplayMetrics dm = mDisplayMetrics;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006834 mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm,
6835 mCompatDisplayMetrics);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006836
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006837 if (config != null) {
6838 config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation)
6839 / dm.density);
6840 config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation)
6841 / dm.density);
Craig Mautner59c00972012-07-30 12:10:24 -07006842 computeSizeRangesAndScreenLayout(displayInfo, rotated, dw, dh, dm.density, config);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006843
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006844 config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
6845 config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
6846 config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dm, dw, dh);
Dianne Hackborndde331c2012-08-03 14:01:57 -07006847 config.densityDpi = displayContent.mBaseDisplayDensity;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006848
Jeff Browndaa37532012-05-01 15:54:03 -07006849 // Update the configuration based on available input devices, lid switch,
6850 // and platform configuration.
6851 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
6852 config.keyboard = Configuration.KEYBOARD_NOKEYS;
6853 config.navigation = Configuration.NAVIGATION_NONAV;
6854
6855 int keyboardPresence = 0;
6856 int navigationPresence = 0;
Craig Mautner1d961d42012-05-27 12:02:11 -07006857 final InputDevice[] devices = mInputManager.getInputDevices();
6858 final int len = devices.length;
6859 for (int i = 0; i < len; i++) {
6860 InputDevice device = devices[i];
Jeff Browndaa37532012-05-01 15:54:03 -07006861 if (!device.isVirtual()) {
6862 final int sources = device.getSources();
6863 final int presenceFlag = device.isExternal() ?
6864 WindowManagerPolicy.PRESENCE_EXTERNAL :
6865 WindowManagerPolicy.PRESENCE_INTERNAL;
6866
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -07006867 if (mIsTouchDevice) {
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006868 if ((sources & InputDevice.SOURCE_TOUCHSCREEN) ==
6869 InputDevice.SOURCE_TOUCHSCREEN) {
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -07006870 config.touchscreen = Configuration.TOUCHSCREEN_FINGER;
6871 }
6872 } else {
6873 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
Jeff Browndaa37532012-05-01 15:54:03 -07006874 }
6875
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006876 if ((sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) {
Jeff Browndaa37532012-05-01 15:54:03 -07006877 config.navigation = Configuration.NAVIGATION_TRACKBALL;
6878 navigationPresence |= presenceFlag;
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006879 } else if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD
Jeff Browndaa37532012-05-01 15:54:03 -07006880 && config.navigation == Configuration.NAVIGATION_NONAV) {
6881 config.navigation = Configuration.NAVIGATION_DPAD;
6882 navigationPresence |= presenceFlag;
6883 }
6884
6885 if (device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) {
6886 config.keyboard = Configuration.KEYBOARD_QWERTY;
6887 keyboardPresence |= presenceFlag;
6888 }
6889 }
6890 }
6891
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006892 // Determine whether a hard keyboard is available and enabled.
6893 boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
6894 if (hardKeyboardAvailable != mHardKeyboardAvailable) {
6895 mHardKeyboardAvailable = hardKeyboardAvailable;
6896 mHardKeyboardEnabled = hardKeyboardAvailable;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006897 mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
6898 mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
6899 }
6900 if (!mHardKeyboardEnabled) {
6901 config.keyboard = Configuration.KEYBOARD_NOKEYS;
6902 }
6903
Jeff Browndaa37532012-05-01 15:54:03 -07006904 // Let the policy update hidden states.
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006905 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
6906 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
6907 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO;
Jeff Browndaa37532012-05-01 15:54:03 -07006908 mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence);
Jeff Brown2992ea72011-01-28 22:04:14 -08006909 }
Jeff Brown597eec82011-01-31 17:12:25 -08006910
Dianne Hackbornc485a602009-03-24 22:39:49 -07006911 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006912 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006913
Jeff Brown2992ea72011-01-28 22:04:14 -08006914 public boolean isHardKeyboardAvailable() {
6915 synchronized (mWindowMap) {
6916 return mHardKeyboardAvailable;
6917 }
6918 }
6919
6920 public boolean isHardKeyboardEnabled() {
6921 synchronized (mWindowMap) {
6922 return mHardKeyboardEnabled;
6923 }
6924 }
6925
6926 public void setHardKeyboardEnabled(boolean enabled) {
6927 synchronized (mWindowMap) {
6928 if (mHardKeyboardEnabled != enabled) {
6929 mHardKeyboardEnabled = enabled;
6930 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
6931 }
6932 }
6933 }
6934
6935 public void setOnHardKeyboardStatusChangeListener(
6936 OnHardKeyboardStatusChangeListener listener) {
6937 synchronized (mWindowMap) {
6938 mHardKeyboardStatusChangeListener = listener;
6939 }
6940 }
6941
6942 void notifyHardKeyboardStatusChange() {
6943 final boolean available, enabled;
6944 final OnHardKeyboardStatusChangeListener listener;
6945 synchronized (mWindowMap) {
6946 listener = mHardKeyboardStatusChangeListener;
6947 available = mHardKeyboardAvailable;
6948 enabled = mHardKeyboardEnabled;
6949 }
6950 if (listener != null) {
6951 listener.onHardKeyboardStatusChange(available, enabled);
6952 }
6953 }
6954
Christopher Tatea53146c2010-09-07 11:57:52 -07006955 // -------------------------------------------------------------
6956 // Drag and drop
6957 // -------------------------------------------------------------
6958
6959 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006960 int flags, int width, int height, Surface outSurface) {
Christopher Tatea53146c2010-09-07 11:57:52 -07006961 if (DEBUG_DRAG) {
6962 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006963 + " flags=" + Integer.toHexString(flags) + " win=" + window
Christopher Tatea53146c2010-09-07 11:57:52 -07006964 + " asbinder=" + window.asBinder());
6965 }
6966
6967 final int callerPid = Binder.getCallingPid();
6968 final long origId = Binder.clearCallingIdentity();
6969 IBinder token = null;
6970
6971 try {
6972 synchronized (mWindowMap) {
6973 try {
Christopher Tatea53146c2010-09-07 11:57:52 -07006974 if (mDragState == null) {
Jeff Browne215f262012-09-10 16:01:14 -07006975 // TODO(multi-display): support other displays
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006976 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07006977 final Display display = displayContent.getDisplay();
Jeff Brown64a55af2012-08-26 02:47:39 -07006978 Surface surface = new Surface(session, "drag surface",
Christopher Tatea53146c2010-09-07 11:57:52 -07006979 width, height, PixelFormat.TRANSLUCENT, Surface.HIDDEN);
Jeff Browne215f262012-09-10 16:01:14 -07006980 surface.setLayerStack(display.getLayerStack());
Dianne Hackbornac1471a2011-02-03 13:46:06 -08006981 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DRAG "
6982 + surface + ": CREATE");
Christopher Tatea53146c2010-09-07 11:57:52 -07006983 outSurface.copyFrom(surface);
Chris Tate7b362e42010-11-04 16:02:52 -07006984 final IBinder winBinder = window.asBinder();
Christopher Tatea53146c2010-09-07 11:57:52 -07006985 token = new Binder();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006986 mDragState = new DragState(this, token, surface, /*flags*/ 0, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07006987 token = mDragState.mToken = new Binder();
6988
6989 // 5 second timeout for this window to actually begin the drag
Chris Tate7b362e42010-11-04 16:02:52 -07006990 mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
6991 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07006992 mH.sendMessageDelayed(msg, 5000);
6993 } else {
6994 Slog.w(TAG, "Drag already in progress");
6995 }
6996 } catch (Surface.OutOfResourcesException e) {
6997 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
6998 if (mDragState != null) {
6999 mDragState.reset();
7000 mDragState = null;
7001 }
Christopher Tatea53146c2010-09-07 11:57:52 -07007002 }
7003 }
7004 } finally {
7005 Binder.restoreCallingIdentity(origId);
7006 }
7007
7008 return token;
7009 }
7010
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007011 // -------------------------------------------------------------
7012 // Input Events and Focus Management
7013 // -------------------------------------------------------------
Jeff Brown46b9ac02010-04-22 18:58:52 -07007014
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08007015 final InputMonitor mInputMonitor = new InputMonitor(this);
Jeff Brown08a746a2012-06-24 12:14:49 -07007016 private boolean mEventDispatchingEnabled;
7017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007018 public void pauseKeyDispatching(IBinder _token) {
7019 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
7020 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07007021 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007022 }
7023
7024 synchronized (mWindowMap) {
7025 WindowToken token = mTokenMap.get(_token);
7026 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07007027 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007028 }
7029 }
7030 }
7031
7032 public void resumeKeyDispatching(IBinder _token) {
7033 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
7034 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07007035 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007036 }
7037
7038 synchronized (mWindowMap) {
7039 WindowToken token = mTokenMap.get(_token);
7040 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07007041 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007042 }
7043 }
7044 }
7045
7046 public void setEventDispatching(boolean enabled) {
7047 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner3d7b7d52012-05-24 11:28:26 -07007048 "setEventDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07007049 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007050 }
7051
7052 synchronized (mWindowMap) {
Jeff Brown08a746a2012-06-24 12:14:49 -07007053 mEventDispatchingEnabled = enabled;
7054 if (mDisplayEnabled) {
7055 mInputMonitor.setEventDispatchingLw(enabled);
7056 }
Craig Mautner3d7b7d52012-05-24 11:28:26 -07007057 sendScreenStatusToClientsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007058 }
7059 }
Romain Guy06882f82009-06-10 13:36:04 -07007060
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07007061 public IBinder getFocusedWindowToken() {
7062 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
7063 "getFocusedWindowToken()")) {
7064 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
7065 }
Svetoslav Ganove15ccb92012-05-16 15:48:55 -07007066 synchronized (mWindowMap) {
7067 WindowState windowState = getFocusedWindowLocked();
7068 if (windowState != null) {
7069 return windowState.mClient.asBinder();
7070 }
7071 return null;
7072 }
7073 }
7074
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007075 private WindowState getFocusedWindow() {
7076 synchronized (mWindowMap) {
7077 return getFocusedWindowLocked();
7078 }
7079 }
7080
7081 private WindowState getFocusedWindowLocked() {
7082 return mCurrentFocus;
7083 }
Romain Guy06882f82009-06-10 13:36:04 -07007084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007085 public boolean detectSafeMode() {
Jeff Brownb09abc12011-01-13 21:08:27 -08007086 if (!mInputMonitor.waitForInputDevicesReady(
7087 INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
7088 Slog.w(TAG, "Devices still not ready after waiting "
Jeff Brownac143512012-04-05 18:57:33 -07007089 + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
7090 + " milliseconds before attempting to detect safe mode.");
Jeff Brownb09abc12011-01-13 21:08:27 -08007091 }
7092
Jeff Brownac143512012-04-05 18:57:33 -07007093 int menuState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
7094 KeyEvent.KEYCODE_MENU);
7095 int sState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, KeyEvent.KEYCODE_S);
7096 int dpadState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD,
7097 KeyEvent.KEYCODE_DPAD_CENTER);
7098 int trackballState = mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL,
Jeff Brownc458ce92012-04-30 14:58:40 -07007099 InputManagerService.BTN_MOUSE);
Jeff Brownac143512012-04-05 18:57:33 -07007100 int volumeDownState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
7101 KeyEvent.KEYCODE_VOLUME_DOWN);
7102 mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
7103 || volumeDownState > 0;
Dianne Hackborn19caadc2012-04-20 17:49:10 -07007104 try {
7105 if (SystemProperties.getInt(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, 0) != 0) {
7106 mSafeMode = true;
7107 SystemProperties.set(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, "");
7108 }
7109 } catch (IllegalArgumentException e) {
7110 }
Jeff Brownac143512012-04-05 18:57:33 -07007111 if (mSafeMode) {
7112 Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
7113 + " dpad=" + dpadState + " trackball=" + trackballState + ")");
7114 } else {
7115 Log.i(TAG, "SAFE MODE not enabled");
7116 }
7117 mPolicy.setSafeMode(mSafeMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007118 return mSafeMode;
7119 }
Romain Guy06882f82009-06-10 13:36:04 -07007120
Dianne Hackborn661cd522011-08-22 00:26:20 -07007121 public void displayReady() {
Jeff Browne215f262012-09-10 16:01:14 -07007122 displayReady(Display.DEFAULT_DISPLAY);
Craig Mautner4f67ba62012-08-02 11:23:00 -07007123
7124 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007125 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07007126 final Display display = displayContent.getDisplay();
7127 readForcedDisplaySizeAndDensityLocked(displayContent);
Dianne Hackborn5a052a42012-08-15 18:49:23 -07007128
Jeff Browne215f262012-09-10 16:01:14 -07007129 mDisplayReady = true;
Craig Mautner4f67ba62012-08-02 11:23:00 -07007130 mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
Jeff Browne215f262012-09-10 16:01:14 -07007131 PackageManager.FEATURE_TOUCHSCREEN);
Craig Mautner4f67ba62012-08-02 11:23:00 -07007132
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007133 final DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Jeff Browne215f262012-09-10 16:01:14 -07007134 mAnimator.setDisplayDimensions(
7135 displayInfo.logicalWidth, displayInfo.logicalHeight,
7136 displayInfo.appWidth, displayInfo.appHeight);
Craig Mautner4f67ba62012-08-02 11:23:00 -07007137
Jeff Browne215f262012-09-10 16:01:14 -07007138 mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
7139 displayContent.mInitialDisplayWidth,
7140 displayContent.mInitialDisplayHeight,
7141 displayContent.mInitialDisplayDensity);
Craig Mautner4f67ba62012-08-02 11:23:00 -07007142 }
Dianne Hackborn5a052a42012-08-15 18:49:23 -07007143
7144 try {
7145 mActivityManager.updateConfiguration(null);
7146 } catch (RemoteException e) {
7147 }
Craig Mautner59c00972012-07-30 12:10:24 -07007148 }
7149
7150 public void displayReady(int displayId) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07007151 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007152 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner4f67ba62012-08-02 11:23:00 -07007153 final DisplayInfo displayInfo;
Craig Mautnera91f9e22012-09-14 16:22:08 -07007154 mAnimator.addDisplayLocked(displayId);
Craig Mautner59c00972012-07-30 12:10:24 -07007155 synchronized(displayContent.mDisplaySizeLock) {
Jeff Brownfa25bf52012-07-23 19:26:30 -07007156 // Bootstrap the default logical display from the display manager.
Craig Mautner4f67ba62012-08-02 11:23:00 -07007157 displayInfo = displayContent.getDisplayInfo();
Jeff Brownbd6e1502012-08-28 03:27:37 -07007158 DisplayInfo newDisplayInfo = mDisplayManagerService.getDisplayInfo(displayId);
7159 if (newDisplayInfo != null) {
7160 displayInfo.copyFrom(newDisplayInfo);
7161 }
Craig Mautner59c00972012-07-30 12:10:24 -07007162 displayContent.mInitialDisplayWidth = displayInfo.logicalWidth;
7163 displayContent.mInitialDisplayHeight = displayInfo.logicalHeight;
Dianne Hackborndde331c2012-08-03 14:01:57 -07007164 displayContent.mInitialDisplayDensity = displayInfo.logicalDensityDpi;
Craig Mautner59c00972012-07-30 12:10:24 -07007165 displayContent.mBaseDisplayWidth = displayContent.mInitialDisplayWidth;
7166 displayContent.mBaseDisplayHeight = displayContent.mInitialDisplayHeight;
Dianne Hackborndde331c2012-08-03 14:01:57 -07007167 displayContent.mBaseDisplayDensity = displayContent.mInitialDisplayDensity;
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007168 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07007169 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07007170 }
7171
Dianne Hackborn661cd522011-08-22 00:26:20 -07007172 public void systemReady() {
7173 mPolicy.systemReady();
7174 }
7175
Craig Mautner59c00972012-07-30 12:10:24 -07007176 // TODO(multidisplay): Call isScreenOn for each display.
Craig Mautner3d7b7d52012-05-24 11:28:26 -07007177 private void sendScreenStatusToClientsLocked() {
Craig Mautner59c00972012-07-30 12:10:24 -07007178 final boolean on = mPowerManager.isScreenOn();
7179 final AllWindowsIterator iterator = new AllWindowsIterator();
7180 while (iterator.hasNext()) {
Romain Guy7e4e5612012-03-05 14:37:29 -08007181 try {
Craig Mautner59c00972012-07-30 12:10:24 -07007182 iterator.next().mClient.dispatchScreenState(on);
Romain Guy7e4e5612012-03-05 14:37:29 -08007183 } catch (RemoteException e) {
7184 // Ignored
7185 }
7186 }
7187 }
7188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007189 // -------------------------------------------------------------
7190 // Async Handler
7191 // -------------------------------------------------------------
7192
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08007193 final class H extends Handler {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007194 public static final int REPORT_FOCUS_CHANGE = 2;
7195 public static final int REPORT_LOSING_FOCUS = 3;
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08007196 public static final int DO_TRAVERSAL = 4;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007197 public static final int ADD_STARTING = 5;
7198 public static final int REMOVE_STARTING = 6;
7199 public static final int FINISHED_STARTING = 7;
7200 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07007201 public static final int REPORT_APPLICATION_TOKEN_DRAWN = 9;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007202 public static final int WINDOW_FREEZE_TIMEOUT = 11;
Craig Mautner259328c2012-08-21 19:30:58 -07007203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007204 public static final int APP_TRANSITION_TIMEOUT = 13;
7205 public static final int PERSIST_ANIMATION_SCALE = 14;
7206 public static final int FORCE_GC = 15;
7207 public static final int ENABLE_SCREEN = 16;
7208 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007209 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07007210 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07007211 public static final int DRAG_START_TIMEOUT = 20;
Chris Tated4533f12010-10-19 15:15:08 -07007212 public static final int DRAG_END_TIMEOUT = 21;
Jeff Brown2992ea72011-01-28 22:04:14 -08007213 public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07007214 public static final int BOOT_TIMEOUT = 23;
Dianne Hackborn38e29a62011-09-18 14:43:08 -07007215 public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
Craig Mautner01cd0e72012-06-18 10:19:11 -07007216 public static final int UPDATE_ANIM_PARAMETERS = 25;
Craig Mautner0447a812012-05-22 16:01:31 -07007217 public static final int SHOW_STRICT_MODE_VIOLATION = 26;
Dianne Hackborn84375872012-06-01 19:03:50 -07007218 public static final int DO_ANIMATION_CALLBACK = 27;
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07007219 public static final int NOTIFY_ROTATION_CHANGED = 28;
7220 public static final int NOTIFY_WINDOW_TRANSITION = 29;
7221 public static final int NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED = 30;
Romain Guy06882f82009-06-10 13:36:04 -07007222
Craig Mautner722285e2012-09-07 13:55:58 -07007223 public static final int DO_DISPLAY_ADDED = 31;
7224 public static final int DO_DISPLAY_REMOVED = 32;
7225 public static final int DO_DISPLAY_CHANGED = 33;
7226
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007227 public static final int CLIENT_FREEZE_TIMEOUT = 34;
7228
Craig Mautner48ba1e72012-04-02 13:18:16 -07007229 public static final int ANIMATOR_WHAT_OFFSET = 100000;
7230 public static final int SET_TRANSPARENT_REGION = ANIMATOR_WHAT_OFFSET + 1;
Craig Mautner12670b52012-07-03 19:15:35 -07007231 public static final int CLEAR_PENDING_ACTIONS = ANIMATOR_WHAT_OFFSET + 2;
Craig Mautner48ba1e72012-04-02 13:18:16 -07007232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007233 public H() {
7234 }
Romain Guy06882f82009-06-10 13:36:04 -07007235
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007236 @Override
7237 public void handleMessage(Message msg) {
Craig Mautner7d8df392012-04-06 15:26:23 -07007238 if (DEBUG_WINDOW_TRACE) {
7239 Slog.v(TAG, "handleMessage: entry what=" + msg.what);
7240 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007241 switch (msg.what) {
7242 case REPORT_FOCUS_CHANGE: {
7243 WindowState lastFocus;
7244 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07007245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007246 synchronized(mWindowMap) {
7247 lastFocus = mLastFocus;
7248 newFocus = mCurrentFocus;
7249 if (lastFocus == newFocus) {
7250 // Focus is not changing, so nothing to do.
7251 return;
7252 }
7253 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007254 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007255 // + " to " + newFocus);
7256 if (newFocus != null && lastFocus != null
7257 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007258 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007259 mLosingFocus.add(lastFocus);
7260 lastFocus = null;
7261 }
7262 }
7263
7264 if (lastFocus != newFocus) {
7265 //System.out.println("Changing focus from " + lastFocus
7266 // + " to " + newFocus);
7267 if (newFocus != null) {
7268 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007269 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007270 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
7271 } catch (RemoteException e) {
7272 // Ignore if process has died.
7273 }
Konstantin Lopyrev5e7833a2010-08-09 17:01:11 -07007274 notifyFocusChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007275 }
7276
7277 if (lastFocus != null) {
7278 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007279 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007280 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
7281 } catch (RemoteException e) {
7282 // Ignore if process has died.
7283 }
7284 }
7285 }
7286 } break;
7287
7288 case REPORT_LOSING_FOCUS: {
7289 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07007290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007291 synchronized(mWindowMap) {
7292 losers = mLosingFocus;
7293 mLosingFocus = new ArrayList<WindowState>();
7294 }
7295
7296 final int N = losers.size();
7297 for (int i=0; i<N; i++) {
7298 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007299 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007300 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
7301 } catch (RemoteException e) {
7302 // Ignore if process has died.
7303 }
7304 }
7305 } break;
7306
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08007307 case DO_TRAVERSAL: {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007308 synchronized(mWindowMap) {
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08007309 mTraversalScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007310 performLayoutAndPlaceSurfacesLocked();
7311 }
7312 } break;
7313
7314 case ADD_STARTING: {
7315 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7316 final StartingData sd = wtoken.startingData;
7317
7318 if (sd == null) {
7319 // Animation has been canceled... do nothing.
7320 return;
7321 }
Romain Guy06882f82009-06-10 13:36:04 -07007322
Joe Onorato8a9b2202010-02-26 18:56:32 -08007323 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007324 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07007325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007326 View view = null;
7327 try {
7328 view = mPolicy.addStartingWindow(
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07007329 wtoken.token, sd.pkg, sd.theme, sd.compatInfo,
7330 sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007331 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007332 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007333 }
7334
7335 if (view != null) {
7336 boolean abort = false;
7337
7338 synchronized(mWindowMap) {
7339 if (wtoken.removed || wtoken.startingData == null) {
7340 // If the window was successfully added, then
7341 // we need to remove it.
7342 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007343 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007344 "Aborted starting " + wtoken
7345 + ": removed=" + wtoken.removed
7346 + " startingData=" + wtoken.startingData);
7347 wtoken.startingWindow = null;
7348 wtoken.startingData = null;
7349 abort = true;
7350 }
7351 } else {
7352 wtoken.startingView = view;
7353 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007354 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007355 "Added starting " + wtoken
7356 + ": startingWindow="
7357 + wtoken.startingWindow + " startingView="
7358 + wtoken.startingView);
7359 }
7360
7361 if (abort) {
7362 try {
7363 mPolicy.removeStartingWindow(wtoken.token, view);
7364 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007365 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007366 }
7367 }
7368 }
7369 } break;
7370
7371 case REMOVE_STARTING: {
7372 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7373 IBinder token = null;
7374 View view = null;
7375 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007376 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007377 + wtoken + ": startingWindow="
7378 + wtoken.startingWindow + " startingView="
7379 + wtoken.startingView);
7380 if (wtoken.startingWindow != null) {
7381 view = wtoken.startingView;
7382 token = wtoken.token;
7383 wtoken.startingData = null;
7384 wtoken.startingView = null;
7385 wtoken.startingWindow = null;
Craig Mautner38b24782012-07-02 16:21:28 -07007386 wtoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007387 }
7388 }
7389 if (view != null) {
7390 try {
7391 mPolicy.removeStartingWindow(token, view);
7392 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007393 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007394 }
7395 }
7396 } break;
7397
7398 case FINISHED_STARTING: {
7399 IBinder token = null;
7400 View view = null;
7401 while (true) {
7402 synchronized (mWindowMap) {
7403 final int N = mFinishedStarting.size();
7404 if (N <= 0) {
7405 break;
7406 }
7407 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
7408
Joe Onorato8a9b2202010-02-26 18:56:32 -08007409 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007410 "Finished starting " + wtoken
7411 + ": startingWindow=" + wtoken.startingWindow
7412 + " startingView=" + wtoken.startingView);
7413
7414 if (wtoken.startingWindow == null) {
7415 continue;
7416 }
7417
7418 view = wtoken.startingView;
7419 token = wtoken.token;
7420 wtoken.startingData = null;
7421 wtoken.startingView = null;
7422 wtoken.startingWindow = null;
Craig Mautner38b24782012-07-02 16:21:28 -07007423 wtoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007424 }
7425
7426 try {
7427 mPolicy.removeStartingWindow(token, view);
7428 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007429 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007430 }
7431 }
7432 } break;
7433
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07007434 case REPORT_APPLICATION_TOKEN_DRAWN: {
7435 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7436
7437 try {
7438 if (DEBUG_VISIBILITY) Slog.v(
7439 TAG, "Reporting drawn in " + wtoken);
7440 wtoken.appToken.windowsDrawn();
7441 } catch (RemoteException ex) {
7442 }
7443 } break;
7444
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007445 case REPORT_APPLICATION_TOKEN_WINDOWS: {
7446 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7447
7448 boolean nowVisible = msg.arg1 != 0;
7449 boolean nowGone = msg.arg2 != 0;
7450
7451 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007452 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007453 TAG, "Reporting visible in " + wtoken
7454 + " visible=" + nowVisible
7455 + " gone=" + nowGone);
7456 if (nowVisible) {
7457 wtoken.appToken.windowsVisible();
7458 } else {
7459 wtoken.appToken.windowsGone();
7460 }
7461 } catch (RemoteException ex) {
7462 }
7463 } break;
Romain Guy06882f82009-06-10 13:36:04 -07007464
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007465 case WINDOW_FREEZE_TIMEOUT: {
Craig Mautner59c00972012-07-30 12:10:24 -07007466 // TODO(multidisplay): Can non-default displays rotate?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007467 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007468 Slog.w(TAG, "Window freeze timeout expired.");
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007469 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07007470 int i = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007471 while (i > 0) {
7472 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07007473 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007474 if (w.mOrientationChanging) {
7475 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007476 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007477 }
7478 }
7479 performLayoutAndPlaceSurfacesLocked();
7480 }
7481 break;
7482 }
Romain Guy06882f82009-06-10 13:36:04 -07007483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007484 case APP_TRANSITION_TIMEOUT: {
7485 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07007486 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007487 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007488 "*** APP TRANSITION TIMEOUT");
7489 mAppTransitionReady = true;
7490 mAppTransitionTimeout = true;
Craig Mautneref25d7a2012-05-15 23:01:47 -07007491 mAnimatingAppTokens.clear();
7492 mAnimatingAppTokens.addAll(mAppTokens);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007493 performLayoutAndPlaceSurfacesLocked();
7494 }
7495 }
7496 break;
7497 }
Romain Guy06882f82009-06-10 13:36:04 -07007498
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007499 case PERSIST_ANIMATION_SCALE: {
Jeff Sharkey6e2bee72012-10-01 13:39:08 -07007500 Settings.Global.putFloat(mContext.getContentResolver(),
7501 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
7502 Settings.Global.putFloat(mContext.getContentResolver(),
7503 Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
7504 Settings.Global.putFloat(mContext.getContentResolver(),
7505 Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007506 break;
7507 }
Romain Guy06882f82009-06-10 13:36:04 -07007508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007509 case FORCE_GC: {
Craig Mautner1caa3992012-06-22 09:46:48 -07007510 synchronized (mWindowMap) {
7511 synchronized (mAnimator) {
7512 // Since we're holding both mWindowMap and mAnimator we don't need to
7513 // hold mAnimator.mLayoutToAnim.
Craig Mautner711f90a2012-07-03 18:43:52 -07007514 if (mAnimator.mAnimating || mLayoutToAnim.mAnimationScheduled) {
Craig Mautner1caa3992012-06-22 09:46:48 -07007515 // If we are animating, don't do the gc now but
7516 // delay a bit so we don't interrupt the animation.
7517 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
7518 2000);
7519 return;
7520 }
7521 // If we are currently rotating the display, it will
7522 // schedule a new message when done.
7523 if (mDisplayFrozen) {
7524 return;
7525 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007526 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007527 }
7528 Runtime.getRuntime().gc();
7529 break;
7530 }
Romain Guy06882f82009-06-10 13:36:04 -07007531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007532 case ENABLE_SCREEN: {
7533 performEnableScreen();
7534 break;
7535 }
Romain Guy06882f82009-06-10 13:36:04 -07007536
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007537 case APP_FREEZE_TIMEOUT: {
7538 synchronized (mWindowMap) {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07007539 synchronized (mAnimator) {
7540 Slog.w(TAG, "App freeze timeout expired.");
7541 int i = mAppTokens.size();
7542 while (i > 0) {
7543 i--;
7544 AppWindowToken tok = mAppTokens.get(i);
Craig Mautner59431632012-04-04 11:56:44 -07007545 if (tok.mAppAnimator.freezingScreen) {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07007546 Slog.w(TAG, "Force clearing freeze: " + tok);
7547 unsetAppFreezingScreenLocked(tok, true, true);
7548 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007549 }
7550 }
7551 }
7552 break;
7553 }
Romain Guy06882f82009-06-10 13:36:04 -07007554
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007555 case CLIENT_FREEZE_TIMEOUT: {
7556 synchronized (mWindowMap) {
7557 if (mClientFreezingScreen) {
7558 mClientFreezingScreen = false;
7559 stopFreezingDisplayLocked();
7560 }
7561 }
7562 break;
7563 }
7564
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007565 case SEND_NEW_CONFIGURATION: {
7566 removeMessages(SEND_NEW_CONFIGURATION);
7567 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07007568 break;
7569 }
Romain Guy06882f82009-06-10 13:36:04 -07007570
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07007571 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007572 if (mWindowsChanged) {
7573 synchronized (mWindowMap) {
7574 mWindowsChanged = false;
7575 }
7576 notifyWindowsChanged();
7577 }
7578 break;
7579 }
7580
Christopher Tatea53146c2010-09-07 11:57:52 -07007581 case DRAG_START_TIMEOUT: {
7582 IBinder win = (IBinder)msg.obj;
7583 if (DEBUG_DRAG) {
7584 Slog.w(TAG, "Timeout starting drag by win " + win);
7585 }
7586 synchronized (mWindowMap) {
7587 // !!! TODO: ANR the app that has failed to start the drag in time
7588 if (mDragState != null) {
Chris Tated4533f12010-10-19 15:15:08 -07007589 mDragState.unregister();
Jeff Brown2e44b072011-01-24 15:21:56 -08007590 mInputMonitor.updateInputWindowsLw(true /*force*/);
Christopher Tatea53146c2010-09-07 11:57:52 -07007591 mDragState.reset();
7592 mDragState = null;
7593 }
7594 }
Chris Tated4533f12010-10-19 15:15:08 -07007595 break;
Christopher Tatea53146c2010-09-07 11:57:52 -07007596 }
7597
Chris Tated4533f12010-10-19 15:15:08 -07007598 case DRAG_END_TIMEOUT: {
7599 IBinder win = (IBinder)msg.obj;
7600 if (DEBUG_DRAG) {
7601 Slog.w(TAG, "Timeout ending drag to win " + win);
7602 }
7603 synchronized (mWindowMap) {
7604 // !!! TODO: ANR the drag-receiving app
Christopher Tated9be36c2011-08-16 16:09:33 -07007605 if (mDragState != null) {
7606 mDragState.mDragResult = false;
7607 mDragState.endDragLw();
7608 }
Chris Tated4533f12010-10-19 15:15:08 -07007609 }
7610 break;
7611 }
Jeff Brown2992ea72011-01-28 22:04:14 -08007612
7613 case REPORT_HARD_KEYBOARD_STATUS_CHANGE: {
7614 notifyHardKeyboardStatusChange();
7615 break;
7616 }
Dianne Hackborn38e29a62011-09-18 14:43:08 -07007617
7618 case BOOT_TIMEOUT: {
7619 performBootTimeout();
7620 break;
7621 }
7622
7623 case WAITING_FOR_DRAWN_TIMEOUT: {
7624 Pair<WindowState, IRemoteCallback> pair;
7625 synchronized (mWindowMap) {
7626 pair = (Pair<WindowState, IRemoteCallback>)msg.obj;
7627 Slog.w(TAG, "Timeout waiting for drawn: " + pair.first);
7628 if (!mWaitingForDrawn.remove(pair)) {
7629 return;
7630 }
7631 }
7632 try {
7633 pair.second.sendResult(null);
7634 } catch (RemoteException e) {
7635 }
7636 break;
7637 }
Craig Mautnera608b882012-03-30 13:03:49 -07007638
Craig Mautner01cd0e72012-06-18 10:19:11 -07007639 case UPDATE_ANIM_PARAMETERS: {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07007640 // Used to send multiple changes from the animation side to the layout side.
Craig Mautnera608b882012-03-30 13:03:49 -07007641 synchronized (mWindowMap) {
Craig Mautner322e4032012-07-13 13:35:20 -07007642 if (copyAnimToLayoutParamsLocked()) {
7643 mH.sendEmptyMessage(CLEAR_PENDING_ACTIONS);
7644 performLayoutAndPlaceSurfacesLocked();
Craig Mautner73850cb2012-04-10 12:56:27 -07007645 }
Craig Mautnera608b882012-03-30 13:03:49 -07007646 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07007647 break;
7648 }
7649
Craig Mautner0447a812012-05-22 16:01:31 -07007650 case SHOW_STRICT_MODE_VIOLATION: {
7651 showStrictModeViolation(msg.arg1);
7652 break;
7653 }
7654
Craig Mautner48ba1e72012-04-02 13:18:16 -07007655 // Animation messages. Move to Window{State}Animator
7656 case SET_TRANSPARENT_REGION: {
Craig Mautnerbec53f72012-04-05 11:49:05 -07007657 Pair<WindowStateAnimator, Region> pair =
Craig Mautner48ba1e72012-04-02 13:18:16 -07007658 (Pair<WindowStateAnimator, Region>) msg.obj;
Craig Mautnerbec53f72012-04-05 11:49:05 -07007659 final WindowStateAnimator winAnimator = pair.first;
7660 winAnimator.setTransparentRegionHint(pair.second);
Craig Mautner48ba1e72012-04-02 13:18:16 -07007661 break;
7662 }
7663
Craig Mautner4d7349b2012-04-20 14:52:47 -07007664 case CLEAR_PENDING_ACTIONS: {
7665 mAnimator.clearPendingActions();
7666 break;
7667 }
Dianne Hackborn84375872012-06-01 19:03:50 -07007668
7669 case DO_ANIMATION_CALLBACK: {
7670 try {
7671 ((IRemoteCallback)msg.obj).sendResult(null);
7672 } catch (RemoteException e) {
7673 }
7674 break;
7675 }
Craig Mautner722285e2012-09-07 13:55:58 -07007676
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07007677 case NOTIFY_ROTATION_CHANGED: {
7678 final int displayId = msg.arg1;
7679 final int rotation = msg.arg2;
7680 handleNotifyRotationChanged(displayId, rotation);
7681 break;
7682 }
Craig Mautner722285e2012-09-07 13:55:58 -07007683
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07007684 case NOTIFY_WINDOW_TRANSITION: {
7685 final int transition = msg.arg1;
7686 WindowInfo info = (WindowInfo) msg.obj;
7687 handleNotifyWindowTranstion(transition, info);
7688 break;
7689 }
Craig Mautner722285e2012-09-07 13:55:58 -07007690
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07007691 case NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED: {
7692 final int displayId = msg.arg1;
7693 final boolean immediate = (msg.arg2 == 1);
7694 Rect rectangle = (Rect) msg.obj;
7695 handleNotifyRectangleOnScreenRequested(displayId, rectangle, immediate);
7696 break;
7697 }
Craig Mautner722285e2012-09-07 13:55:58 -07007698
7699 case DO_DISPLAY_ADDED:
7700 synchronized (mWindowMap) {
7701 handleDisplayAddedLocked(msg.arg1);
7702 }
7703 break;
7704
7705 case DO_DISPLAY_REMOVED:
7706 synchronized (mWindowMap) {
7707 handleDisplayRemovedLocked(msg.arg1);
7708 }
7709 break;
7710
7711 case DO_DISPLAY_CHANGED:
7712 synchronized (mWindowMap) {
7713 handleDisplayChangedLocked(msg.arg1);
7714 }
7715 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007716 }
Craig Mautner7d8df392012-04-06 15:26:23 -07007717 if (DEBUG_WINDOW_TRACE) {
7718 Slog.v(TAG, "handleMessage: exit");
7719 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007720 }
7721 }
7722
7723 // -------------------------------------------------------------
7724 // IWindowManager API
7725 // -------------------------------------------------------------
7726
Craig Mautner7d8df392012-04-06 15:26:23 -07007727 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007728 public IWindowSession openSession(IInputMethodClient client,
7729 IInputContext inputContext) {
7730 if (client == null) throw new IllegalArgumentException("null client");
7731 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08007732 Session session = new Session(this, client, inputContext);
Jeff Brown46b9ac02010-04-22 18:58:52 -07007733 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007734 }
7735
Craig Mautner7d8df392012-04-06 15:26:23 -07007736 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007737 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
7738 synchronized (mWindowMap) {
7739 // The focus for the client is the window immediately below
7740 // where we would place the input method window.
7741 int idx = findDesiredInputMethodWindowIndexLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007742 if (idx > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07007743 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007744 WindowState imFocus = getDefaultWindowListLocked().get(idx-1);
Dianne Hackbornac920872012-05-22 11:49:49 -07007745 if (DEBUG_INPUT_METHOD) {
7746 Slog.i(TAG, "Desired input method target: " + imFocus);
Craig Mautner59c00972012-07-30 12:10:24 -07007747 Slog.i(TAG, "Current focus: " + mCurrentFocus);
7748 Slog.i(TAG, "Last focus: " + mLastFocus);
Dianne Hackbornac920872012-05-22 11:49:49 -07007749 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007750 if (imFocus != null) {
Dianne Hackborne75d8722011-01-27 19:37:40 -08007751 // This may be a starting window, in which case we still want
7752 // to count it as okay.
7753 if (imFocus.mAttrs.type == LayoutParams.TYPE_APPLICATION_STARTING
7754 && imFocus.mAppToken != null) {
7755 // The client has definitely started, so it really should
7756 // have a window in this app token. Let's look for it.
7757 for (int i=0; i<imFocus.mAppToken.windows.size(); i++) {
7758 WindowState w = imFocus.mAppToken.windows.get(i);
7759 if (w != imFocus) {
Dianne Hackbornac920872012-05-22 11:49:49 -07007760 Log.i(TAG, "Switching to real app window: " + w);
Dianne Hackborne75d8722011-01-27 19:37:40 -08007761 imFocus = w;
7762 break;
7763 }
7764 }
7765 }
Dianne Hackbornac920872012-05-22 11:49:49 -07007766 if (DEBUG_INPUT_METHOD) {
7767 Slog.i(TAG, "IM target client: " + imFocus.mSession.mClient);
7768 if (imFocus.mSession.mClient != null) {
7769 Slog.i(TAG, "IM target client binder: "
7770 + imFocus.mSession.mClient.asBinder());
7771 Slog.i(TAG, "Requesting client binder: " + client.asBinder());
7772 }
7773 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007774 if (imFocus.mSession.mClient != null &&
7775 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
7776 return true;
7777 }
7778 }
7779 }
Craig Mautner59c00972012-07-30 12:10:24 -07007780
7781 // Okay, how about this... what is the current focus?
7782 // It seems in some cases we may not have moved the IM
7783 // target window, such as when it was in a pop-up window,
7784 // so let's also look at the current focus. (An example:
7785 // go to Gmail, start searching so the keyboard goes up,
7786 // press home. Sometimes the IME won't go down.)
7787 // Would be nice to fix this more correctly, but it's
7788 // way at the end of a release, and this should be good enough.
7789 if (mCurrentFocus != null && mCurrentFocus.mSession.mClient != null
7790 && mCurrentFocus.mSession.mClient.asBinder() == client.asBinder()) {
7791 return true;
7792 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007793 }
7794 return false;
7795 }
Romain Guy06882f82009-06-10 13:36:04 -07007796
Craig Mautner59c00972012-07-30 12:10:24 -07007797 public void getInitialDisplaySize(int displayId, Point size) {
7798 // TODO(cmautner): Access to DisplayContent should be locked on mWindowMap. Doing that
7799 // could lead to deadlock since this is called from ActivityManager.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007800 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner59c00972012-07-30 12:10:24 -07007801 synchronized(displayContent.mDisplaySizeLock) {
7802 size.x = displayContent.mInitialDisplayWidth;
7803 size.y = displayContent.mInitialDisplayHeight;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007804 }
7805 }
7806
Jeff Brown43aa1592012-09-10 17:36:31 -07007807 public void setForcedDisplaySize(int displayId, int width, int height) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007808 synchronized(mWindowMap) {
Jeff Brown43aa1592012-09-10 17:36:31 -07007809 // Set some sort of reasonable bounds on the size of the display that we
7810 // will try to emulate.
7811 final int MIN_WIDTH = 200;
7812 final int MIN_HEIGHT = 200;
7813 final int MAX_SCALE = 2;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007814 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Jeff Brown43aa1592012-09-10 17:36:31 -07007815
7816 width = Math.min(Math.max(width, MIN_WIDTH),
7817 displayContent.mInitialDisplayWidth * MAX_SCALE);
7818 height = Math.min(Math.max(height, MIN_HEIGHT),
7819 displayContent.mInitialDisplayHeight * MAX_SCALE);
Craig Mautner59c00972012-07-30 12:10:24 -07007820 setForcedDisplaySizeLocked(displayContent, width, height);
Jeff Brown43aa1592012-09-10 17:36:31 -07007821 Settings.Global.putString(mContext.getContentResolver(),
7822 Settings.Global.DISPLAY_SIZE_FORCED, width + "," + height);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007823 }
7824 }
7825
Dianne Hackborndde331c2012-08-03 14:01:57 -07007826 private void readForcedDisplaySizeAndDensityLocked(final DisplayContent displayContent) {
Jeff Brown43aa1592012-09-10 17:36:31 -07007827 final String sizeStr = Settings.Global.getString(mContext.getContentResolver(),
7828 Settings.Global.DISPLAY_SIZE_FORCED);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007829 if (sizeStr != null && sizeStr.length() > 0) {
7830 final int pos = sizeStr.indexOf(',');
7831 if (pos > 0 && sizeStr.lastIndexOf(',') == pos) {
7832 int width, height;
7833 try {
7834 width = Integer.parseInt(sizeStr.substring(0, pos));
7835 height = Integer.parseInt(sizeStr.substring(pos+1));
7836 synchronized(displayContent.mDisplaySizeLock) {
7837 if (displayContent.mBaseDisplayWidth != width
7838 || displayContent.mBaseDisplayHeight != height) {
Dianne Hackborndde331c2012-08-03 14:01:57 -07007839 Slog.i(TAG, "FORCED DISPLAY SIZE: " + width + "x" + height);
7840 displayContent.mBaseDisplayWidth = width;
7841 displayContent.mBaseDisplayHeight = height;
7842 }
7843 }
7844 } catch (NumberFormatException ex) {
7845 }
7846 }
Joe Onorato571ae902011-05-24 13:48:43 -07007847 }
Jeff Brown43aa1592012-09-10 17:36:31 -07007848 final String densityStr = Settings.Global.getString(mContext.getContentResolver(),
7849 Settings.Global.DISPLAY_DENSITY_FORCED);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007850 if (densityStr != null && densityStr.length() > 0) {
7851 int density;
7852 try {
7853 density = Integer.parseInt(densityStr);
7854 synchronized(displayContent.mDisplaySizeLock) {
7855 if (displayContent.mBaseDisplayDensity != density) {
Dianne Hackborndde331c2012-08-03 14:01:57 -07007856 Slog.i(TAG, "FORCED DISPLAY DENSITY: " + density);
7857 displayContent.mBaseDisplayDensity = density;
7858 }
7859 }
7860 } catch (NumberFormatException ex) {
7861 }
Joe Onorato571ae902011-05-24 13:48:43 -07007862 }
Joe Onorato571ae902011-05-24 13:48:43 -07007863 }
7864
Craig Mautner59c00972012-07-30 12:10:24 -07007865 private void setForcedDisplaySizeLocked(DisplayContent displayContent, int width, int height) {
Joe Onorato571ae902011-05-24 13:48:43 -07007866 Slog.i(TAG, "Using new display size: " + width + "x" + height);
7867
Craig Mautner59c00972012-07-30 12:10:24 -07007868 synchronized(displayContent.mDisplaySizeLock) {
7869 displayContent.mBaseDisplayWidth = width;
7870 displayContent.mBaseDisplayHeight = height;
Dianne Hackborn1fbee792011-11-30 11:29:58 -08007871 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007872 reconfigureDisplayLocked(displayContent);
7873 }
7874
7875 public void clearForcedDisplaySize(int displayId) {
7876 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007877 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007878 setForcedDisplaySizeLocked(displayContent, displayContent.mInitialDisplayWidth,
7879 displayContent.mInitialDisplayHeight);
Jeff Brown43aa1592012-09-10 17:36:31 -07007880 Settings.Global.putString(mContext.getContentResolver(),
7881 Settings.Global.DISPLAY_SIZE_FORCED, "");
Dianne Hackborndde331c2012-08-03 14:01:57 -07007882 }
7883 }
7884
7885 public void setForcedDisplayDensity(int displayId, int density) {
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, density);
Jeff Brown43aa1592012-09-10 17:36:31 -07007889 Settings.Global.putString(mContext.getContentResolver(),
7890 Settings.Global.DISPLAY_DENSITY_FORCED, Integer.toString(density));
Dianne Hackborndde331c2012-08-03 14:01:57 -07007891 }
7892 }
7893
7894 private void setForcedDisplayDensityLocked(DisplayContent displayContent, int density) {
7895 Slog.i(TAG, "Using new display density: " + density);
7896
7897 synchronized(displayContent.mDisplaySizeLock) {
7898 displayContent.mBaseDisplayDensity = density;
7899 }
7900 reconfigureDisplayLocked(displayContent);
7901 }
7902
7903 public void clearForcedDisplayDensity(int displayId) {
7904 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007905 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007906 setForcedDisplayDensityLocked(displayContent, displayContent.mInitialDisplayDensity);
Jeff Brownbf6f6f92012-09-25 15:03:20 -07007907 Settings.Global.putString(mContext.getContentResolver(),
7908 Settings.Global.DISPLAY_DENSITY_FORCED, "");
Dianne Hackborndde331c2012-08-03 14:01:57 -07007909 }
7910 }
7911
7912 private void reconfigureDisplayLocked(DisplayContent displayContent) {
Craig Mautner69b08182012-09-05 13:07:13 -07007913 // TODO: Multidisplay: for now only use with default display.
Jeff Browne215f262012-09-10 16:01:14 -07007914 mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
7915 displayContent.mBaseDisplayWidth,
7916 displayContent.mBaseDisplayHeight,
7917 displayContent.mBaseDisplayDensity);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007918
Craig Mautner19d59bc2012-09-04 11:15:56 -07007919 displayContent.layoutNeeded = true;
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007920
7921 boolean configChanged = updateOrientationFromAppTokensLocked(false);
7922 mTempConfiguration.setToDefaults();
7923 mTempConfiguration.fontScale = mCurConfiguration.fontScale;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08007924 if (computeScreenConfigurationLocked(mTempConfiguration)) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007925 if (mCurConfiguration.diff(mTempConfiguration) != 0) {
7926 configChanged = true;
7927 }
7928 }
7929
7930 if (configChanged) {
7931 mWaitingForConfig = true;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007932 startFreezingDisplayLocked(false, 0, 0);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007933 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
7934 }
7935
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007936 performLayoutAndPlaceSurfacesLocked();
7937 }
7938
Dianne Hackbornf87d1962012-04-04 12:48:24 -07007939 public boolean hasSystemNavBar() {
7940 return mPolicy.hasSystemNavBar();
Dianne Hackborn81e56d52011-05-26 00:55:58 -07007941 }
7942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007943 // -------------------------------------------------------------
7944 // Internals
7945 // -------------------------------------------------------------
7946
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007947 final WindowState windowForClientLocked(Session session, IWindow client,
7948 boolean throwOnError) {
7949 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007950 }
Romain Guy06882f82009-06-10 13:36:04 -07007951
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007952 final WindowState windowForClientLocked(Session session, IBinder client,
7953 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007954 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007955 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007956 TAG, "Looking up client " + client + ": " + win);
7957 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007958 RuntimeException ex = new IllegalArgumentException(
7959 "Requested window " + client + " does not exist");
7960 if (throwOnError) {
7961 throw ex;
7962 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007963 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007964 return null;
7965 }
7966 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007967 RuntimeException ex = new IllegalArgumentException(
7968 "Requested window " + client + " is in session " +
7969 win.mSession + ", not " + session);
7970 if (throwOnError) {
7971 throw ex;
7972 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007973 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007974 return null;
7975 }
7976
7977 return win;
7978 }
7979
Dianne Hackborna8f60182009-09-01 19:01:50 -07007980 final void rebuildAppWindowListLocked() {
Craig Mautner59c00972012-07-30 12:10:24 -07007981 DisplayContentsIterator iterator = new DisplayContentsIterator();
7982 while (iterator.hasNext()) {
7983 rebuildAppWindowListLocked(iterator.next());
7984 }
7985 }
7986
7987 private void rebuildAppWindowListLocked(final DisplayContent displayContent) {
7988 final WindowList windows = displayContent.getWindowList();
7989 int NW = windows.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07007990 int i;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007991 int lastBelow = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007992 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007993
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007994 if (mRebuildTmp.length < NW) {
7995 mRebuildTmp = new WindowState[NW+10];
7996 }
7997
Dianne Hackborna8f60182009-09-01 19:01:50 -07007998 // First remove all existing app windows.
7999 i=0;
8000 while (i < NW) {
Craig Mautner59c00972012-07-30 12:10:24 -07008001 WindowState w = windows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008002 if (w.mAppToken != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07008003 WindowState win = windows.remove(i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008004 win.mRebuilding = true;
8005 mRebuildTmp[numRemoved] = win;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008006 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008007 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008008 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008009 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008010 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07008011 continue;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008012 } else if (lastBelow == i-1) {
Craig Mautner65d11b32012-10-01 13:59:52 -07008013 if (w.mAttrs.type == TYPE_WALLPAPER || w.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008014 lastBelow = i;
8015 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07008016 }
8017 i++;
8018 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008019
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008020 // Keep whatever windows were below the app windows still below,
8021 // by skipping them.
8022 lastBelow++;
8023 i = lastBelow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008024
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008025 // First add all of the exiting app tokens... these are no longer
8026 // in the main app list, but still have windows shown. We put them
8027 // in the back because now that the animation is over we no longer
8028 // will care about them.
8029 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07008030 for (int j=0; j<NT; j++) {
Craig Mautner59c00972012-07-30 12:10:24 -07008031 i = reAddAppWindowsLocked(displayContent, i, mExitingAppTokens.get(j));
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008032 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008033
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008034 // And add in the still active app tokens in Z order.
Craig Mautneref25d7a2012-05-15 23:01:47 -07008035 NT = mAnimatingAppTokens.size();
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008036 for (int j=0; j<NT; j++) {
Craig Mautner59c00972012-07-30 12:10:24 -07008037 i = reAddAppWindowsLocked(displayContent, i, mAnimatingAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07008038 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008039
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008040 i -= lastBelow;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008041 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008042 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008043 + " windows but added " + i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008044 for (i=0; i<numRemoved; i++) {
8045 WindowState ws = mRebuildTmp[i];
8046 if (ws.mRebuilding) {
8047 StringWriter sw = new StringWriter();
8048 PrintWriter pw = new PrintWriter(sw);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07008049 ws.dump(pw, "", true);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008050 pw.flush();
8051 Slog.w(TAG, "This window was lost: " + ws);
8052 Slog.w(TAG, sw.toString());
Craig Mautnerf20588f2012-04-11 17:06:21 -07008053 ws.mWinAnimator.destroySurfaceLocked();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008054 }
8055 }
8056 Slog.w(TAG, "Current app token list:");
Craig Mautneref25d7a2012-05-15 23:01:47 -07008057 dumpAnimatingAppTokensLocked();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008058 Slog.w(TAG, "Final window list:");
8059 dumpWindowsLocked();
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008060 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07008061 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008062
Craig Mautner59c00972012-07-30 12:10:24 -07008063 private final void assignLayersLocked(WindowList windows) {
8064 int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008065 int curBaseLayer = 0;
8066 int curLayer = 0;
8067 int i;
Romain Guy06882f82009-06-10 13:36:04 -07008068
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08008069 if (DEBUG_LAYERS) {
8070 RuntimeException here = new RuntimeException("here");
8071 here.fillInStackTrace();
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008072 Slog.v(TAG, "Assigning layers", here);
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08008073 }
8074
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008075 for (i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07008076 final WindowState w = windows.get(i);
Craig Mautneracafd192012-05-10 10:41:02 -07008077 final WindowStateAnimator winAnimator = w.mWinAnimator;
8078 boolean layerChanged = false;
8079 int oldLayer = w.mLayer;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008080 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
8081 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008082 curLayer += WINDOW_LAYER_MULTIPLIER;
8083 w.mLayer = curLayer;
8084 } else {
8085 curBaseLayer = curLayer = w.mBaseLayer;
8086 w.mLayer = curLayer;
8087 }
Craig Mautneracafd192012-05-10 10:41:02 -07008088 if (w.mLayer != oldLayer) {
8089 layerChanged = true;
8090 }
8091 oldLayer = winAnimator.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008092 if (w.mTargetAppToken != null) {
Craig Mautneracafd192012-05-10 10:41:02 -07008093 winAnimator.mAnimLayer =
Craig Mautner59431632012-04-04 11:56:44 -07008094 w.mLayer + w.mTargetAppToken.mAppAnimator.animLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008095 } else if (w.mAppToken != null) {
Craig Mautneracafd192012-05-10 10:41:02 -07008096 winAnimator.mAnimLayer =
Craig Mautner59431632012-04-04 11:56:44 -07008097 w.mLayer + w.mAppToken.mAppAnimator.animLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008098 } else {
Craig Mautneracafd192012-05-10 10:41:02 -07008099 winAnimator.mAnimLayer = w.mLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008100 }
8101 if (w.mIsImWindow) {
Craig Mautneracafd192012-05-10 10:41:02 -07008102 winAnimator.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008103 } else if (w.mIsWallpaper) {
Craig Mautneracafd192012-05-10 10:41:02 -07008104 winAnimator.mAnimLayer += mWallpaperAnimLayerAdjustment;
8105 }
8106 if (winAnimator.mAnimLayer != oldLayer) {
8107 layerChanged = true;
8108 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07008109 if (layerChanged && mAnimator.isDimmingLocked(winAnimator)) {
Craig Mautneracafd192012-05-10 10:41:02 -07008110 // Force an animation pass just to update the mDimAnimator layer.
Craig Mautner711f90a2012-07-03 18:43:52 -07008111 updateLayoutToAnimationLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008112 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008113 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
Craig Mautner8863cca2012-09-18 15:04:34 -07008114 + "mBase=" + w.mBaseLayer
8115 + " mLayer=" + w.mLayer
8116 + (w.mAppToken == null ?
8117 "" : " mAppLayer=" + w.mAppToken.mAppAnimator.animLayerAdjustment)
8118 + " =mAnimLayer=" + winAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008119 //System.out.println(
8120 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
8121 }
8122 }
8123
8124 private boolean mInLayout = false;
8125 private final void performLayoutAndPlaceSurfacesLocked() {
8126 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07008127 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008128 throw new RuntimeException("Recursive call!");
8129 }
Craig Mautneref25d7a2012-05-15 23:01:47 -07008130 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
8131 + Debug.getCallers(3));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008132 return;
8133 }
8134
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008135 if (mWaitingForConfig) {
8136 // Our configuration has changed (most likely rotation), but we
8137 // don't yet have the complete configuration to report to
8138 // applications. Don't do any window layout until we have it.
8139 return;
8140 }
8141
Jeff Browne215f262012-09-10 16:01:14 -07008142 if (!mDisplayReady) {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008143 // Not yet initialized, nothing to do.
8144 return;
8145 }
8146
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07008147 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008148 mInLayout = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008149 boolean recoveringMemory = false;
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008150
8151 try {
8152 if (mForceRemoves != null) {
8153 recoveringMemory = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008154 // Wait a little bit for things to settle down, and off we go.
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008155 for (int i=0; i<mForceRemoves.size(); i++) {
8156 WindowState ws = mForceRemoves.get(i);
8157 Slog.i(TAG, "Force removing: " + ws);
8158 removeWindowInnerLocked(ws.mSession, ws);
8159 }
8160 mForceRemoves = null;
8161 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
8162 Object tmp = new Object();
8163 synchronized (tmp) {
8164 try {
8165 tmp.wait(250);
8166 } catch (InterruptedException e) {
8167 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008168 }
8169 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008170 } catch (RuntimeException e) {
Dianne Hackborn89620282011-09-11 12:47:45 -07008171 Log.wtf(TAG, "Unhandled exception while force removing for memory", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008172 }
Craig Mautner59c00972012-07-30 12:10:24 -07008173
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008174 try {
Craig Mautner76a71652012-09-03 23:23:58 -07008175 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Craig Mautnerbb1449b2012-03-23 16:11:14 -07008176
Craig Mautner59c00972012-07-30 12:10:24 -07008177 mInLayout = false;
8178
Craig Mautner19d59bc2012-09-04 11:15:56 -07008179 if (needsLayout()) {
Craig Mautnerbb1449b2012-03-23 16:11:14 -07008180 if (++mLayoutRepeatCount < 6) {
8181 requestTraversalLocked();
8182 } else {
8183 Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
8184 mLayoutRepeatCount = 0;
8185 }
8186 } else {
8187 mLayoutRepeatCount = 0;
8188 }
Craig Mautnerbb1449b2012-03-23 16:11:14 -07008189
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008190 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008191 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
8192 mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008193 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008194 } catch (RuntimeException e) {
8195 mInLayout = false;
Dianne Hackborn89620282011-09-11 12:47:45 -07008196 Log.wtf(TAG, "Unhandled exception while laying out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008197 }
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07008198
8199 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008200 }
8201
Craig Mautner59c00972012-07-30 12:10:24 -07008202 private final void performLayoutLockedInner(final DisplayContent displayContent,
8203 boolean initial, boolean updateInputWindows) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07008204 if (!displayContent.layoutNeeded) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008205 return;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008206 }
Craig Mautner19d59bc2012-09-04 11:15:56 -07008207 displayContent.layoutNeeded = false;
Craig Mautner59c00972012-07-30 12:10:24 -07008208 WindowList windows = displayContent.getWindowList();
Craig Mautner69b08182012-09-05 13:07:13 -07008209 boolean isDefaultDisplay = displayContent.isDefaultDisplay;
Craig Mautner59c00972012-07-30 12:10:24 -07008210
8211 DisplayInfo displayInfo = displayContent.getDisplayInfo();
8212 final int dw = displayInfo.logicalWidth;
8213 final int dh = displayInfo.logicalHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008214
Dianne Hackborndf89e652011-10-06 22:35:11 -07008215 final int NFW = mFakeWindows.size();
8216 for (int i=0; i<NFW; i++) {
8217 mFakeWindows.get(i).layout(dw, dh);
8218 }
8219
Craig Mautner59c00972012-07-30 12:10:24 -07008220 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008221 int i;
8222
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008223 if (DEBUG_LAYOUT) {
8224 Slog.v(TAG, "-------------------------------------");
8225 Slog.v(TAG, "performLayout: needed="
Craig Mautner19d59bc2012-09-04 11:15:56 -07008226 + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008227 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008228
8229 WindowStateAnimator universeBackground = null;
8230
Craig Mautner69b08182012-09-05 13:07:13 -07008231 mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mRotation);
8232 if (isDefaultDisplay) {
8233 // Not needed on non-default displays.
8234 mSystemDecorLayer = mPolicy.getSystemDecorRectLw(mSystemDecorRect);
8235 mScreenRect.set(0, 0, dw, dh);
8236 }
Romain Guy06882f82009-06-10 13:36:04 -07008237
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008238 int seq = mLayoutSeq+1;
8239 if (seq < 0) seq = 0;
8240 mLayoutSeq = seq;
8241
8242 // First perform layout of any root windows (not attached
8243 // to another window).
8244 int topAttached = -1;
8245 for (i = N-1; i >= 0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07008246 final WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008247
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008248 // Don't do layout of a window if it is not visible, or
8249 // soon won't be visible, to avoid wasting time and funky
8250 // changes while a window is animating away.
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008251 final boolean gone = win.isGoneForLayoutLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008252
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008253 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008254 Slog.v(TAG, "1ST PASS " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008255 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
Craig Mautner812d2ca2012-09-27 15:35:34 -07008256 + " mLayoutAttached=" + win.mLayoutAttached
8257 + " screen changed=" + win.isConfigDiff(ActivityInfo.CONFIG_SCREEN_SIZE));
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008258 final AppWindowToken atoken = win.mAppToken;
8259 if (gone) Slog.v(TAG, " GONE: mViewVisibility="
8260 + win.mViewVisibility + " mRelayoutCalled="
8261 + win.mRelayoutCalled + " hidden="
8262 + win.mRootToken.hidden + " hiddenRequested="
8263 + (atoken != null && atoken.hiddenRequested)
8264 + " mAttachedHidden=" + win.mAttachedHidden);
8265 else Slog.v(TAG, " VIS: mViewVisibility="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008266 + win.mViewVisibility + " mRelayoutCalled="
8267 + win.mRelayoutCalled + " hidden="
8268 + win.mRootToken.hidden + " hiddenRequested="
8269 + (atoken != null && atoken.hiddenRequested)
8270 + " mAttachedHidden=" + win.mAttachedHidden);
8271 }
Craig Mautner69b08182012-09-05 13:07:13 -07008272
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008273 // If this view is GONE, then skip it -- keep the current
8274 // frame, and let the caller know so they can ignore it
8275 // if they want. (We do the normal layout for INVISIBLE
8276 // windows, since that means "perform layout as normal,
8277 // just don't display").
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008278 if (!gone || !win.mHaveFrame || win.mLayoutNeeded
Craig Mautner812d2ca2012-09-27 15:35:34 -07008279 || win.isConfigDiff(ActivityInfo.CONFIG_SCREEN_SIZE)
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008280 || win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008281 if (!win.mLayoutAttached) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008282 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08008283 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008284 win.mContentChanged = false;
8285 }
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008286 win.mLayoutNeeded = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008287 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008288 mPolicy.layoutWindowLw(win, win.mAttrs, null);
8289 win.mLayoutSeq = seq;
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008290 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008291 + win.mFrame + " mContainingFrame="
8292 + win.mContainingFrame + " mDisplayFrame="
8293 + win.mDisplayFrame);
8294 } else {
8295 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008296 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07008297 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008298 if (win.mViewVisibility == View.VISIBLE
8299 && win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND
8300 && universeBackground == null) {
8301 universeBackground = win.mWinAnimator;
8302 }
8303 }
8304
8305 if (mAnimator.mUniverseBackground != universeBackground) {
8306 mFocusMayChange = true;
8307 mAnimator.mUniverseBackground = universeBackground;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008308 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008309
8310 // Now perform layout of attached windows, which usually
8311 // depend on the position of the window they are attached to.
8312 // XXX does not deal with windows that are attached to windows
8313 // that are themselves attached.
8314 for (i = topAttached; i >= 0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07008315 final WindowState win = windows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008316
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008317 if (win.mLayoutAttached) {
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008318 if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008319 + " mHaveFrame=" + win.mHaveFrame
8320 + " mViewVisibility=" + win.mViewVisibility
8321 + " mRelayoutCalled=" + win.mRelayoutCalled);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008322 // If this view is GONE, then skip it -- keep the current
8323 // frame, and let the caller know so they can ignore it
8324 // if they want. (We do the normal layout for INVISIBLE
8325 // windows, since that means "perform layout as normal,
8326 // just don't display").
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008327 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008328 || !win.mHaveFrame || win.mLayoutNeeded) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008329 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08008330 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008331 win.mContentChanged = false;
8332 }
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008333 win.mLayoutNeeded = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008334 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008335 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
8336 win.mLayoutSeq = seq;
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008337 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008338 + win.mFrame + " mContainingFrame="
8339 + win.mContainingFrame + " mDisplayFrame="
8340 + win.mDisplayFrame);
8341 }
8342 }
8343 }
Jeff Brown349703e2010-06-22 01:27:15 -07008344
8345 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown3a22cd92011-01-21 13:59:04 -08008346 mInputMonitor.setUpdateInputWindowsNeededLw();
8347 if (updateInputWindows) {
Jeff Brown2e44b072011-01-24 15:21:56 -08008348 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08008349 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008350
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008351 mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008352 }
Romain Guy06882f82009-06-10 13:36:04 -07008353
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008354 void makeWindowFreezingScreenIfNeededLocked(WindowState w) {
8355 // If the screen is currently frozen or off, then keep
8356 // it frozen/off until this window draws at its new
8357 // orientation.
Craig Mautner2fb98b12012-03-20 17:24:00 -07008358 if (!okToDisplay()) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008359 if (DEBUG_ORIENTATION) Slog.v(TAG,
8360 "Changing surface while display frozen: " + w);
8361 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07008362 mInnerFields.mOrientationChangeComplete = false;
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008363 if (!mWindowsFreezingScreen) {
8364 mWindowsFreezingScreen = true;
8365 // XXX should probably keep timeout from
8366 // when we first froze the display.
8367 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
8368 mH.sendMessageDelayed(mH.obtainMessage(
8369 H.WINDOW_FREEZE_TIMEOUT), 2000);
8370 }
8371 }
8372 }
8373
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008374 /**
8375 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
Craig Mautner19d59bc2012-09-04 11:15:56 -07008376 * @param windows List of windows on default display.
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008377 * @return bitmap indicating if another pass through layout must be made.
8378 */
Craig Mautner59c00972012-07-30 12:10:24 -07008379 public int handleAppTransitionReadyLocked(WindowList windows) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008380 int changes = 0;
8381 int i;
8382 int NN = mOpeningApps.size();
8383 boolean goodToGo = true;
8384 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8385 "Checking " + NN + " opening apps (frozen="
8386 + mDisplayFrozen + " timeout="
8387 + mAppTransitionTimeout + ")...");
8388 if (!mDisplayFrozen && !mAppTransitionTimeout) {
8389 // If the display isn't frozen, wait to do anything until
8390 // all of the apps are ready. Otherwise just go because
8391 // we'll unfreeze the display when everyone is ready.
8392 for (i=0; i<NN && goodToGo; i++) {
8393 AppWindowToken wtoken = mOpeningApps.get(i);
8394 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Craig Mautner1d961d42012-05-27 12:02:11 -07008395 "Check opening app=" + wtoken + ": allDrawn="
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008396 + wtoken.allDrawn + " startingDisplayed="
Craig Mautner7358fbf2012-04-12 21:06:33 -07008397 + wtoken.startingDisplayed + " startingMoved="
8398 + wtoken.startingMoved);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008399 if (!wtoken.allDrawn && !wtoken.startingDisplayed
8400 && !wtoken.startingMoved) {
8401 goodToGo = false;
8402 }
8403 }
8404 }
8405 if (goodToGo) {
8406 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
8407 int transit = mNextAppTransition;
8408 if (mSkipAppTransitionAnimation) {
8409 transit = WindowManagerPolicy.TRANSIT_UNSET;
8410 }
8411 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
8412 mAppTransitionReady = false;
8413 mAppTransitionRunning = true;
8414 mAppTransitionTimeout = false;
8415 mStartingIconInTransition = false;
8416 mSkipAppTransitionAnimation = false;
8417
8418 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
8419
Craig Mautneref25d7a2012-05-15 23:01:47 -07008420 rebuildAppWindowListLocked();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008421
Craig Mautner0afddcb2012-05-08 15:38:00 -07008422 // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
Craig Mautner83339b42012-05-01 22:13:23 -07008423 WindowState oldWallpaper =
8424 mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
Craig Mautner0afddcb2012-05-08 15:38:00 -07008425 && !mWallpaperTarget.mWinAnimator.isDummyAnimation()
Craig Mautner83339b42012-05-01 22:13:23 -07008426 ? null : mWallpaperTarget;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008427
8428 adjustWallpaperWindowsLocked();
8429 mInnerFields.mWallpaperMayChange = false;
8430
8431 // The top-most window will supply the layout params,
8432 // and we will determine it below.
8433 LayoutParams animLp = null;
8434 int bestAnimLayer = -1;
8435 boolean fullscreenAnim = false;
8436
8437 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8438 "New wallpaper target=" + mWallpaperTarget
Daniel Sandlerab886f52012-06-04 14:36:25 -04008439 + ", oldWallpaper=" + oldWallpaper
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008440 + ", lower target=" + mLowerWallpaperTarget
8441 + ", upper target=" + mUpperWallpaperTarget);
8442 int foundWallpapers = 0;
8443 // Do a first pass through the tokens for two
8444 // things:
8445 // (1) Determine if both the closing and opening
8446 // app token sets are wallpaper targets, in which
8447 // case special animations are needed
8448 // (since the wallpaper needs to stay static
8449 // behind them).
8450 // (2) Find the layout params of the top-most
8451 // application window in the tokens, which is
8452 // what will control the animation theme.
8453 final int NC = mClosingApps.size();
8454 NN = NC + mOpeningApps.size();
8455 for (i=0; i<NN; i++) {
8456 AppWindowToken wtoken;
8457 int mode;
8458 if (i < NC) {
8459 wtoken = mClosingApps.get(i);
8460 mode = 1;
8461 } else {
8462 wtoken = mOpeningApps.get(i-NC);
8463 mode = 2;
8464 }
8465 if (mLowerWallpaperTarget != null) {
8466 if (mLowerWallpaperTarget.mAppToken == wtoken
8467 || mUpperWallpaperTarget.mAppToken == wtoken) {
8468 foundWallpapers |= mode;
8469 }
8470 }
8471 if (wtoken.appFullscreen) {
8472 WindowState ws = wtoken.findMainWindow();
8473 if (ws != null) {
8474 animLp = ws.mAttrs;
8475 bestAnimLayer = ws.mLayer;
8476 fullscreenAnim = true;
8477 }
8478 } else if (!fullscreenAnim) {
8479 WindowState ws = wtoken.findMainWindow();
8480 if (ws != null) {
8481 if (ws.mLayer > bestAnimLayer) {
8482 animLp = ws.mAttrs;
8483 bestAnimLayer = ws.mLayer;
8484 }
8485 }
8486 }
8487 }
8488
8489 if (foundWallpapers == 3) {
8490 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8491 "Wallpaper animation!");
8492 switch (transit) {
8493 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
8494 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
8495 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
8496 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
8497 break;
8498 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
8499 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
8500 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
8501 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
8502 break;
8503 }
8504 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8505 "New transit: " + transit);
Daniel Sandlerab886f52012-06-04 14:36:25 -04008506 } else if ((oldWallpaper != null) && !mOpeningApps.contains(oldWallpaper.mAppToken)) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008507 // We are transitioning from an activity with
8508 // a wallpaper to one without.
8509 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
8510 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8511 "New transit away from wallpaper: " + transit);
Craig Mautner8863cca2012-09-18 15:04:34 -07008512 } else if (mWallpaperTarget != null && mWallpaperTarget.isVisibleLw()) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008513 // We are transitioning from an activity without
8514 // a wallpaper to now showing the wallpaper
8515 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
8516 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8517 "New transit into wallpaper: " + transit);
8518 }
8519
8520 // If all closing windows are obscured, then there is
8521 // no need to do an animation. This is the case, for
8522 // example, when this transition is being done behind
8523 // the lock screen.
8524 if (!mPolicy.allowAppAnimationsLw()) {
8525 animLp = null;
8526 }
8527
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008528 AppWindowToken topOpeningApp = null;
8529 int topOpeningLayer = 0;
8530
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008531 NN = mOpeningApps.size();
8532 for (i=0; i<NN; i++) {
8533 AppWindowToken wtoken = mOpeningApps.get(i);
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008534 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Craig Mautnerbec53f72012-04-05 11:49:05 -07008535 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008536 appAnimator.clearThumbnail();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008537 wtoken.reportedVisible = false;
8538 wtoken.inPendingTransaction = false;
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008539 appAnimator.animation = null;
Craig Mautnerbec53f72012-04-05 11:49:05 -07008540 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008541 wtoken.updateReportedVisibilityLocked();
8542 wtoken.waitingToShow = false;
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008543
8544 appAnimator.mAllAppWinAnimators.clear();
8545 final int N = wtoken.allAppWindows.size();
8546 for (int j = 0; j < N; j++) {
8547 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
8548 }
8549 mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
8550
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008551 if (animLp != null) {
8552 int layer = -1;
8553 for (int j=0; j<wtoken.windows.size(); j++) {
8554 WindowState win = wtoken.windows.get(j);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07008555 if (win.mWinAnimator.mAnimLayer > layer) {
8556 layer = win.mWinAnimator.mAnimLayer;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008557 }
8558 }
8559 if (topOpeningApp == null || layer > topOpeningLayer) {
8560 topOpeningApp = wtoken;
8561 topOpeningLayer = layer;
8562 }
8563 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008564 }
8565 NN = mClosingApps.size();
8566 for (i=0; i<NN; i++) {
8567 AppWindowToken wtoken = mClosingApps.get(i);
8568 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Craig Mautner8863cca2012-09-18 15:04:34 -07008569 "Now closing app " + wtoken);
Craig Mautner59431632012-04-04 11:56:44 -07008570 wtoken.mAppAnimator.clearThumbnail();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008571 wtoken.inPendingTransaction = false;
Craig Mautner59431632012-04-04 11:56:44 -07008572 wtoken.mAppAnimator.animation = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008573 setTokenVisibilityLocked(wtoken, animLp, false,
8574 transit, false);
8575 wtoken.updateReportedVisibilityLocked();
8576 wtoken.waitingToHide = false;
8577 // Force the allDrawn flag, because we want to start
8578 // this guy's animations regardless of whether it's
8579 // gotten drawn.
8580 wtoken.allDrawn = true;
8581 }
8582
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008583 if (mNextAppTransitionThumbnail != null && topOpeningApp != null
Craig Mautner59431632012-04-04 11:56:44 -07008584 && topOpeningApp.mAppAnimator.animation != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008585 // This thumbnail animation is very special, we need to have
8586 // an extra surface with the thumbnail included with the animation.
8587 Rect dirty = new Rect(0, 0, mNextAppTransitionThumbnail.getWidth(),
8588 mNextAppTransitionThumbnail.getHeight());
8589 try {
Jeff Browne215f262012-09-10 16:01:14 -07008590 // TODO(multi-display): support other displays
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008591 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07008592 final Display display = displayContent.getDisplay();
Jeff Brown64a55af2012-08-26 02:47:39 -07008593 Surface surface = new Surface(mFxSession,
8594 "thumbnail anim",
Craig Mautner6881a102012-07-27 13:04:51 -07008595 dirty.width(), dirty.height(),
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008596 PixelFormat.TRANSLUCENT, Surface.HIDDEN);
Jeff Browne215f262012-09-10 16:01:14 -07008597 surface.setLayerStack(display.getLayerStack());
Craig Mautner59431632012-04-04 11:56:44 -07008598 topOpeningApp.mAppAnimator.thumbnail = surface;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008599 if (SHOW_TRANSACTIONS) Slog.i(TAG, " THUMBNAIL "
8600 + surface + ": CREATE");
8601 Surface drawSurface = new Surface();
8602 drawSurface.copyFrom(surface);
8603 Canvas c = drawSurface.lockCanvas(dirty);
8604 c.drawBitmap(mNextAppTransitionThumbnail, 0, 0, null);
8605 drawSurface.unlockCanvasAndPost(c);
8606 drawSurface.release();
Craig Mautner59431632012-04-04 11:56:44 -07008607 topOpeningApp.mAppAnimator.thumbnailLayer = topOpeningLayer;
Michael Jurka21385cd2012-05-03 10:57:31 -07008608 Animation anim = createThumbnailAnimationLocked(
Michael Jurka832cb222012-04-13 09:32:47 -07008609 transit, true, true, mNextAppTransitionScaleUp);
Craig Mautner59431632012-04-04 11:56:44 -07008610 topOpeningApp.mAppAnimator.thumbnailAnimation = anim;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008611 anim.restrictDuration(MAX_ANIMATION_DURATION);
8612 anim.scaleCurrentDuration(mTransitionAnimationScale);
Craig Mautner59431632012-04-04 11:56:44 -07008613 topOpeningApp.mAppAnimator.thumbnailX = mNextAppTransitionStartX;
8614 topOpeningApp.mAppAnimator.thumbnailY = mNextAppTransitionStartY;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008615 } catch (Surface.OutOfResourcesException e) {
8616 Slog.e(TAG, "Can't allocate thumbnail surface w=" + dirty.width()
8617 + " h=" + dirty.height(), e);
Craig Mautner59431632012-04-04 11:56:44 -07008618 topOpeningApp.mAppAnimator.clearThumbnail();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008619 }
8620 }
8621
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07008622 mNextAppTransitionType = ActivityOptions.ANIM_NONE;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008623 mNextAppTransitionPackage = null;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008624 mNextAppTransitionThumbnail = null;
Dianne Hackborn84375872012-06-01 19:03:50 -07008625 scheduleAnimationCallback(mNextAppTransitionCallback);
8626 mNextAppTransitionCallback = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008627
8628 mOpeningApps.clear();
8629 mClosingApps.clear();
8630
8631 // This has changed the visibility of windows, so perform
8632 // a new layout to get them all up-to-date.
Craig Mautner39834192012-09-02 07:47:24 -07008633 changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008634 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008635 getDefaultDisplayContentLocked().layoutNeeded = true;
Craig Mautner59c00972012-07-30 12:10:24 -07008636
8637 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008638 if (windows == getDefaultWindowListLocked()
8639 && !moveInputMethodWindowsIfNeededLocked(true)) {
Craig Mautner59c00972012-07-30 12:10:24 -07008640 assignLayersLocked(windows);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008641 }
Craig Mautner59c00972012-07-30 12:10:24 -07008642 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, false /*updateInputWindows*/);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008643 mFocusMayChange = false;
8644 }
8645
8646 return changes;
8647 }
8648
8649 /**
8650 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008651 * @return bitmap indicating if another pass through layout must be made.
8652 */
Craig Mautner2f995a72012-02-21 09:53:21 -08008653 private int handleAnimatingStoppedAndTransitionLocked() {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008654 int changes = 0;
8655
8656 mAppTransitionRunning = false;
Craig Mautneref25d7a2012-05-15 23:01:47 -07008657 // Restore window app tokens to the ActivityManager views
Craig Mautner3f99fde2012-06-19 14:10:01 -07008658 for (int i = mAnimatingAppTokens.size() - 1; i >= 0; i--) {
8659 mAnimatingAppTokens.get(i).sendingToBottom = false;
8660 }
Craig Mautneref25d7a2012-05-15 23:01:47 -07008661 mAnimatingAppTokens.clear();
8662 mAnimatingAppTokens.addAll(mAppTokens);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008663 rebuildAppWindowListLocked();
Craig Mautneref25d7a2012-05-15 23:01:47 -07008664
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008665 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
8666 mInnerFields.mAdjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Craig Mautneref25d7a2012-05-15 23:01:47 -07008667 moveInputMethodWindowsIfNeededLocked(true);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008668 mInnerFields.mWallpaperMayChange = true;
8669 // Since the window list has been rebuilt, focus might
8670 // have to be recomputed since the actual order of windows
8671 // might have changed again.
8672 mFocusMayChange = true;
8673
8674 return changes;
8675 }
8676
8677 /**
8678 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
8679 *
8680 * @return bitmap indicating if another pass through layout must be made.
8681 */
8682 private int animateAwayWallpaperLocked() {
8683 int changes = 0;
8684 WindowState oldWallpaper = mWallpaperTarget;
8685 if (mLowerWallpaperTarget != null
8686 && mLowerWallpaperTarget.mAppToken != null) {
8687 if (DEBUG_WALLPAPER) Slog.v(TAG,
8688 "wallpaperForceHiding changed with lower="
8689 + mLowerWallpaperTarget);
8690 if (DEBUG_WALLPAPER) Slog.v(TAG,
8691 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
8692 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
8693 if (mLowerWallpaperTarget.mAppToken.hidden) {
8694 // The lower target has become hidden before we
8695 // actually started the animation... let's completely
8696 // re-evaluate everything.
8697 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
8698 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
8699 }
8700 }
8701 mInnerFields.mAdjResult |= adjustWallpaperWindowsLocked();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008702 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
8703 + " NEW: " + mWallpaperTarget
8704 + " LOWER: " + mLowerWallpaperTarget);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008705 return changes;
8706 }
8707
Craig Mautnere32c3072012-03-12 15:25:35 -07008708 private void updateResizingWindows(final WindowState w) {
Craig Mautnera608b882012-03-30 13:03:49 -07008709 final WindowStateAnimator winAnimator = w.mWinAnimator;
Craig Mautner1efacf72012-04-27 12:58:21 -07008710 if (w.mHasSurface && !w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
Craig Mautnere32c3072012-03-12 15:25:35 -07008711 w.mContentInsetsChanged |=
Dianne Hackborn5c58de32012-04-28 19:52:37 -07008712 !w.mLastContentInsets.equals(w.mContentInsets);
Craig Mautnere32c3072012-03-12 15:25:35 -07008713 w.mVisibleInsetsChanged |=
Dianne Hackborn5c58de32012-04-28 19:52:37 -07008714 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Craig Mautner812d2ca2012-09-27 15:35:34 -07008715 boolean configChanged = w.isConfigChanged();
Craig Mautnere32c3072012-03-12 15:25:35 -07008716 if (DEBUG_CONFIGURATION && configChanged) {
8717 Slog.v(TAG, "Win " + w + " config changed: "
8718 + mCurConfiguration);
8719 }
8720 if (localLOGV) Slog.v(TAG, "Resizing " + w
8721 + ": configChanged=" + configChanged
8722 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
8723 w.mLastFrame.set(w.mFrame);
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07008724 if (w.mContentInsetsChanged
Craig Mautnere32c3072012-03-12 15:25:35 -07008725 || w.mVisibleInsetsChanged
Craig Mautnera608b882012-03-30 13:03:49 -07008726 || winAnimator.mSurfaceResized
Craig Mautnere32c3072012-03-12 15:25:35 -07008727 || configChanged) {
8728 if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
8729 Slog.v(TAG, "Resize reasons: "
8730 + " contentInsetsChanged=" + w.mContentInsetsChanged
8731 + " visibleInsetsChanged=" + w.mVisibleInsetsChanged
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008732 + " surfaceResized=" + winAnimator.mSurfaceResized
Craig Mautnere32c3072012-03-12 15:25:35 -07008733 + " configChanged=" + configChanged);
8734 }
8735
8736 w.mLastContentInsets.set(w.mContentInsets);
8737 w.mLastVisibleInsets.set(w.mVisibleInsets);
8738 makeWindowFreezingScreenIfNeededLocked(w);
8739 // If the orientation is changing, then we need to
8740 // hold off on unfreezing the display until this
8741 // window has been redrawn; to do that, we need
8742 // to go through the process of getting informed
8743 // by the application when it has finished drawing.
8744 if (w.mOrientationChanging) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07008745 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautner83339b42012-05-01 22:13:23 -07008746 "Orientation start waiting for draw mDrawState=DRAW_PENDING in "
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008747 + w + ", surface " + winAnimator.mSurface);
Craig Mautner749a7bb2012-04-02 13:49:53 -07008748 winAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
Craig Mautnere32c3072012-03-12 15:25:35 -07008749 if (w.mAppToken != null) {
8750 w.mAppToken.allDrawn = false;
8751 }
8752 }
8753 if (!mResizingWindows.contains(w)) {
8754 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008755 "Resizing window " + w + " to " + winAnimator.mSurfaceW
8756 + "x" + winAnimator.mSurfaceH);
Craig Mautnere32c3072012-03-12 15:25:35 -07008757 mResizingWindows.add(w);
8758 }
8759 } else if (w.mOrientationChanging) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07008760 if (w.isDrawnLw()) {
Craig Mautnere32c3072012-03-12 15:25:35 -07008761 if (DEBUG_ORIENTATION) Slog.v(TAG,
8762 "Orientation not waiting for draw in "
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008763 + w + ", surface " + winAnimator.mSurface);
Craig Mautnere32c3072012-03-12 15:25:35 -07008764 w.mOrientationChanging = false;
8765 }
8766 }
8767 }
8768 }
8769
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008770 /**
8771 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
8772 *
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008773 * @param w WindowState this method is applied to.
8774 * @param currentTime The time which animations use for calculating transitions.
8775 * @param innerDw Width of app window.
8776 * @param innerDh Height of app window.
8777 */
8778 private void handleNotObscuredLocked(final WindowState w, final long currentTime,
8779 final int innerDw, final int innerDh) {
8780 final WindowManager.LayoutParams attrs = w.mAttrs;
8781 final int attrFlags = attrs.flags;
8782 final boolean canBeSeen = w.isDisplayedLw();
8783
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07008784 if (w.mHasSurface) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008785 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
8786 mInnerFields.mHoldScreen = w.mSession;
8787 }
8788 if (!mInnerFields.mSyswin && w.mAttrs.screenBrightness >= 0
8789 && mInnerFields.mScreenBrightness < 0) {
8790 mInnerFields.mScreenBrightness = w.mAttrs.screenBrightness;
8791 }
8792 if (!mInnerFields.mSyswin && w.mAttrs.buttonBrightness >= 0
8793 && mInnerFields.mButtonBrightness < 0) {
8794 mInnerFields.mButtonBrightness = w.mAttrs.buttonBrightness;
8795 }
Jeff Brown1e3b98d2012-09-30 18:58:59 -07008796 if (!mInnerFields.mSyswin && w.mAttrs.userActivityTimeout >= 0
8797 && mInnerFields.mUserActivityTimeout < 0) {
8798 mInnerFields.mUserActivityTimeout = w.mAttrs.userActivityTimeout;
8799 }
8800
Craig Mautner65d11b32012-10-01 13:59:52 -07008801 final int type = attrs.type;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008802 if (canBeSeen
Craig Mautner65d11b32012-10-01 13:59:52 -07008803 && (type == TYPE_SYSTEM_DIALOG
Craig Mautner88400d32012-09-30 12:35:45 -07008804 || type == TYPE_RECENTS_OVERLAY
Craig Mautner65d11b32012-10-01 13:59:52 -07008805 || type == TYPE_KEYGUARD
8806 || type == TYPE_SYSTEM_ERROR)) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008807 mInnerFields.mSyswin = true;
8808 }
Craig Mautner65d11b32012-10-01 13:59:52 -07008809
8810 if (canBeSeen) {
8811 if (type == TYPE_DREAM || type == TYPE_KEYGUARD) {
8812 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_MIRROR;
8813 } else if (mInnerFields.mDisplayHasContent
8814 == LayoutFields.DISPLAY_CONTENT_UNKNOWN) {
8815 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNIQUE;
8816 }
8817 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008818 }
8819
8820 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
8821 if (opaqueDrawn && w.isFullscreen(innerDw, innerDh)) {
8822 // This window completely covers everything behind it,
Craig Mautner2fb98b12012-03-20 17:24:00 -07008823 // so we want to leave all of them as undimmed (for
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008824 // performance reasons).
8825 mInnerFields.mObscured = true;
Craig Mautner35af2ff2012-04-24 14:30:15 -07008826 } else if (canBeSeen && (attrFlags & FLAG_DIM_BEHIND) != 0
Craig Mautner236a35b2012-06-08 09:54:59 -07008827 && !(w.mAppToken != null && w.mAppToken.hiddenRequested)
8828 && !w.mExiting) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07008829 if (localLOGV) Slog.v(TAG, "Win " + w + " obscured=" + mInnerFields.mObscured);
8830 if (!mInnerFields.mDimming) {
8831 //Slog.i(TAG, "DIM BEHIND: " + w);
8832 mInnerFields.mDimming = true;
Craig Mautneracafd192012-05-10 10:41:02 -07008833 final WindowStateAnimator winAnimator = w.mWinAnimator;
Craig Mautnera91f9e22012-09-14 16:22:08 -07008834 if (!mAnimator.isDimmingLocked(winAnimator)) {
Craig Mautnerf8d4fbb2012-04-11 09:25:53 -07008835 final int width, height;
Craig Mautner65d11b32012-10-01 13:59:52 -07008836 if (attrs.type == TYPE_BOOT_PROGRESS) {
Craig Mautner59c00972012-07-30 12:10:24 -07008837 final DisplayInfo displayInfo = w.mDisplayContent.getDisplayInfo();
8838 width = displayInfo.logicalWidth;
8839 height = displayInfo.logicalHeight;
Craig Mautnerf8d4fbb2012-04-11 09:25:53 -07008840 } else {
8841 width = innerDw;
8842 height = innerDh;
8843 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07008844 startDimmingLocked(
8845 winAnimator, w.mExiting ? 0 : w.mAttrs.dimAmount, width, height);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008846 }
8847 }
8848 }
8849 }
8850
Craig Mautner6fbda632012-07-03 09:26:39 -07008851 private void updateAllDrawnLocked() {
8852 // See if any windows have been drawn, so they (and others
8853 // associated with them) can now be shown.
8854 final ArrayList<AppWindowToken> appTokens = mAnimatingAppTokens;
8855 final int NT = appTokens.size();
8856 for (int i=0; i<NT; i++) {
8857 AppWindowToken wtoken = appTokens.get(i);
8858 if (!wtoken.allDrawn) {
8859 int numInteresting = wtoken.numInterestingWindows;
8860 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
8861 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
8862 "allDrawn: " + wtoken
8863 + " interesting=" + numInteresting
8864 + " drawn=" + wtoken.numDrawnWindows);
8865 wtoken.allDrawn = true;
8866 }
8867 }
8868 }
8869 }
8870
Brad Fitzpatrick68044332010-11-22 18:19:48 -08008871 // "Something has changed! Let's make it correct now."
Craig Mautner76a71652012-09-03 23:23:58 -07008872 private final void performLayoutAndPlaceSurfacesLockedInner(boolean recoveringMemory) {
Craig Mautner7d8df392012-04-06 15:26:23 -07008873 if (DEBUG_WINDOW_TRACE) {
Craig Mautner3255a282012-04-16 15:42:47 -07008874 Slog.v(TAG, "performLayoutAndPlaceSurfacesLockedInner: entry. Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -07008875 + Debug.getCallers(3));
Craig Mautner7d8df392012-04-06 15:26:23 -07008876 }
Joe Onorato34bcebc2010-07-07 18:05:01 -04008877
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008878 final long currentTime = SystemClock.uptimeMillis();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008879
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008880 int i;
8881
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008882 if (mFocusMayChange) {
8883 mFocusMayChange = false;
Jeff Brown3a22cd92011-01-21 13:59:04 -08008884 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
8885 false /*updateInputWindows*/);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008886 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008887
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008888 // Initialize state of exiting tokens.
8889 for (i=mExitingTokens.size()-1; i>=0; i--) {
8890 mExitingTokens.get(i).hasVisible = false;
8891 }
8892
8893 // Initialize state of exiting applications.
8894 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
8895 mExitingAppTokens.get(i).hasVisible = false;
8896 }
8897
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008898 mInnerFields.mHoldScreen = null;
8899 mInnerFields.mScreenBrightness = -1;
8900 mInnerFields.mButtonBrightness = -1;
Jeff Brown1e3b98d2012-09-30 18:58:59 -07008901 mInnerFields.mUserActivityTimeout = -1;
Craig Mautner65d11b32012-10-01 13:59:52 -07008902 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNKNOWN;
Jeff Brown1e3b98d2012-09-30 18:58:59 -07008903
Craig Mautner6fbda632012-07-03 09:26:39 -07008904 mTransactionSequence++;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07008905
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008906 final DisplayContent defaultDisplay = getDefaultDisplayContentLocked();
Craig Mautner76a71652012-09-03 23:23:58 -07008907 final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
8908 final int defaultDw = defaultInfo.logicalWidth;
8909 final int defaultDh = defaultInfo.logicalHeight;
Craig Mautner76a71652012-09-03 23:23:58 -07008910
Dianne Hackborn36991742011-10-11 21:35:26 -07008911 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
8912 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008913 Surface.openTransaction();
8914 try {
Craig Mautner76a71652012-09-03 23:23:58 -07008915
Jeff Brown4ed8fe72012-08-30 18:18:29 -07008916 if (mWatermark != null) {
Craig Mautner76a71652012-09-03 23:23:58 -07008917 mWatermark.positionSurface(defaultDw, defaultDh);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07008918 }
8919 if (mStrictModeFlash != null) {
Craig Mautner76a71652012-09-03 23:23:58 -07008920 mStrictModeFlash.positionSurface(defaultDw, defaultDh);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07008921 }
8922
Craig Mautner7358fbf2012-04-12 21:06:33 -07008923 boolean focusDisplayed = false;
Craig Mautner6fbda632012-07-03 09:26:39 -07008924 boolean updateAllDrawn = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008925
Craig Mautner76a71652012-09-03 23:23:58 -07008926 DisplayContentsIterator iterator = new DisplayContentsIterator();
8927 while (iterator.hasNext()) {
8928 final DisplayContent displayContent = iterator.next();
8929 WindowList windows = displayContent.getWindowList();
8930 DisplayInfo displayInfo = displayContent.getDisplayInfo();
Craig Mautner19d59bc2012-09-04 11:15:56 -07008931 final int displayId = displayContent.getDisplayId();
Craig Mautner76a71652012-09-03 23:23:58 -07008932 final int dw = displayInfo.logicalWidth;
8933 final int dh = displayInfo.logicalHeight;
8934 final int innerDw = displayInfo.appWidth;
8935 final int innerDh = displayInfo.appHeight;
Craig Mautner19d59bc2012-09-04 11:15:56 -07008936 final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008937
Craig Mautner65d11b32012-10-01 13:59:52 -07008938 // Reset for each display unless we are forcing mirroring.
8939 if (mInnerFields.mDisplayHasContent != LayoutFields.DISPLAY_CONTENT_MIRROR) {
8940 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNKNOWN;
8941 }
8942
Craig Mautner76a71652012-09-03 23:23:58 -07008943 int repeats = 0;
8944 do {
8945 repeats++;
8946 if (repeats > 6) {
8947 Slog.w(TAG, "Animation repeat aborted after too many iterations");
Craig Mautner76a71652012-09-03 23:23:58 -07008948 displayContent.layoutNeeded = false;
8949 break;
Craig Mautner5702d4d2012-06-30 14:10:16 -07008950 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008951
Craig Mautner76a71652012-09-03 23:23:58 -07008952 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("On entry to LockedInner",
8953 displayContent.pendingLayoutChanges);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008954
Craig Mautner76a71652012-09-03 23:23:58 -07008955 if (isDefaultDisplay && ((displayContent.pendingLayoutChanges
8956 & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0)
8957 && ((adjustWallpaperWindowsLocked()
8958 & ADJUST_WALLPAPER_LAYERS_CHANGED) != 0)) {
8959 assignLayersLocked(windows);
Craig Mautner76a71652012-09-03 23:23:58 -07008960 displayContent.layoutNeeded = true;
8961 }
8962
8963 if (isDefaultDisplay && (displayContent.pendingLayoutChanges
8964 & WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
8965 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
8966 if (updateOrientationFromAppTokensLocked(true)) {
Craig Mautner76a71652012-09-03 23:23:58 -07008967 displayContent.layoutNeeded = true;
8968 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008969 }
8970 }
8971
Craig Mautner76a71652012-09-03 23:23:58 -07008972 if ((displayContent.pendingLayoutChanges
8973 & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
Craig Mautner76a71652012-09-03 23:23:58 -07008974 displayContent.layoutNeeded = true;
Craig Mautner6fbda632012-07-03 09:26:39 -07008975 }
Craig Mautner76a71652012-09-03 23:23:58 -07008976
8977 // FIRST LOOP: Perform a layout, if needed.
8978 if (repeats < 4) {
8979 performLayoutLockedInner(displayContent, repeats == 1,
8980 false /*updateInputWindows*/);
8981 } else {
8982 Slog.w(TAG, "Layout repeat skipped after too many iterations");
8983 }
8984
8985 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
8986 // it is animating.
8987 displayContent.pendingLayoutChanges = 0;
8988
8989 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("loop number "
8990 + mLayoutRepeatCount, displayContent.pendingLayoutChanges);
8991
Craig Mautner69b08182012-09-05 13:07:13 -07008992 if (isDefaultDisplay) {
8993 mPolicy.beginPostLayoutPolicyLw(dw, dh);
8994 for (i = windows.size() - 1; i >= 0; i--) {
8995 WindowState w = windows.get(i);
8996 if (w.mHasSurface) {
8997 mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs);
8998 }
Craig Mautner6fbda632012-07-03 09:26:39 -07008999 }
Craig Mautner69b08182012-09-05 13:07:13 -07009000 displayContent.pendingLayoutChanges |= mPolicy.finishPostLayoutPolicyLw();
9001 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
9002 "after finishPostLayoutPolicyLw", displayContent.pendingLayoutChanges);
Craig Mautner76a71652012-09-03 23:23:58 -07009003 }
Craig Mautner76a71652012-09-03 23:23:58 -07009004 } while (displayContent.pendingLayoutChanges != 0);
9005
9006 mInnerFields.mObscured = false;
9007 mInnerFields.mDimming = false;
9008 mInnerFields.mSyswin = false;
9009
9010 // Only used if default window
9011 final boolean someoneLosingFocus = !mLosingFocus.isEmpty();
9012
9013 final int N = windows.size();
9014 for (i=N-1; i>=0; i--) {
9015 WindowState w = windows.get(i);
9016
9017 final boolean obscuredChanged = w.mObscured != mInnerFields.mObscured;
9018
9019 // Update effect.
9020 w.mObscured = mInnerFields.mObscured;
9021 if (!mInnerFields.mObscured) {
9022 handleNotObscuredLocked(w, currentTime, innerDw, innerDh);
9023 }
9024
9025 if (isDefaultDisplay && obscuredChanged && (mWallpaperTarget == w)
9026 && w.isVisibleLw()) {
9027 // This is the wallpaper target and its obscured state
9028 // changed... make sure the current wallaper's visibility
9029 // has been updated accordingly.
9030 updateWallpaperVisibilityLocked();
9031 }
9032
9033 final WindowStateAnimator winAnimator = w.mWinAnimator;
9034
9035 // If the window has moved due to its containing
9036 // content frame changing, then we'd like to animate
9037 // it.
9038 if (w.mHasSurface && w.shouldAnimateMove()) {
9039 // Frame has moved, containing content frame
9040 // has also moved, and we're not currently animating...
9041 // let's do something.
9042 Animation a = AnimationUtils.loadAnimation(mContext,
9043 com.android.internal.R.anim.window_move_from_decor);
9044 winAnimator.setAnimation(a);
9045 winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
9046 winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
9047 try {
9048 w.mClient.moved(w.mFrame.left, w.mFrame.top);
9049 } catch (RemoteException e) {
9050 }
9051 }
9052
9053 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
9054 w.mContentChanged = false;
9055
9056 // Moved from updateWindowsAndWallpaperLocked().
9057 if (w.mHasSurface) {
9058 // Take care of the window being ready to display.
Craig Mautner69b08182012-09-05 13:07:13 -07009059 final boolean committed =
9060 winAnimator.commitFinishDrawingLocked(currentTime);
9061 if (isDefaultDisplay && committed) {
Craig Mautner65d11b32012-10-01 13:59:52 -07009062 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
9063 if (DEBUG_WALLPAPER) Slog.v(TAG,
Craig Mautner76a71652012-09-03 23:23:58 -07009064 "First draw done in potential wallpaper target " + w);
9065 mInnerFields.mWallpaperMayChange = true;
9066 displayContent.pendingLayoutChanges |=
9067 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
9068 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
9069 debugLayoutRepeats(
9070 "wallpaper and commitFinishDrawingLocked true",
9071 displayContent.pendingLayoutChanges);
Craig Mautner6fbda632012-07-03 09:26:39 -07009072 }
9073 }
Craig Mautner76a71652012-09-03 23:23:58 -07009074 }
9075
Craig Mautnera91f9e22012-09-14 16:22:08 -07009076 winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
Craig Mautner76a71652012-09-03 23:23:58 -07009077
9078 final AppWindowToken atoken = w.mAppToken;
Craig Mautner65d11b32012-10-01 13:59:52 -07009079 if (DEBUG_STARTING_WINDOW && atoken != null
9080 && w == atoken.startingWindow) {
Craig Mautner76a71652012-09-03 23:23:58 -07009081 Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen="
9082 + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
9083 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
9084 }
9085 if (atoken != null
9086 && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
9087 if (atoken.lastTransactionSequence != mTransactionSequence) {
9088 atoken.lastTransactionSequence = mTransactionSequence;
9089 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
9090 atoken.startingDisplayed = false;
9091 }
Craig Mautner65d11b32012-10-01 13:59:52 -07009092 if ((w.isOnScreen() || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
Craig Mautner76a71652012-09-03 23:23:58 -07009093 && !w.mExiting && !w.mDestroying) {
9094 if (WindowManagerService.DEBUG_VISIBILITY ||
9095 WindowManagerService.DEBUG_ORIENTATION) {
9096 Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
9097 + ", isAnimating=" + winAnimator.isAnimating());
9098 if (!w.isDrawnLw()) {
9099 Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurface
9100 + " pv=" + w.mPolicyVisibility
9101 + " mDrawState=" + winAnimator.mDrawState
9102 + " ah=" + w.mAttachedHidden
9103 + " th=" + atoken.hiddenRequested
9104 + " a=" + winAnimator.mAnimating);
Craig Mautner6fbda632012-07-03 09:26:39 -07009105 }
9106 }
Craig Mautner76a71652012-09-03 23:23:58 -07009107 if (w != atoken.startingWindow) {
9108 if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
9109 atoken.numInterestingWindows++;
9110 if (w.isDrawnLw()) {
9111 atoken.numDrawnWindows++;
9112 if (WindowManagerService.DEBUG_VISIBILITY ||
9113 WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
9114 "tokenMayBeDrawn: " + atoken
9115 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen
9116 + " mAppFreezing=" + w.mAppFreezing);
9117 updateAllDrawn = true;
9118 }
9119 }
9120 } else if (w.isDrawnLw()) {
9121 atoken.startingDisplayed = true;
9122 }
Craig Mautner6fbda632012-07-03 09:26:39 -07009123 }
9124 }
9125 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009126
Craig Mautner76a71652012-09-03 23:23:58 -07009127 if (isDefaultDisplay && someoneLosingFocus && (w == mCurrentFocus)
9128 && w.isDisplayedLw()) {
9129 focusDisplayed = true;
9130 }
Craig Mautner51bb12b2012-04-27 14:39:53 -07009131
Craig Mautner76a71652012-09-03 23:23:58 -07009132 updateResizingWindows(w);
9133 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07009134
Craig Mautner65d11b32012-10-01 13:59:52 -07009135 final boolean hasUniqueContent;
9136 switch (mInnerFields.mDisplayHasContent) {
9137 case LayoutFields.DISPLAY_CONTENT_MIRROR:
9138 hasUniqueContent = isDefaultDisplay;
9139 break;
9140 case LayoutFields.DISPLAY_CONTENT_UNIQUE:
9141 hasUniqueContent = true;
9142 break;
9143 case LayoutFields.DISPLAY_CONTENT_UNKNOWN:
9144 default:
9145 hasUniqueContent = false;
9146 break;
9147 }
9148 mDisplayManagerService.setDisplayHasContent(displayId, hasUniqueContent,
9149 true /* inTraversal, must call performTraversalInTrans... below */);
9150
Craig Mautnera91f9e22012-09-14 16:22:08 -07009151 if (!mInnerFields.mDimming && mAnimator.isDimmingLocked(displayId)) {
9152 stopDimmingLocked(displayId);
9153 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009154 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009155
Craig Mautner6fbda632012-07-03 09:26:39 -07009156 if (updateAllDrawn) {
9157 updateAllDrawnLocked();
9158 }
9159
Craig Mautner7358fbf2012-04-12 21:06:33 -07009160 if (focusDisplayed) {
9161 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
9162 }
Craig Mautner65d11b32012-10-01 13:59:52 -07009163
9164 // Give the display manager a chance to adjust properties
9165 // like display rotation if it needs to.
9166 mDisplayManagerService.performTraversalInTransactionFromWindowManager();
9167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009168 } catch (RuntimeException e) {
Dianne Hackborn89620282011-09-11 12:47:45 -07009169 Log.wtf(TAG, "Unhandled exception in Window Manager", e);
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07009170 } finally {
9171 Surface.closeTransaction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009172 }
9173
Craig Mautner76a71652012-09-03 23:23:58 -07009174 final WindowList defaultWindows = defaultDisplay.getWindowList();
9175
Craig Mautner764983d2012-03-22 11:37:36 -07009176 // If we are ready to perform an app transition, check through
9177 // all of the app tokens to be shown and see if they are ready
9178 // to go.
9179 if (mAppTransitionReady) {
Craig Mautner76a71652012-09-03 23:23:58 -07009180 defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009181 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAppTransitionReadyLocked",
Craig Mautner76a71652012-09-03 23:23:58 -07009182 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009183 }
9184
9185 mInnerFields.mAdjResult = 0;
9186
9187 if (!mAnimator.mAnimating && mAppTransitionRunning) {
9188 // We have finished the animation of an app transition. To do
9189 // this, we have delayed a lot of operations like showing and
9190 // hiding apps, moving apps in Z-order, etc. The app token list
9191 // reflects the correct Z-order, but the window list may now
9192 // be out of sync with it. So here we will just rebuild the
9193 // entire app window list. Fun!
Craig Mautner76a71652012-09-03 23:23:58 -07009194 defaultDisplay.pendingLayoutChanges |= handleAnimatingStoppedAndTransitionLocked();
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009195 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAnimStopAndXitionLock",
Craig Mautner76a71652012-09-03 23:23:58 -07009196 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009197 }
9198
Craig Mautner76a71652012-09-03 23:23:58 -07009199 if (mInnerFields.mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
9200 && !mAppTransitionReady) {
Craig Mautner764983d2012-03-22 11:37:36 -07009201 // At this point, there was a window with a wallpaper that
9202 // was force hiding other windows behind it, but now it
9203 // is going away. This may be simple -- just animate
9204 // away the wallpaper and its window -- or it may be
9205 // hard -- the wallpaper now needs to be shown behind
9206 // something that was hidden.
Craig Mautner76a71652012-09-03 23:23:58 -07009207 defaultDisplay.pendingLayoutChanges |= animateAwayWallpaperLocked();
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009208 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animateAwayWallpaperLocked",
Craig Mautner76a71652012-09-03 23:23:58 -07009209 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009210 }
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009211 mInnerFields.mWallpaperForceHidingChanged = false;
Craig Mautner764983d2012-03-22 11:37:36 -07009212
Craig Mautnere7ae2502012-03-26 17:11:19 -07009213 if (mInnerFields.mWallpaperMayChange) {
9214 if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG,
9215 "Wallpaper may change! Adjusting");
9216 mInnerFields.mAdjResult |= adjustWallpaperWindowsLocked();
9217 }
9218
9219 if ((mInnerFields.mAdjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
9220 if (DEBUG_WALLPAPER) Slog.v(TAG,
9221 "Wallpaper layer changed: assigning layers + relayout");
Craig Mautner76a71652012-09-03 23:23:58 -07009222 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
9223 assignLayersLocked(defaultWindows);
Craig Mautnere7ae2502012-03-26 17:11:19 -07009224 } else if ((mInnerFields.mAdjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
9225 if (DEBUG_WALLPAPER) Slog.v(TAG,
9226 "Wallpaper visibility changed: relayout");
Craig Mautner76a71652012-09-03 23:23:58 -07009227 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
Craig Mautnere7ae2502012-03-26 17:11:19 -07009228 }
9229
9230 if (mFocusMayChange) {
9231 mFocusMayChange = false;
9232 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
9233 false /*updateInputWindows*/)) {
Craig Mautner76a71652012-09-03 23:23:58 -07009234 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
Craig Mautnere7ae2502012-03-26 17:11:19 -07009235 mInnerFields.mAdjResult = 0;
9236 }
9237 }
Craig Mautner764983d2012-03-22 11:37:36 -07009238
Craig Mautner19d59bc2012-09-04 11:15:56 -07009239 if (needsLayout()) {
Craig Mautner76a71652012-09-03 23:23:58 -07009240 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
9241 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
9242 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009243 }
9244
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009245 if (!mResizingWindows.isEmpty()) {
9246 for (i = mResizingWindows.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009247 WindowState win = mResizingWindows.get(i);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009248 final WindowStateAnimator winAnimator = win.mWinAnimator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009249 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -08009250 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07009251 "Reporting new frame to " + win + ": " + win.mCompatFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -07009252 int diff = 0;
Craig Mautner812d2ca2012-09-27 15:35:34 -07009253 boolean configChanged = win.isConfigChanged();
Craig Mautnerc36c49e2012-09-29 16:02:43 -07009254 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION
9255 // TODO: Remove once b/7094175 is fixed
9256 || ((String)win.mAttrs.getTitle()).contains("Keyguard"))
Dianne Hackborn694f79b2010-03-17 19:44:59 -07009257 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009258 Slog.i(TAG, "Sending new config to window " + win + ": "
Craig Mautnera608b882012-03-30 13:03:49 -07009259 + winAnimator.mSurfaceW + "x" + winAnimator.mSurfaceH
Dianne Hackborn694f79b2010-03-17 19:44:59 -07009260 + " / " + mCurConfiguration + " / 0x"
9261 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009262 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07009263 win.mConfiguration = mCurConfiguration;
Craig Mautner749a7bb2012-04-02 13:49:53 -07009264 if (DEBUG_ORIENTATION &&
9265 winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) Slog.i(
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009266 TAG, "Resizing " + win + " WITH DRAW PENDING");
Svetoslav Ganov758143e2012-08-06 16:40:27 -07009267 win.mClient.resized(win.mFrame, win.mLastContentInsets, win.mLastVisibleInsets,
Craig Mautner749a7bb2012-04-02 13:49:53 -07009268 winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING,
9269 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009270 win.mContentInsetsChanged = false;
9271 win.mVisibleInsetsChanged = false;
Craig Mautnera608b882012-03-30 13:03:49 -07009272 winAnimator.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009273 } catch (RemoteException e) {
9274 win.mOrientationChanging = false;
9275 }
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009276 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009277 mResizingWindows.clear();
9278 }
Romain Guy06882f82009-06-10 13:36:04 -07009279
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009280 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
9281 "With display frozen, orientationChangeComplete="
9282 + mInnerFields.mOrientationChangeComplete);
9283 if (mInnerFields.mOrientationChangeComplete) {
9284 if (mWindowsFreezingScreen) {
9285 mWindowsFreezingScreen = false;
9286 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
9287 }
9288 stopFreezingDisplayLocked();
9289 }
9290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009291 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009292 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009293 i = mDestroySurface.size();
9294 if (i > 0) {
9295 do {
9296 i--;
9297 WindowState win = mDestroySurface.get(i);
9298 win.mDestroying = false;
9299 if (mInputMethodWindow == win) {
9300 mInputMethodWindow = null;
9301 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009302 if (win == mWallpaperTarget) {
9303 wallpaperDestroyed = true;
9304 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009305 win.mWinAnimator.destroySurfaceLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009306 } while (i > 0);
9307 mDestroySurface.clear();
9308 }
9309
9310 // Time to remove any exiting tokens?
9311 for (i=mExitingTokens.size()-1; i>=0; i--) {
9312 WindowToken token = mExitingTokens.get(i);
9313 if (!token.hasVisible) {
9314 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07009315 if (token.windowType == TYPE_WALLPAPER) {
9316 mWallpaperTokens.remove(token);
Craig Mautner918b53b2012-07-09 14:15:54 -07009317 updateLayoutToAnimWallpaperTokens();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07009318 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009319 }
9320 }
9321
9322 // Time to remove any exiting applications?
9323 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
9324 AppWindowToken token = mExitingAppTokens.get(i);
9325 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009326 // Make sure there is no animation running on this token,
9327 // so any windows associated with it will be removed as
9328 // soon as their animations are complete
Craig Mautner59431632012-04-04 11:56:44 -07009329 token.mAppAnimator.clearAnimation();
9330 token.mAppAnimator.animating = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009331 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
9332 "performLayout: App token exiting now removed" + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009333 mAppTokens.remove(token);
Craig Mautneref25d7a2012-05-15 23:01:47 -07009334 mAnimatingAppTokens.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009335 mExitingAppTokens.remove(i);
9336 }
9337 }
9338
Dianne Hackborn12d3a942012-04-27 14:16:30 -07009339 if (!mAnimator.mAnimating && mRelayoutWhileAnimating.size() > 0) {
9340 for (int j=mRelayoutWhileAnimating.size()-1; j>=0; j--) {
9341 try {
9342 mRelayoutWhileAnimating.get(j).mClient.doneAnimating();
9343 } catch (RemoteException e) {
9344 }
9345 }
9346 mRelayoutWhileAnimating.clear();
9347 }
9348
Craig Mautner19d59bc2012-09-04 11:15:56 -07009349 if (wallpaperDestroyed && (adjustWallpaperWindowsLocked() != 0)) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07009350 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009351 }
Craig Mautner76a71652012-09-03 23:23:58 -07009352
9353 DisplayContentsIterator iterator = new DisplayContentsIterator();
9354 while (iterator.hasNext()) {
9355 DisplayContent displayContent = iterator.next();
9356 if (displayContent.pendingLayoutChanges != 0) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009357 displayContent.layoutNeeded = true;
Craig Mautner76a71652012-09-03 23:23:58 -07009358 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009359 }
Jeff Browneb857f12010-07-16 10:06:33 -07009360
Jeff Brown3a22cd92011-01-21 13:59:04 -08009361 // Finally update all input windows now that the window changes have stabilized.
Jeff Brown2e44b072011-01-24 15:21:56 -08009362 mInputMonitor.updateInputWindowsLw(true /*force*/);
Jeff Browneb857f12010-07-16 10:06:33 -07009363
Craig Mautner259328c2012-08-21 19:30:58 -07009364 setHoldScreenLocked(mInnerFields.mHoldScreen);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009365 if (!mDisplayFrozen) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009366 if (mInnerFields.mScreenBrightness < 0 || mInnerFields.mScreenBrightness > 1.0f) {
Jeff Brown96307042012-07-27 15:51:34 -07009367 mPowerManager.setScreenBrightnessOverrideFromWindowManager(-1);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009368 } else {
Jeff Brown96307042012-07-27 15:51:34 -07009369 mPowerManager.setScreenBrightnessOverrideFromWindowManager(
9370 toBrightnessOverride(mInnerFields.mScreenBrightness));
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009371 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009372 if (mInnerFields.mButtonBrightness < 0 || mInnerFields.mButtonBrightness > 1.0f) {
Jeff Brown96307042012-07-27 15:51:34 -07009373 mPowerManager.setButtonBrightnessOverrideFromWindowManager(-1);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009374 } else {
Jeff Brown96307042012-07-27 15:51:34 -07009375 mPowerManager.setButtonBrightnessOverrideFromWindowManager(
9376 toBrightnessOverride(mInnerFields.mButtonBrightness));
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009377 }
Jeff Brown1e3b98d2012-09-30 18:58:59 -07009378 mPowerManager.setUserActivityTimeoutOverrideFromWindowManager(
9379 mInnerFields.mUserActivityTimeout);
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009380 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009381
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009382 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009383 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Jeff Brown96307042012-07-27 15:51:34 -07009384 mPowerManager.wakeUp(SystemClock.uptimeMillis());
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009385 mTurnOnScreen = false;
9386 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009387
Craig Mautnera608b882012-03-30 13:03:49 -07009388 if (mInnerFields.mUpdateRotation) {
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009389 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009390 if (updateRotationUncheckedLocked(false)) {
Dianne Hackborn3e4f9d02011-02-04 14:05:55 -08009391 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07009392 } else {
Craig Mautnera608b882012-03-30 13:03:49 -07009393 mInnerFields.mUpdateRotation = false;
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009394 }
9395 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009396
Craig Mautner19d59bc2012-09-04 11:15:56 -07009397 if (mInnerFields.mOrientationChangeComplete && !defaultDisplay.layoutNeeded
9398 && !mInnerFields.mUpdateRotation) {
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07009399 checkDrawnWindowsLocked();
9400 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009401
Craig Mautner76a71652012-09-03 23:23:58 -07009402 final int N = mPendingRemove.size();
9403 if (N > 0) {
9404 if (mPendingRemoveTmp.length < N) {
9405 mPendingRemoveTmp = new WindowState[N+10];
9406 }
9407 mPendingRemove.toArray(mPendingRemoveTmp);
9408 mPendingRemove.clear();
9409 DisplayContentList displayList = new DisplayContentList();
9410 for (i = 0; i < N; i++) {
9411 WindowState w = mPendingRemoveTmp[i];
9412 removeWindowInnerLocked(w.mSession, w);
9413 if (!displayList.contains(w.mDisplayContent)) {
9414 displayList.add(w.mDisplayContent);
9415 }
9416 }
9417
9418 for (DisplayContent displayContent : displayList) {
9419 assignLayersLocked(displayContent.getWindowList());
Craig Mautner19d59bc2012-09-04 11:15:56 -07009420 displayContent.layoutNeeded = true;
Craig Mautner76a71652012-09-03 23:23:58 -07009421 }
Craig Mautner76a71652012-09-03 23:23:58 -07009422 }
9423
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08009424 // Check to see if we are now in a state where the screen should
9425 // be enabled, because the window obscured flags have changed.
9426 enableScreenIfNeededLocked();
Craig Mautner7d8df392012-04-06 15:26:23 -07009427
Craig Mautner711f90a2012-07-03 18:43:52 -07009428 updateLayoutToAnimationLocked();
Craig Mautner7d8df392012-04-06 15:26:23 -07009429
9430 if (DEBUG_WINDOW_TRACE) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009431 Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: animating="
9432 + mAnimator.mAnimating);
Craig Mautner7d8df392012-04-06 15:26:23 -07009433 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009434 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009435
Jeff Brown96307042012-07-27 15:51:34 -07009436 private int toBrightnessOverride(float value) {
9437 return (int)(value * PowerManager.BRIGHTNESS_ON);
9438 }
9439
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009440 void checkDrawnWindowsLocked() {
9441 if (mWaitingForDrawn.size() > 0) {
9442 for (int j=mWaitingForDrawn.size()-1; j>=0; j--) {
9443 Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(j);
9444 WindowState win = pair.first;
9445 //Slog.i(TAG, "Waiting for drawn " + win + ": removed="
9446 // + win.mRemoved + " visible=" + win.isVisibleLw()
9447 // + " shown=" + win.mSurfaceShown);
9448 if (win.mRemoved || !win.isVisibleLw()) {
9449 // Window has been removed or made invisible; no draw
9450 // will now happen, so stop waiting.
9451 Slog.w(TAG, "Aborted waiting for drawn: " + pair.first);
9452 try {
9453 pair.second.sendResult(null);
9454 } catch (RemoteException e) {
9455 }
9456 mWaitingForDrawn.remove(pair);
9457 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009458 } else if (win.mWinAnimator.mSurfaceShown) {
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009459 // Window is now drawn (and shown).
9460 try {
9461 pair.second.sendResult(null);
9462 } catch (RemoteException e) {
9463 }
9464 mWaitingForDrawn.remove(pair);
9465 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9466 }
9467 }
9468 }
9469 }
9470
9471 public void waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009472 synchronized (mWindowMap) {
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009473 WindowState win = windowForClientLocked(null, token, true);
9474 if (win != null) {
9475 Pair<WindowState, IRemoteCallback> pair =
9476 new Pair<WindowState, IRemoteCallback>(win, callback);
9477 Message m = mH.obtainMessage(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9478 mH.sendMessageDelayed(m, 2000);
9479 mWaitingForDrawn.add(pair);
9480 checkDrawnWindowsLocked();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009481 }
9482 }
9483 }
9484
Craig Mautner259328c2012-08-21 19:30:58 -07009485 void setHoldScreenLocked(final Session newHoldScreen) {
9486 final boolean hold = newHoldScreen != null;
9487
9488 if (hold && mHoldingScreenOn != newHoldScreen) {
9489 mHoldingScreenWakeLock.setWorkSource(new WorkSource(newHoldScreen.mUid));
9490 }
9491 mHoldingScreenOn = newHoldScreen;
9492
9493 final boolean state = mHoldingScreenWakeLock.isHeld();
9494 if (hold != state) {
9495 if (hold) {
Daniel Sandler0601eb72011-04-13 01:01:32 -04009496 mPolicy.screenOnStartedLw();
Jeff Brown46b9ac02010-04-22 18:58:52 -07009497 mHoldingScreenWakeLock.acquire();
9498 } else {
9499 mPolicy.screenOnStoppedLw();
9500 mHoldingScreenWakeLock.release();
9501 }
9502 }
9503 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009504
Craig Mautner722285e2012-09-07 13:55:58 -07009505 @Override
Jeff Brown4ed8fe72012-08-30 18:18:29 -07009506 public void requestTraversal() {
9507 synchronized (mWindowMap) {
9508 requestTraversalLocked();
9509 }
9510 }
9511
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08009512 void requestTraversalLocked() {
9513 if (!mTraversalScheduled) {
9514 mTraversalScheduled = true;
9515 mH.sendEmptyMessage(H.DO_TRAVERSAL);
9516 }
9517 }
9518
Craig Mautner711f90a2012-07-03 18:43:52 -07009519 /** Note that Locked in this case is on mLayoutToAnim */
Jeff Brown4a06c802012-02-15 15:06:01 -08009520 void scheduleAnimationLocked() {
Craig Mautner711f90a2012-07-03 18:43:52 -07009521 final LayoutToAnimatorParams layoutToAnim = mLayoutToAnim;
9522 if (!layoutToAnim.mAnimationScheduled) {
9523 layoutToAnim.mAnimationScheduled = true;
9524 mChoreographer.postCallback(
9525 Choreographer.CALLBACK_ANIMATION, mAnimator.mAnimationRunnable, null);
9526 }
9527 }
9528
9529 void updateLayoutToAnimationLocked() {
9530 final LayoutToAnimatorParams layoutToAnim = mLayoutToAnim;
Craig Mautner1caa3992012-06-22 09:46:48 -07009531 synchronized (layoutToAnim) {
9532 // Copy local params to transfer params.
Craig Mautnera91f9e22012-09-14 16:22:08 -07009533 SparseArray<WinAnimatorList> allWinAnimatorLists = layoutToAnim.mWinAnimatorLists;
Craig Mautner59c00972012-07-30 12:10:24 -07009534 allWinAnimatorLists.clear();
9535 DisplayContentsIterator iterator = new DisplayContentsIterator();
9536 while (iterator.hasNext()) {
9537 final DisplayContent displayContent = iterator.next();
9538 WinAnimatorList winAnimatorList = new WinAnimatorList();
9539 final WindowList windows = displayContent.getWindowList();
9540 int N = windows.size();
9541 for (int i = 0; i < N; i++) {
9542 final WindowStateAnimator winAnimator = windows.get(i).mWinAnimator;
9543 if (winAnimator.mSurface != null) {
9544 winAnimatorList.add(winAnimator);
9545 }
Craig Mautner1caa3992012-06-22 09:46:48 -07009546 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07009547 allWinAnimatorLists.put(displayContent.getDisplayId(), winAnimatorList);
Craig Mautner1caa3992012-06-22 09:46:48 -07009548 }
Craig Mautner322e4032012-07-13 13:35:20 -07009549
Craig Mautner1caa3992012-06-22 09:46:48 -07009550 layoutToAnim.mWallpaperTarget = mWallpaperTarget;
Craig Mautner918b53b2012-07-09 14:15:54 -07009551 layoutToAnim.mLowerWallpaperTarget = mLowerWallpaperTarget;
9552 layoutToAnim.mUpperWallpaperTarget = mUpperWallpaperTarget;
Craig Mautner322e4032012-07-13 13:35:20 -07009553
9554 final ArrayList<AppWindowAnimParams> paramList = layoutToAnim.mAppWindowAnimParams;
9555 paramList.clear();
Craig Mautner59c00972012-07-30 12:10:24 -07009556 int N = mAnimatingAppTokens.size();
Craig Mautner322e4032012-07-13 13:35:20 -07009557 for (int i = 0; i < N; i++) {
9558 paramList.add(new AppWindowAnimParams(mAnimatingAppTokens.get(i).mAppAnimator));
9559 }
9560
9561 layoutToAnim.mParamsModified = true;
Craig Mautner711f90a2012-07-03 18:43:52 -07009562 scheduleAnimationLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009563 }
9564 }
Romain Guy06882f82009-06-10 13:36:04 -07009565
Craig Mautner918b53b2012-07-09 14:15:54 -07009566 void updateLayoutToAnimWallpaperTokens() {
9567 synchronized(mLayoutToAnim) {
9568 mLayoutToAnim.mWallpaperTokens = new ArrayList<WindowToken>(mWallpaperTokens);
9569 mLayoutToAnim.mChanges |= LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED;
9570 }
9571 }
9572
Craig Mautnera91f9e22012-09-14 16:22:08 -07009573 void setAnimDimParams(int displayId, DimAnimator.Parameters params) {
Craig Mautnera76fdb72012-07-03 19:03:02 -07009574 synchronized (mLayoutToAnim) {
Craig Mautnera91f9e22012-09-14 16:22:08 -07009575 mLayoutToAnim.mDimParams.put(displayId, params);
Craig Mautnera76fdb72012-07-03 19:03:02 -07009576 scheduleAnimationLocked();
9577 }
9578 }
9579
Craig Mautnera91f9e22012-09-14 16:22:08 -07009580 void startDimmingLocked(final WindowStateAnimator winAnimator, final float target,
Craig Mautnera76fdb72012-07-03 19:03:02 -07009581 final int width, final int height) {
Craig Mautnera91f9e22012-09-14 16:22:08 -07009582 setAnimDimParams(winAnimator.mWin.getDisplayId(),
9583 new DimAnimator.Parameters(winAnimator, width, height, target));
Craig Mautnera76fdb72012-07-03 19:03:02 -07009584 }
9585
Craig Mautnera91f9e22012-09-14 16:22:08 -07009586 void stopDimmingLocked(int displayId) {
9587 setAnimDimParams(displayId, null);
Craig Mautnera76fdb72012-07-03 19:03:02 -07009588 }
9589
Craig Mautner19d59bc2012-09-04 11:15:56 -07009590 private boolean needsLayout() {
9591 DisplayContentsIterator iterator = new DisplayContentsIterator();
9592 while (iterator.hasNext()) {
9593 if (iterator.next().layoutNeeded) {
9594 return true;
9595 }
9596 }
9597 return false;
9598 }
9599
Craig Mautner322e4032012-07-13 13:35:20 -07009600 private boolean copyAnimToLayoutParamsLocked() {
9601 boolean doRequest = false;
9602 final WindowAnimator.AnimatorToLayoutParams animToLayout = mAnimator.mAnimToLayout;
9603 synchronized (animToLayout) {
9604 animToLayout.mUpdateQueued = false;
9605 final int bulkUpdateParams = animToLayout.mBulkUpdateParams;
9606 // TODO(cmautner): As the number of bits grows, use masks of bit groups to
9607 // eliminate unnecessary tests.
9608 if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) {
9609 mInnerFields.mUpdateRotation = true;
9610 doRequest = true;
9611 }
9612 if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
9613 mInnerFields.mWallpaperMayChange = true;
9614 doRequest = true;
9615 }
9616 if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
9617 mInnerFields.mWallpaperForceHidingChanged = true;
9618 doRequest = true;
9619 }
9620 if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
9621 mInnerFields.mOrientationChangeComplete = false;
9622 } else {
9623 mInnerFields.mOrientationChangeComplete = true;
9624 if (mWindowsFreezingScreen) {
9625 doRequest = true;
9626 }
9627 }
9628 if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
9629 mTurnOnScreen = true;
9630 }
9631
Craig Mautner76a71652012-09-03 23:23:58 -07009632 SparseIntArray pendingLayouts = animToLayout.mPendingLayoutChanges;
9633 final int count = pendingLayouts.size();
9634 if (count > 0) {
Craig Mautner322e4032012-07-13 13:35:20 -07009635 doRequest = true;
9636 }
Craig Mautner76a71652012-09-03 23:23:58 -07009637 for (int i = 0; i < count; ++i) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07009638 final DisplayContent displayContent =
9639 getDisplayContentLocked(pendingLayouts.keyAt(i));
Craig Mautner69b08182012-09-05 13:07:13 -07009640 displayContent.pendingLayoutChanges |= pendingLayouts.valueAt(i);
Craig Mautner76a71652012-09-03 23:23:58 -07009641 }
Craig Mautner322e4032012-07-13 13:35:20 -07009642
9643 mWindowDetachedWallpaper = animToLayout.mWindowDetachedWallpaper;
9644 }
9645 return doRequest;
9646 }
9647
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009648 boolean reclaimSomeSurfaceMemoryLocked(WindowStateAnimator winAnimator, String operation,
9649 boolean secure) {
9650 final Surface surface = winAnimator.mSurface;
Dianne Hackborn64825172011-03-02 21:32:58 -08009651 boolean leakedSurface = false;
9652 boolean killedApps = false;
Romain Guy06882f82009-06-10 13:36:04 -07009653
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009654 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
9655 winAnimator.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -07009656
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009657 if (mForceRemoves == null) {
9658 mForceRemoves = new ArrayList<WindowState>();
9659 }
Romain Guy06882f82009-06-10 13:36:04 -07009660
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009661 long callingIdentity = Binder.clearCallingIdentity();
9662 try {
9663 // There was some problem... first, do a sanity check of the
9664 // window list to make sure we haven't left any dangling surfaces
9665 // around.
Craig Mautner59c00972012-07-30 12:10:24 -07009666
9667 AllWindowsIterator iterator = new AllWindowsIterator();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009668 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
Craig Mautner59c00972012-07-30 12:10:24 -07009669 while (iterator.hasNext()) {
9670 WindowState ws = iterator.next();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009671 WindowStateAnimator wsa = ws.mWinAnimator;
9672 if (wsa.mSurface != null) {
9673 if (!mSessions.contains(wsa.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009674 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009675 + ws + " surface=" + wsa.mSurface
9676 + " token=" + ws.mToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009677 + " pid=" + ws.mSession.mPid
9678 + " uid=" + ws.mSession.mUid);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08009679 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009680 wsa.mSurface.destroy();
9681 wsa.mSurfaceShown = false;
9682 wsa.mSurface = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009683 ws.mHasSurface = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009684 mForceRemoves.add(ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009685 leakedSurface = true;
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08009686 } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009687 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009688 + ws + " surface=" + wsa.mSurface
9689 + " token=" + ws.mAppToken);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08009690 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009691 wsa.mSurface.destroy();
9692 wsa.mSurfaceShown = false;
9693 wsa.mSurface = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009694 ws.mHasSurface = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009695 leakedSurface = true;
9696 }
9697 }
9698 }
Romain Guy06882f82009-06-10 13:36:04 -07009699
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009700 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009701 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009702 SparseIntArray pidCandidates = new SparseIntArray();
Craig Mautner59c00972012-07-30 12:10:24 -07009703 iterator = new AllWindowsIterator();
9704 while (iterator.hasNext()) {
9705 WindowState ws = iterator.next();
9706 if (mForceRemoves.contains(ws)) {
9707 continue;
9708 }
9709 WindowStateAnimator wsa = ws.mWinAnimator;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009710 if (wsa.mSurface != null) {
9711 pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009712 }
9713 }
9714 if (pidCandidates.size() > 0) {
9715 int[] pids = new int[pidCandidates.size()];
9716 for (int i=0; i<pids.length; i++) {
9717 pids[i] = pidCandidates.keyAt(i);
9718 }
9719 try {
Dianne Hackborn64825172011-03-02 21:32:58 -08009720 if (mActivityManager.killPids(pids, "Free memory", secure)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009721 killedApps = true;
9722 }
9723 } catch (RemoteException e) {
9724 }
9725 }
9726 }
Romain Guy06882f82009-06-10 13:36:04 -07009727
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009728 if (leakedSurface || killedApps) {
9729 // We managed to reclaim some memory, so get rid of the trouble
9730 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -08009731 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009732 if (surface != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009733 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
Dianne Hackborn5fd21692011-06-07 14:09:47 -07009734 "RECOVER DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009735 surface.destroy();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009736 winAnimator.mSurfaceShown = false;
9737 winAnimator.mSurface = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009738 winAnimator.mWin.mHasSurface = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009739 }
Romain Guy06882f82009-06-10 13:36:04 -07009740
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009741 try {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009742 winAnimator.mWin.mClient.dispatchGetNewSurface();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009743 } catch (RemoteException e) {
9744 }
9745 }
9746 } finally {
9747 Binder.restoreCallingIdentity(callingIdentity);
9748 }
Dianne Hackborn64825172011-03-02 21:32:58 -08009749
9750 return leakedSurface || killedApps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009751 }
Romain Guy06882f82009-06-10 13:36:04 -07009752
Jeff Brown3a22cd92011-01-21 13:59:04 -08009753 private boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009754 WindowState newFocus = computeFocusedWindowLocked();
9755 if (mCurrentFocus != newFocus) {
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07009756 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009757 // This check makes sure that we don't already have the focus
9758 // change message pending.
9759 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
9760 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009761 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009762 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
9763 final WindowState oldFocus = mCurrentFocus;
9764 mCurrentFocus = newFocus;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009765 mAnimator.setCurrentFocus(newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009766 mLosingFocus.remove(newFocus);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009767 int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus);
Romain Guy06882f82009-06-10 13:36:04 -07009768
Craig Mautner59c00972012-07-30 12:10:24 -07009769 // TODO(multidisplay): Focused windows on default display only.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07009770 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07009771
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009772 final WindowState imWindow = mInputMethodWindow;
9773 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009774 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009775 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009776 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
Jeff Brown20337632012-09-24 14:25:54 -07009777 displayContent.layoutNeeded = true;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009778 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009779 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Craig Mautner59c00972012-07-30 12:10:24 -07009780 performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009781 focusChanged &= ~WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009782 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
9783 // Client will do the layout, but we need to assign layers
9784 // for handleNewWindowLocked() below.
Craig Mautner59c00972012-07-30 12:10:24 -07009785 assignLayersLocked(displayContent.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009786 }
9787 }
Dianne Hackborndf89e652011-10-06 22:35:11 -07009788
Craig Mautner39834192012-09-02 07:47:24 -07009789 if ((focusChanged & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07009790 // The change in focus caused us to need to do a layout. Okay.
Jeff Brown20337632012-09-24 14:25:54 -07009791 displayContent.layoutNeeded = true;
Dianne Hackborndf89e652011-10-06 22:35:11 -07009792 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Craig Mautner59c00972012-07-30 12:10:24 -07009793 performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009794 }
9795 }
9796
Jeff Brown349703e2010-06-22 01:27:15 -07009797 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
9798 // If we defer assigning layers, then the caller is responsible for
9799 // doing this part.
Jeff Brown3a22cd92011-01-21 13:59:04 -08009800 finishUpdateFocusedWindowAfterAssignLayersLocked(updateInputWindows);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009801 }
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07009802
9803 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009804 return true;
9805 }
9806 return false;
9807 }
Jeff Brown349703e2010-06-22 01:27:15 -07009808
Jeff Brown3a22cd92011-01-21 13:59:04 -08009809 private void finishUpdateFocusedWindowAfterAssignLayersLocked(boolean updateInputWindows) {
9810 mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows);
Jeff Brown349703e2010-06-22 01:27:15 -07009811 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009812
9813 private WindowState computeFocusedWindowLocked() {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07009814 if (mAnimator.mUniverseBackground != null
9815 && mAnimator.mUniverseBackground.mWin.canReceiveKeys()) {
9816 return mAnimator.mUniverseBackground.mWin;
9817 }
9818
Jeff Brown20337632012-09-24 14:25:54 -07009819 final int displayCount = mDisplayContents.size();
9820 for (int i = 0; i < displayCount; i++) {
9821 final DisplayContent displayContent = mDisplayContents.valueAt(i);
9822 WindowState win = findFocusedWindowLocked(displayContent);
9823 if (win != null) {
9824 return win;
9825 }
9826 }
9827 return null;
9828 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009829
Jeff Brown20337632012-09-24 14:25:54 -07009830 private WindowState findFocusedWindowLocked(DisplayContent displayContent) {
9831 int nextAppIndex = mAppTokens.size()-1;
9832 WindowToken nextApp = nextAppIndex >= 0 ? mAppTokens.get(nextAppIndex) : null;
9833
9834 final WindowList windows = displayContent.getWindowList();
Craig Mautner59c00972012-07-30 12:10:24 -07009835 for (int i = windows.size() - 1; i >= 0; i--) {
Jeff Brown20337632012-09-24 14:25:54 -07009836 final WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009837
Joe Onorato8a9b2202010-02-26 18:56:32 -08009838 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009839 TAG, "Looking for focus: " + i
9840 + " = " + win
9841 + ", flags=" + win.mAttrs.flags
9842 + ", canReceive=" + win.canReceiveKeys());
9843
9844 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -07009845
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009846 // If this window's application has been removed, just skip it.
Craig Mautneref25d7a2012-05-15 23:01:47 -07009847 if (thisApp != null && (thisApp.removed || thisApp.sendingToBottom)) {
Craig Mautner3f99fde2012-06-19 14:10:01 -07009848 if (DEBUG_FOCUS) Slog.v(TAG, "Skipping app because " + (thisApp.removed
9849 ? "removed" : "sendingToBottom"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009850 continue;
9851 }
Romain Guy06882f82009-06-10 13:36:04 -07009852
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009853 // If there is a focused app, don't allow focus to go to any
9854 // windows below it. If this is an application window, step
9855 // through the app tokens until we find its app.
9856 if (thisApp != null && nextApp != null && thisApp != nextApp
9857 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
9858 int origAppIndex = nextAppIndex;
9859 while (nextAppIndex > 0) {
9860 if (nextApp == mFocusedApp) {
9861 // Whoops, we are below the focused app... no focus
9862 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -08009863 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009864 TAG, "Reached focused app: " + mFocusedApp);
9865 return null;
9866 }
9867 nextAppIndex--;
9868 nextApp = mAppTokens.get(nextAppIndex);
9869 if (nextApp == thisApp) {
9870 break;
9871 }
9872 }
9873 if (thisApp != nextApp) {
9874 // Uh oh, the app token doesn't exist! This shouldn't
9875 // happen, but if it does we can get totally hosed...
9876 // so restart at the original app.
9877 nextAppIndex = origAppIndex;
9878 nextApp = mAppTokens.get(nextAppIndex);
9879 }
9880 }
9881
9882 // Dispatch to this window if it is wants key events.
9883 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009884 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009885 TAG, "Found focus @ " + i + " = " + win);
Jeff Brown20337632012-09-24 14:25:54 -07009886 return win;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009887 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009888 }
Jeff Brown20337632012-09-24 14:25:54 -07009889 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009890 }
9891
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009892 private void startFreezingDisplayLocked(boolean inTransaction,
9893 int exitAnim, int enterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009894 if (mDisplayFrozen) {
9895 return;
9896 }
Romain Guy06882f82009-06-10 13:36:04 -07009897
Jeff Browne215f262012-09-10 16:01:14 -07009898 if (!mDisplayReady || !mPolicy.isScreenOnFully()) {
Dianne Hackborn8e8d65f2011-08-11 19:36:18 -07009899 // No need to freeze the screen before the system is ready or if
9900 // the screen is off.
9901 return;
9902 }
9903
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009904 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -07009905
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009906 mDisplayFrozen = true;
Craig Mautner7d8df392012-04-06 15:26:23 -07009907
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009908 mInputMonitor.freezeInputDispatchingLw();
Craig Mautner7d8df392012-04-06 15:26:23 -07009909
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009910 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
9911 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07009912 mNextAppTransitionType = ActivityOptions.ANIM_NONE;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009913 mNextAppTransitionPackage = null;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07009914 mNextAppTransitionThumbnail = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009915 mAppTransitionReady = true;
9916 }
Romain Guy06882f82009-06-10 13:36:04 -07009917
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009918 if (PROFILE_ORIENTATION) {
9919 File file = new File("/data/system/frozen");
9920 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
9921 }
Dianne Hackborna1111872010-11-23 20:55:11 -08009922
9923 if (CUSTOM_SCREEN_ROTATION) {
Craig Mautnera91f9e22012-09-14 16:22:08 -07009924 final DisplayContent displayContent = getDefaultDisplayContentLocked();
9925 final int displayId = displayContent.getDisplayId();
9926 ScreenRotationAnimation screenRotationAnimation =
9927 mAnimator.getScreenRotationAnimationLocked(displayId);
9928 if (screenRotationAnimation != null) {
9929 screenRotationAnimation.kill();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08009930 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07009931
Craig Mautner59c00972012-07-30 12:10:24 -07009932 // TODO(multidisplay): rotation on main screen only.
Jeff Browne215f262012-09-10 16:01:14 -07009933 final Display display = displayContent.getDisplay();
9934 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
Craig Mautnera91f9e22012-09-14 16:22:08 -07009935 screenRotationAnimation = new ScreenRotationAnimation(mContext,
Jeff Browne215f262012-09-10 16:01:14 -07009936 display, mFxSession, inTransaction, displayInfo.logicalWidth,
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009937 displayInfo.logicalHeight, display.getRotation(),
9938 exitAnim, enterAnim);
Craig Mautnera91f9e22012-09-14 16:22:08 -07009939 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackborna1111872010-11-23 20:55:11 -08009940 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009941 }
Romain Guy06882f82009-06-10 13:36:04 -07009942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009943 private void stopFreezingDisplayLocked() {
9944 if (!mDisplayFrozen) {
9945 return;
9946 }
Romain Guy06882f82009-06-10 13:36:04 -07009947
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009948 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen
9949 || mClientFreezingScreen) {
Craig Mautnerd87946b2012-03-29 18:00:19 -07009950 if (DEBUG_ORIENTATION) Slog.d(TAG,
9951 "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + mWaitingForConfig
9952 + ", mAppsFreezingScreen=" + mAppsFreezingScreen
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009953 + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen
9954 + ", mClientFreezingScreen=" + mClientFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009955 return;
9956 }
9957
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009958 mDisplayFrozen = false;
9959 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009960 mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009961 if (PROFILE_ORIENTATION) {
9962 Debug.stopMethodTracing();
9963 }
Dianne Hackborna1111872010-11-23 20:55:11 -08009964
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009965 boolean updateRotation = false;
Craig Mautner59c00972012-07-30 12:10:24 -07009966
Craig Mautnera91f9e22012-09-14 16:22:08 -07009967 final DisplayContent displayContent = getDefaultDisplayContentLocked();
9968 final int displayId = displayContent.getDisplayId();
9969 ScreenRotationAnimation screenRotationAnimation =
9970 mAnimator.getScreenRotationAnimationLocked(displayId);
9971 if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
9972 && screenRotationAnimation.hasScreenshot()) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07009973 if (DEBUG_ORIENTATION) Slog.i(TAG, "**** Dismissing screen rotation animation");
Craig Mautner59c00972012-07-30 12:10:24 -07009974 // TODO(multidisplay): rotation on main screen only.
Craig Mautnera91f9e22012-09-14 16:22:08 -07009975 DisplayInfo displayInfo = displayContent.getDisplayInfo();
9976 if (screenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
Craig Mautner59c00972012-07-30 12:10:24 -07009977 mTransitionAnimationScale, displayInfo.logicalWidth,
9978 displayInfo.logicalHeight)) {
Craig Mautner711f90a2012-07-03 18:43:52 -07009979 updateLayoutToAnimationLocked();
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009980 } else {
Craig Mautnera91f9e22012-09-14 16:22:08 -07009981 screenRotationAnimation.kill();
9982 screenRotationAnimation = null;
9983 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009984 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -08009985 }
9986 } else {
Craig Mautnera91f9e22012-09-14 16:22:08 -07009987 if (screenRotationAnimation != null) {
9988 screenRotationAnimation.kill();
9989 screenRotationAnimation = null;
9990 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009991 }
9992 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -08009993 }
Romain Guy06882f82009-06-10 13:36:04 -07009994
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009995 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009996
Dianne Hackborn420829e2011-01-28 11:30:35 -08009997 boolean configChanged;
9998
Christopher Tateb696aee2010-04-02 19:08:30 -07009999 // While the display is frozen we don't re-compute the orientation
10000 // to avoid inconsistent states. However, something interesting
10001 // could have actually changed during that time so re-evaluate it
10002 // now to catch that.
Dianne Hackborn420829e2011-01-28 11:30:35 -080010003 configChanged = updateOrientationFromAppTokensLocked(false);
Christopher Tateb696aee2010-04-02 19:08:30 -070010004
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010005 // A little kludge: a lot could have happened while the
10006 // display was frozen, so now that we are coming back we
10007 // do a gc so that any remote references the system
10008 // processes holds on others can be released if they are
10009 // no longer needed.
10010 mH.removeMessages(H.FORCE_GC);
10011 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
10012 2000);
Romain Guy06882f82009-06-10 13:36:04 -070010013
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010014 mScreenFrozenLock.release();
Dianne Hackborn89ba6752011-01-23 16:51:16 -080010015
10016 if (updateRotation) {
10017 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Jeff Brown01a98dd2011-09-20 15:08:29 -070010018 configChanged |= updateRotationUncheckedLocked(false);
Dianne Hackborn420829e2011-01-28 11:30:35 -080010019 }
10020
10021 if (configChanged) {
10022 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackborn89ba6752011-01-23 16:51:16 -080010023 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010024 }
Romain Guy06882f82009-06-10 13:36:04 -070010025
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010026 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
10027 DisplayMetrics dm) {
10028 if (index < tokens.length) {
10029 String str = tokens[index];
10030 if (str != null && str.length() > 0) {
10031 try {
10032 int val = Integer.parseInt(str);
10033 return val;
10034 } catch (Exception e) {
10035 }
10036 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010037 }
10038 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
10039 return defDps;
10040 }
10041 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
10042 return val;
10043 }
10044
Jeff Brown4ed8fe72012-08-30 18:18:29 -070010045 void createWatermarkInTransaction() {
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010046 if (mWatermark != null) {
10047 return;
10048 }
10049
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010050 File file = new File("/system/etc/setup.conf");
10051 FileInputStream in = null;
10052 try {
10053 in = new FileInputStream(file);
10054 DataInputStream ind = new DataInputStream(in);
10055 String line = ind.readLine();
10056 if (line != null) {
10057 String[] toks = line.split("%");
10058 if (toks != null && toks.length > 0) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010059 mWatermark = new Watermark(getDefaultDisplayContentLocked().getDisplay(),
Jeff Browne215f262012-09-10 16:01:14 -070010060 mRealDisplayMetrics, mFxSession, toks);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010061 }
10062 }
10063 } catch (FileNotFoundException e) {
10064 } catch (IOException e) {
10065 } finally {
10066 if (in != null) {
10067 try {
10068 in.close();
10069 } catch (IOException e) {
10070 }
10071 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010072 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010073 }
10074
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010075 @Override
Joe Onorato664644d2011-01-23 17:53:23 -080010076 public void statusBarVisibilityChanged(int visibility) {
Dianne Hackborndf89e652011-10-06 22:35:11 -070010077 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
10078 != PackageManager.PERMISSION_GRANTED) {
10079 throw new SecurityException("Caller does not hold permission "
10080 + android.Manifest.permission.STATUS_BAR);
10081 }
Dianne Hackborn9a230e02011-10-06 11:51:27 -070010082
Joe Onorato664644d2011-01-23 17:53:23 -080010083 synchronized (mWindowMap) {
Dianne Hackborndf89e652011-10-06 22:35:11 -070010084 mLastStatusBarVisibility = visibility;
10085 visibility = mPolicy.adjustSystemUiVisibilityLw(visibility);
10086 updateStatusBarVisibilityLocked(visibility);
10087 }
10088 }
10089
Craig Mautner59c00972012-07-30 12:10:24 -070010090 // TOOD(multidisplay): StatusBar on multiple screens?
Dianne Hackborndf89e652011-10-06 22:35:11 -070010091 void updateStatusBarVisibilityLocked(int visibility) {
10092 mInputManager.setSystemUiVisibility(visibility);
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010093 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -070010094 final int N = windows.size();
Dianne Hackborndf89e652011-10-06 22:35:11 -070010095 for (int i = 0; i < N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -070010096 WindowState ws = windows.get(i);
Dianne Hackborndf89e652011-10-06 22:35:11 -070010097 try {
10098 int curValue = ws.mSystemUiVisibility;
10099 int diff = curValue ^ visibility;
10100 // We are only interested in differences of one of the
10101 // clearable flags...
10102 diff &= View.SYSTEM_UI_CLEARABLE_FLAGS;
10103 // ...if it has actually been cleared.
10104 diff &= ~visibility;
10105 int newValue = (curValue&~diff) | (visibility&diff);
10106 if (newValue != curValue) {
10107 ws.mSeq++;
10108 ws.mSystemUiVisibility = newValue;
10109 }
10110 if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) {
10111 ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq,
10112 visibility, newValue, diff);
10113 }
10114 } catch (RemoteException e) {
10115 // so sorry
10116 }
10117 }
10118 }
10119
10120 @Override
10121 public void reevaluateStatusBarVisibility() {
10122 synchronized (mWindowMap) {
10123 int visibility = mPolicy.adjustSystemUiVisibilityLw(mLastStatusBarVisibility);
10124 updateStatusBarVisibilityLocked(visibility);
10125 performLayoutAndPlaceSurfacesLocked();
10126 }
10127 }
10128
10129 @Override
Jeff Brown32cbc38552011-12-01 14:01:49 -080010130 public FakeWindow addFakeWindow(Looper looper,
10131 InputEventReceiver.Factory inputEventReceiverFactory,
Dianne Hackborndf89e652011-10-06 22:35:11 -070010132 String name, int windowType, int layoutParamsFlags, boolean canReceiveKeys,
10133 boolean hasFocus, boolean touchFullscreen) {
10134 synchronized (mWindowMap) {
Jeff Brown32cbc38552011-12-01 14:01:49 -080010135 FakeWindowImpl fw = new FakeWindowImpl(this, looper, inputEventReceiverFactory,
10136 name, windowType,
Dianne Hackborndf89e652011-10-06 22:35:11 -070010137 layoutParamsFlags, canReceiveKeys, hasFocus, touchFullscreen);
10138 int i=0;
10139 while (i<mFakeWindows.size()) {
10140 if (mFakeWindows.get(i).mWindowLayer <= fw.mWindowLayer) {
10141 break;
Joe Onorato664644d2011-01-23 17:53:23 -080010142 }
10143 }
Dianne Hackborndf89e652011-10-06 22:35:11 -070010144 mFakeWindows.add(i, fw);
10145 mInputMonitor.updateInputWindowsLw(true);
10146 return fw;
10147 }
10148 }
10149
10150 boolean removeFakeWindowLocked(FakeWindow window) {
10151 synchronized (mWindowMap) {
10152 if (mFakeWindows.remove(window)) {
10153 mInputMonitor.updateInputWindowsLw(true);
10154 return true;
10155 }
10156 return false;
Joe Onorato664644d2011-01-23 17:53:23 -080010157 }
10158 }
10159
satoke0a99412012-05-10 02:22:58 +090010160 // It is assumed that this method is called only by InputMethodManagerService.
10161 public void saveLastInputMethodWindowForTransition() {
10162 synchronized (mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -070010163 // TODO(multidisplay): Pass in the displayID.
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010164 DisplayContent displayContent = getDefaultDisplayContentLocked();
satoke0a99412012-05-10 02:22:58 +090010165 if (mInputMethodWindow != null) {
10166 mPolicy.setLastInputMethodWindowLw(mInputMethodWindow, mInputMethodTarget);
10167 }
10168 }
10169 }
10170
Daniel Sandler0c4ccff2011-10-19 16:39:14 -040010171 @Override
10172 public boolean hasNavigationBar() {
10173 return mPolicy.hasNavigationBar();
10174 }
10175
Jim Miller93c518e2012-01-17 15:55:31 -080010176 public void lockNow() {
10177 mPolicy.lockNow();
10178 }
10179
Jeff Brownd7a04de2012-06-17 14:17:52 -070010180 void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010181 pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010182 mPolicy.dump(" ", pw, args);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010183 }
10184
Jeff Brownd7a04de2012-06-17 14:17:52 -070010185 void dumpTokensLocked(PrintWriter pw, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010186 pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
10187 if (mTokenMap.size() > 0) {
10188 pw.println(" All tokens:");
10189 Iterator<WindowToken> it = mTokenMap.values().iterator();
10190 while (it.hasNext()) {
10191 WindowToken token = it.next();
10192 pw.print(" Token "); pw.print(token.token);
10193 if (dumpAll) {
10194 pw.println(':');
10195 token.dump(pw, " ");
10196 } else {
10197 pw.println();
10198 }
10199 }
10200 }
10201 if (mWallpaperTokens.size() > 0) {
10202 pw.println();
10203 pw.println(" Wallpaper tokens:");
10204 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
10205 WindowToken token = mWallpaperTokens.get(i);
10206 pw.print(" Wallpaper #"); pw.print(i);
10207 pw.print(' '); pw.print(token);
10208 if (dumpAll) {
10209 pw.println(':');
10210 token.dump(pw, " ");
10211 } else {
10212 pw.println();
10213 }
10214 }
10215 }
10216 if (mAppTokens.size() > 0) {
10217 pw.println();
10218 pw.println(" Application tokens in Z order:");
10219 for (int i=mAppTokens.size()-1; i>=0; i--) {
Craig Mautnerdbb79912012-03-01 18:59:14 -080010220 pw.print(" App #"); pw.print(i); pw.println(": ");
10221 mAppTokens.get(i).dump(pw, " ");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010222 }
10223 }
10224 if (mFinishedStarting.size() > 0) {
10225 pw.println();
10226 pw.println(" Finishing start of application tokens:");
10227 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
10228 WindowToken token = mFinishedStarting.get(i);
10229 pw.print(" Finished Starting #"); pw.print(i);
10230 pw.print(' '); pw.print(token);
10231 if (dumpAll) {
10232 pw.println(':');
10233 token.dump(pw, " ");
10234 } else {
10235 pw.println();
10236 }
10237 }
10238 }
10239 if (mExitingTokens.size() > 0) {
10240 pw.println();
10241 pw.println(" Exiting tokens:");
10242 for (int i=mExitingTokens.size()-1; i>=0; i--) {
10243 WindowToken token = mExitingTokens.get(i);
10244 pw.print(" Exiting #"); pw.print(i);
10245 pw.print(' '); pw.print(token);
10246 if (dumpAll) {
10247 pw.println(':');
10248 token.dump(pw, " ");
10249 } else {
10250 pw.println();
10251 }
10252 }
10253 }
10254 if (mExitingAppTokens.size() > 0) {
10255 pw.println();
10256 pw.println(" Exiting application tokens:");
10257 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
10258 WindowToken token = mExitingAppTokens.get(i);
10259 pw.print(" Exiting App #"); pw.print(i);
10260 pw.print(' '); pw.print(token);
10261 if (dumpAll) {
10262 pw.println(':');
10263 token.dump(pw, " ");
10264 } else {
10265 pw.println();
10266 }
10267 }
10268 }
Craig Mautneref25d7a2012-05-15 23:01:47 -070010269 if (mAppTransitionRunning && mAnimatingAppTokens.size() > 0) {
10270 pw.println();
10271 pw.println(" Application tokens during animation:");
10272 for (int i=mAnimatingAppTokens.size()-1; i>=0; i--) {
10273 WindowToken token = mAnimatingAppTokens.get(i);
10274 pw.print(" App moving to bottom #"); pw.print(i);
10275 pw.print(' '); pw.print(token);
10276 if (dumpAll) {
10277 pw.println(':');
10278 token.dump(pw, " ");
10279 } else {
10280 pw.println();
10281 }
10282 }
10283 }
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010284 if (mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
10285 pw.println();
10286 if (mOpeningApps.size() > 0) {
10287 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
10288 }
10289 if (mClosingApps.size() > 0) {
10290 pw.print(" mClosingApps="); pw.println(mClosingApps);
10291 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010292 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010293 }
10294
Jeff Brownd7a04de2012-06-17 14:17:52 -070010295 void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010296 pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
10297 if (mSessions.size() > 0) {
10298 Iterator<Session> it = mSessions.iterator();
10299 while (it.hasNext()) {
10300 Session s = it.next();
10301 pw.print(" Session "); pw.print(s); pw.println(':');
10302 s.dump(pw, " ");
10303 }
10304 }
10305 }
10306
Jeff Brownd7a04de2012-06-17 14:17:52 -070010307 void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010308 ArrayList<WindowState> windows) {
10309 pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010310 dumpWindowsNoHeaderLocked(pw, dumpAll, windows);
10311 }
10312
10313 void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll,
10314 ArrayList<WindowState> windows) {
Craig Mautner59c00972012-07-30 12:10:24 -070010315 int j = 0;
10316 final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
10317 while (iterator.hasNext()) {
10318 final WindowState w = iterator.next();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010319 if (windows == null || windows.contains(w)) {
Craig Mautner59c00972012-07-30 12:10:24 -070010320 pw.print(" Window #"); pw.print(j++); pw.print(' ');
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010321 pw.print(w); pw.println(":");
Dianne Hackborn89620282011-09-11 12:47:45 -070010322 w.dump(pw, " ", dumpAll || windows != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010323 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010324 }
10325 if (mInputMethodDialogs.size() > 0) {
10326 pw.println();
10327 pw.println(" Input method dialogs:");
10328 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
10329 WindowState w = mInputMethodDialogs.get(i);
10330 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010331 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010332 }
10333 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010334 }
10335 if (mPendingRemove.size() > 0) {
10336 pw.println();
10337 pw.println(" Remove pending for:");
10338 for (int i=mPendingRemove.size()-1; i>=0; i--) {
10339 WindowState w = mPendingRemove.get(i);
10340 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010341 pw.print(" Remove #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010342 pw.print(w);
10343 if (dumpAll) {
10344 pw.println(":");
10345 w.dump(pw, " ", true);
10346 } else {
10347 pw.println();
10348 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010349 }
10350 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010351 }
10352 if (mForceRemoves != null && mForceRemoves.size() > 0) {
10353 pw.println();
10354 pw.println(" Windows force removing:");
10355 for (int i=mForceRemoves.size()-1; i>=0; i--) {
10356 WindowState w = mForceRemoves.get(i);
10357 pw.print(" Removing #"); pw.print(i); pw.print(' ');
10358 pw.print(w);
10359 if (dumpAll) {
10360 pw.println(":");
10361 w.dump(pw, " ", true);
10362 } else {
10363 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010364 }
10365 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010366 }
10367 if (mDestroySurface.size() > 0) {
10368 pw.println();
10369 pw.println(" Windows waiting to destroy their surface:");
10370 for (int i=mDestroySurface.size()-1; i>=0; i--) {
10371 WindowState w = mDestroySurface.get(i);
10372 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010373 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010374 pw.print(w);
10375 if (dumpAll) {
10376 pw.println(":");
10377 w.dump(pw, " ", true);
10378 } else {
10379 pw.println();
10380 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010381 }
10382 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010383 }
10384 if (mLosingFocus.size() > 0) {
10385 pw.println();
10386 pw.println(" Windows losing focus:");
10387 for (int i=mLosingFocus.size()-1; i>=0; i--) {
10388 WindowState w = mLosingFocus.get(i);
10389 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010390 pw.print(" Losing #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010391 pw.print(w);
10392 if (dumpAll) {
10393 pw.println(":");
10394 w.dump(pw, " ", true);
10395 } else {
10396 pw.println();
10397 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010398 }
10399 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010400 }
10401 if (mResizingWindows.size() > 0) {
10402 pw.println();
10403 pw.println(" Windows waiting to resize:");
10404 for (int i=mResizingWindows.size()-1; i>=0; i--) {
10405 WindowState w = mResizingWindows.get(i);
10406 if (windows == null || windows.contains(w)) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010407 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010408 pw.print(w);
10409 if (dumpAll) {
10410 pw.println(":");
10411 w.dump(pw, " ", true);
10412 } else {
10413 pw.println();
10414 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010415 }
10416 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010417 }
Dianne Hackborn38e29a62011-09-18 14:43:08 -070010418 if (mWaitingForDrawn.size() > 0) {
10419 pw.println();
10420 pw.println(" Clients waiting for these windows to be drawn:");
10421 for (int i=mWaitingForDrawn.size()-1; i>=0; i--) {
10422 Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(i);
10423 pw.print(" Waiting #"); pw.print(i); pw.print(' '); pw.print(pair.first);
10424 pw.print(": "); pw.println(pair.second);
10425 }
10426 }
Craig Mautnera91f9e22012-09-14 16:22:08 -070010427 pw.println(" DisplayContents");
Jeff Browne215f262012-09-10 16:01:14 -070010428 if (mDisplayReady) {
Craig Mautner59c00972012-07-30 12:10:24 -070010429 DisplayContentsIterator dCIterator = new DisplayContentsIterator();
10430 while (dCIterator.hasNext()) {
Craig Mautnera91f9e22012-09-14 16:22:08 -070010431 dCIterator.next().dump(" ", pw);
Craig Mautner59c00972012-07-30 12:10:24 -070010432 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010433 } else {
10434 pw.println(" NO DISPLAY");
10435 }
10436 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
10437 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
10438 if (mLastFocus != mCurrentFocus) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010439 pw.print(" mLastFocus="); pw.println(mLastFocus);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010440 }
10441 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
10442 if (mInputMethodTarget != null) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010443 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010444 }
10445 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
10446 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
10447 if (dumpAll) {
Dianne Hackborn85afd1b2012-05-13 13:31:06 -070010448 pw.print(" mSystemDecorRect="); pw.print(mSystemDecorRect.toShortString());
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070010449 pw.print(" mSystemDecorLayer="); pw.print(mSystemDecorLayer);
10450 pw.print(" mScreenRecr="); pw.println(mScreenRect.toShortString());
Dianne Hackborndf89e652011-10-06 22:35:11 -070010451 if (mLastStatusBarVisibility != 0) {
10452 pw.print(" mLastStatusBarVisibility=0x");
10453 pw.println(Integer.toHexString(mLastStatusBarVisibility));
10454 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010455 if (mInputMethodWindow != null) {
10456 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
10457 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -070010458 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -070010459 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
10460 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
10461 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
10462 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010463 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
10464 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
10465 if (mInputMethodAnimLayerAdjustment != 0 ||
10466 mWallpaperAnimLayerAdjustment != 0) {
10467 pw.print(" mInputMethodAnimLayerAdjustment=");
10468 pw.print(mInputMethodAnimLayerAdjustment);
10469 pw.print(" mWallpaperAnimLayerAdjustment=");
10470 pw.println(mWallpaperAnimLayerAdjustment);
10471 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010472 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
10473 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
Craig Mautner19d59bc2012-09-04 11:15:56 -070010474 if (needsLayout()) {
10475 pw.print(" layoutNeeded on displays=");
10476 DisplayContentsIterator dcIterator = new DisplayContentsIterator();
10477 while (dcIterator.hasNext()) {
10478 final DisplayContent displayContent = dcIterator.next();
10479 if (displayContent.layoutNeeded) {
10480 pw.print(displayContent.getDisplayId());
10481 }
10482 }
10483 pw.println();
10484 }
Craig Mautner69b08182012-09-05 13:07:13 -070010485 pw.print(" mTransactionSequence="); pw.println(mTransactionSequence);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010486 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -070010487 pw.print(" windows="); pw.print(mWindowsFreezingScreen);
10488 pw.print(" client="); pw.print(mClientFreezingScreen);
10489 pw.print(" apps="); pw.print(mAppsFreezingScreen);
10490 pw.print(" waitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010491 pw.print(" mRotation="); pw.print(mRotation);
Dianne Hackborndacea8c2011-04-21 17:26:39 -070010492 pw.print(" mAltOrientation="); pw.println(mAltOrientation);
Craig Mautnerf20588f2012-04-11 17:06:21 -070010493 pw.print(" mLastWindowForcedOrientation="); pw.print(mLastWindowForcedOrientation);
Dianne Hackbornbc7386c2011-06-06 17:27:54 -070010494 pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation);
Jeff Brown01a98dd2011-09-20 15:08:29 -070010495 pw.print(" mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
Dianne Hackborn4dcece82012-02-10 14:50:32 -080010496 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
10497 pw.print(" mTransitionWindowAnimationScale="); pw.print(mTransitionAnimationScale);
Chet Haasec38fa1f2012-02-01 16:37:46 -080010498 pw.print(" mAnimatorDurationScale="); pw.println(mAnimatorDurationScale);
Dianne Hackborn4dcece82012-02-10 14:50:32 -080010499 pw.print(" mTraversalScheduled="); pw.print(mTraversalScheduled);
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010500 pw.print(" mNextAppTransition=0x");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010501 pw.print(Integer.toHexString(mNextAppTransition));
Dianne Hackborn9d132642011-04-21 17:26:39 -070010502 pw.print(" mAppTransitionReady="); pw.println(mAppTransitionReady);
10503 pw.print(" mAppTransitionRunning="); pw.print(mAppTransitionRunning);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010504 pw.print(" mAppTransitionTimeout="); pw.println(mAppTransitionTimeout);
10505 if (mNextAppTransitionType != ActivityOptions.ANIM_NONE) {
10506 pw.print(" mNextAppTransitionType="); pw.println(mNextAppTransitionType);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010507 }
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010508 switch (mNextAppTransitionType) {
10509 case ActivityOptions.ANIM_CUSTOM:
10510 pw.print(" mNextAppTransitionPackage=");
Dianne Hackborn84375872012-06-01 19:03:50 -070010511 pw.println(mNextAppTransitionPackage);
10512 pw.print(" mNextAppTransitionEnter=0x");
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010513 pw.print(Integer.toHexString(mNextAppTransitionEnter));
10514 pw.print(" mNextAppTransitionExit=0x");
Dianne Hackborn84375872012-06-01 19:03:50 -070010515 pw.println(Integer.toHexString(mNextAppTransitionExit));
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010516 break;
10517 case ActivityOptions.ANIM_SCALE_UP:
10518 pw.print(" mNextAppTransitionStartX="); pw.print(mNextAppTransitionStartX);
10519 pw.print(" mNextAppTransitionStartY=");
10520 pw.println(mNextAppTransitionStartY);
10521 pw.print(" mNextAppTransitionStartWidth=");
10522 pw.print(mNextAppTransitionStartWidth);
10523 pw.print(" mNextAppTransitionStartHeight=");
10524 pw.println(mNextAppTransitionStartHeight);
10525 break;
Michael Jurka832cb222012-04-13 09:32:47 -070010526 case ActivityOptions.ANIM_THUMBNAIL_SCALE_UP:
10527 case ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN:
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010528 pw.print(" mNextAppTransitionThumbnail=");
10529 pw.print(mNextAppTransitionThumbnail);
Dianne Hackborn84375872012-06-01 19:03:50 -070010530 pw.print(" mNextAppTransitionStartX=");
10531 pw.print(mNextAppTransitionStartX);
10532 pw.print(" mNextAppTransitionStartY=");
10533 pw.println(mNextAppTransitionStartY);
Michael Jurka832cb222012-04-13 09:32:47 -070010534 pw.print(" mNextAppTransitionScaleUp="); pw.println(mNextAppTransitionScaleUp);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010535 break;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070010536 }
Dianne Hackborn84375872012-06-01 19:03:50 -070010537 if (mNextAppTransitionCallback != null) {
10538 pw.print(" mNextAppTransitionCallback=");
10539 pw.println(mNextAppTransitionCallback);
10540 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010541 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010542 pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Craig Mautner6fbda632012-07-03 09:26:39 -070010543 pw.println(" Window Animator:");
Craig Mautnera91f9e22012-09-14 16:22:08 -070010544 mAnimator.dumpLocked(pw, " ", dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010545 }
10546 }
10547
Jeff Brownd7a04de2012-06-17 14:17:52 -070010548 boolean dumpWindows(PrintWriter pw, String name, String[] args,
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010549 int opti, boolean dumpAll) {
Craig Mautner722285e2012-09-07 13:55:58 -070010550 WindowList windows = new WindowList();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010551 if ("visible".equals(name)) {
10552 synchronized(mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -070010553 final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
10554 while (iterator.hasNext()) {
10555 final WindowState w = iterator.next();
Craig Mautnerc2f9be02012-03-27 17:32:29 -070010556 if (w.mWinAnimator.mSurfaceShown) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010557 windows.add(w);
10558 }
10559 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010560 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010561 } else {
10562 int objectId = 0;
10563 // See if this is an object ID.
10564 try {
10565 objectId = Integer.parseInt(name, 16);
10566 name = null;
10567 } catch (RuntimeException e) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010568 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010569 synchronized(mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -070010570 final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
10571 while (iterator.hasNext()) {
10572 final WindowState w = iterator.next();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010573 if (name != null) {
10574 if (w.mAttrs.getTitle().toString().contains(name)) {
10575 windows.add(w);
10576 }
10577 } else if (System.identityHashCode(w) == objectId) {
10578 windows.add(w);
10579 }
10580 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010581 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010582 }
10583
10584 if (windows.size() <= 0) {
10585 return false;
10586 }
10587
10588 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010589 dumpWindowsLocked(pw, dumpAll, windows);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010590 }
10591 return true;
10592 }
10593
Jeff Brownd7a04de2012-06-17 14:17:52 -070010594 void dumpLastANRLocked(PrintWriter pw) {
10595 pw.println("WINDOW MANAGER LAST ANR (dumpsys window lastanr)");
10596 if (mLastANRState == null) {
10597 pw.println(" <no ANR has occurred since boot>");
10598 } else {
10599 pw.println(mLastANRState);
10600 }
10601 }
10602
10603 /**
10604 * Saves information about the state of the window manager at
10605 * the time an ANR occurred before anything else in the system changes
10606 * in response.
10607 *
Jeff Brownee172412012-06-18 12:58:03 -070010608 * @param appWindowToken The application that ANR'd, may be null.
Jeff Brownd7a04de2012-06-17 14:17:52 -070010609 * @param windowState The window that ANR'd, may be null.
10610 */
10611 public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState) {
10612 StringWriter sw = new StringWriter();
10613 PrintWriter pw = new PrintWriter(sw);
10614 pw.println(" ANR time: " + DateFormat.getInstance().format(new Date()));
Jeff Brownee172412012-06-18 12:58:03 -070010615 if (appWindowToken != null) {
10616 pw.println(" Application at fault: " + appWindowToken.stringName);
10617 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010618 if (windowState != null) {
10619 pw.println(" Window at fault: " + windowState.mAttrs.getTitle());
10620 }
10621 pw.println();
10622 dumpWindowsNoHeaderLocked(pw, true, null);
10623 pw.close();
10624 mLastANRState = sw.toString();
10625 }
10626
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010627 @Override
10628 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10629 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
10630 != PackageManager.PERMISSION_GRANTED) {
10631 pw.println("Permission Denial: can't dump WindowManager from from pid="
10632 + Binder.getCallingPid()
10633 + ", uid=" + Binder.getCallingUid());
10634 return;
10635 }
10636
10637 boolean dumpAll = false;
10638
10639 int opti = 0;
10640 while (opti < args.length) {
10641 String opt = args[opti];
10642 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10643 break;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010644 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010645 opti++;
10646 if ("-a".equals(opt)) {
10647 dumpAll = true;
10648 } else if ("-h".equals(opt)) {
10649 pw.println("Window manager dump options:");
10650 pw.println(" [-a] [-h] [cmd] ...");
10651 pw.println(" cmd may be one of:");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010652 pw.println(" l[astanr]: last ANR information");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010653 pw.println(" p[policy]: policy state");
10654 pw.println(" s[essions]: active sessions");
10655 pw.println(" t[okens]: token list");
10656 pw.println(" w[indows]: window list");
10657 pw.println(" cmd may also be a NAME to dump windows. NAME may");
10658 pw.println(" be a partial substring in a window name, a");
10659 pw.println(" Window hex object identifier, or");
10660 pw.println(" \"all\" for all windows, or");
10661 pw.println(" \"visible\" for the visible windows.");
10662 pw.println(" -a: include all available server state.");
10663 return;
Dianne Hackborn87fc3082010-12-03 13:09:12 -080010664 } else {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010665 pw.println("Unknown argument: " + opt + "; use -h for help");
Dianne Hackborn87fc3082010-12-03 13:09:12 -080010666 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010667 }
10668
10669 // Is the caller requesting to dump a particular piece of data?
10670 if (opti < args.length) {
10671 String cmd = args[opti];
10672 opti++;
Jeff Brownd7a04de2012-06-17 14:17:52 -070010673 if ("lastanr".equals(cmd) || "l".equals(cmd)) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010674 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010675 dumpLastANRLocked(pw);
10676 }
10677 return;
10678 } else if ("policy".equals(cmd) || "p".equals(cmd)) {
10679 synchronized(mWindowMap) {
10680 dumpPolicyLocked(pw, args, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010681 }
10682 return;
10683 } else if ("sessions".equals(cmd) || "s".equals(cmd)) {
10684 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010685 dumpSessionsLocked(pw, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010686 }
10687 return;
10688 } else if ("tokens".equals(cmd) || "t".equals(cmd)) {
10689 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010690 dumpTokensLocked(pw, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010691 }
10692 return;
10693 } else if ("windows".equals(cmd) || "w".equals(cmd)) {
10694 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010695 dumpWindowsLocked(pw, true, null);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010696 }
10697 return;
10698 } else if ("all".equals(cmd) || "a".equals(cmd)) {
10699 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010700 dumpWindowsLocked(pw, true, null);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010701 }
10702 return;
10703 } else {
10704 // Dumping a single name?
Jeff Brownd7a04de2012-06-17 14:17:52 -070010705 if (!dumpWindows(pw, cmd, args, opti, dumpAll)) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010706 pw.println("Bad window command, or no windows match: " + cmd);
10707 pw.println("Use -h for help.");
10708 }
10709 return;
10710 }
10711 }
10712
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010713 synchronized(mWindowMap) {
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010714 pw.println();
10715 if (dumpAll) {
10716 pw.println("-------------------------------------------------------------------------------");
10717 }
10718 dumpLastANRLocked(pw);
10719 pw.println();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010720 if (dumpAll) {
10721 pw.println("-------------------------------------------------------------------------------");
10722 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010723 dumpPolicyLocked(pw, args, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010724 pw.println();
10725 if (dumpAll) {
10726 pw.println("-------------------------------------------------------------------------------");
10727 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010728 dumpSessionsLocked(pw, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010729 pw.println();
10730 if (dumpAll) {
10731 pw.println("-------------------------------------------------------------------------------");
10732 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010733 dumpTokensLocked(pw, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010734 pw.println();
10735 if (dumpAll) {
10736 pw.println("-------------------------------------------------------------------------------");
10737 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010738 dumpWindowsLocked(pw, dumpAll, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010739 }
10740 }
10741
Jeff Brown349703e2010-06-22 01:27:15 -070010742 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010743 public void monitor() {
10744 synchronized (mWindowMap) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070010745 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010746
Jeff Brown2992ea72011-01-28 22:04:14 -080010747 public interface OnHardKeyboardStatusChangeListener {
10748 public void onHardKeyboardStatusChange(boolean available, boolean enabled);
10749 }
Craig Mautnera2c77052012-03-26 12:14:43 -070010750
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070010751 void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
Craig Mautnercf8cbbe2012-03-25 21:54:36 -070010752 if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070010753 Slog.v(TAG, "Layouts looping: " + msg + ", mPendingLayoutChanges = 0x" +
10754 Integer.toHexString(pendingLayoutChanges));
Craig Mautnercf8cbbe2012-03-25 21:54:36 -070010755 }
10756 }
Craig Mautner59c00972012-07-30 12:10:24 -070010757
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010758 public void createDisplayContentLocked(final Display display) {
Craig Mautner722285e2012-09-07 13:55:58 -070010759 if (display == null) {
10760 throw new IllegalArgumentException("getDisplayContent: display must not be null");
10761 }
10762 final DisplayContent displayContent = new DisplayContent(display);
10763 mDisplayContents.put(display.getDisplayId(), displayContent);
10764 }
10765
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010766 public DisplayContent getDisplayContentLocked(final int displayId) {
Craig Mautner59c00972012-07-30 12:10:24 -070010767 DisplayContent displayContent = mDisplayContents.get(displayId);
10768 if (displayContent == null) {
Jeff Brownbd6e1502012-08-28 03:27:37 -070010769 displayContent = new DisplayContent(mDisplayManager.getDisplay(displayId));
Craig Mautner59c00972012-07-30 12:10:24 -070010770 mDisplayContents.put(displayId, displayContent);
10771 }
10772 return displayContent;
10773 }
10774
10775 class DisplayContentsIterator implements Iterator<DisplayContent> {
10776 private int cur;
10777
10778 @Override
10779 public boolean hasNext() {
10780 return cur < mDisplayContents.size();
10781 }
10782
10783 @Override
10784 public DisplayContent next() {
10785 if (hasNext()) {
10786 return mDisplayContents.valueAt(cur++);
10787 }
10788 throw new NoSuchElementException();
10789 }
10790
10791 @Override
10792 public void remove() {
10793 throw new IllegalArgumentException("AllDisplayContentIterator.remove not implemented");
10794 }
10795 }
10796
Jeff Brown83d616a2012-09-09 20:33:43 -070010797 final static boolean REVERSE_ITERATOR = true;
Craig Mautner59c00972012-07-30 12:10:24 -070010798 class AllWindowsIterator implements Iterator<WindowState> {
10799 private DisplayContent mDisplayContent;
10800 private DisplayContentsIterator mDisplayContentsIterator;
10801 private WindowList mWindowList;
10802 private int mWindowListIndex;
10803 private boolean mReverse;
10804
10805 AllWindowsIterator() {
10806 mDisplayContentsIterator = new DisplayContentsIterator();
10807 mDisplayContent = mDisplayContentsIterator.next();
10808 mWindowList = mDisplayContent.getWindowList();
10809 }
10810
10811 AllWindowsIterator(boolean reverse) {
10812 this();
10813 mReverse = reverse;
10814 mWindowListIndex = reverse ? mWindowList.size() - 1 : 0;
10815 }
10816
10817 @Override
10818 public boolean hasNext() {
10819 if (mReverse) {
10820 return mWindowListIndex >= 0;
10821 }
10822 return mWindowListIndex < mWindowList.size();
10823 }
10824
10825 @Override
10826 public WindowState next() {
10827 if (hasNext()) {
10828 WindowState win = mWindowList.get(mWindowListIndex);
10829 if (mReverse) {
10830 mWindowListIndex--;
10831 if (mWindowListIndex < 0 && mDisplayContentsIterator.hasNext()) {
10832 mDisplayContent = mDisplayContentsIterator.next();
10833 mWindowList = mDisplayContent.getWindowList();
10834 mWindowListIndex = mWindowList.size() - 1;
10835 }
10836 } else {
10837 mWindowListIndex++;
Craig Mautnerb47bbc32012-08-22 17:41:48 -070010838 if (mWindowListIndex >= mWindowList.size()
10839 && mDisplayContentsIterator.hasNext()) {
Craig Mautner59c00972012-07-30 12:10:24 -070010840 mDisplayContent = mDisplayContentsIterator.next();
10841 mWindowList = mDisplayContent.getWindowList();
10842 mWindowListIndex = 0;
10843 }
10844 }
10845 return win;
10846 }
10847 throw new NoSuchElementException();
10848 }
10849
10850 @Override
10851 public void remove() {
10852 throw new IllegalArgumentException("AllWindowsIterator.remove not implemented");
10853 }
10854 }
10855
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010856 public DisplayContent getDefaultDisplayContentLocked() {
10857 return getDisplayContentLocked(Display.DEFAULT_DISPLAY);
Craig Mautner59c00972012-07-30 12:10:24 -070010858 }
10859
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010860 public WindowList getDefaultWindowListLocked() {
10861 return getDefaultDisplayContentLocked().getWindowList();
Craig Mautner59c00972012-07-30 12:10:24 -070010862 }
10863
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010864 public DisplayInfo getDefaultDisplayInfoLocked() {
10865 return getDefaultDisplayContentLocked().getDisplayInfo();
Craig Mautner59c00972012-07-30 12:10:24 -070010866 }
10867
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010868 public WindowList getWindowListLocked(final Display display) {
10869 return getDisplayContentLocked(display.getDisplayId()).getWindowList();
Craig Mautner39834192012-09-02 07:47:24 -070010870 }
Craig Mautner722285e2012-09-07 13:55:58 -070010871
10872 @Override
10873 public void onDisplayAdded(int displayId) {
10874 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_ADDED, displayId, 0));
10875 }
10876
10877 private void handleDisplayAddedLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010878 createDisplayContentLocked(mDisplayManager.getDisplay(displayId));
Craig Mautnera91f9e22012-09-14 16:22:08 -070010879 displayReady(displayId);
Craig Mautner722285e2012-09-07 13:55:58 -070010880 }
10881
10882 @Override
10883 public void onDisplayRemoved(int displayId) {
10884 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_REMOVED, displayId, 0));
10885 }
10886
10887 private void handleDisplayRemovedLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010888 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner722285e2012-09-07 13:55:58 -070010889 mDisplayContents.delete(displayId);
10890 WindowList windows = displayContent.getWindowList();
Jeff Browncb882f92012-10-02 16:35:35 -070010891 while (!windows.isEmpty()) {
10892 final WindowState win = windows.get(windows.size() - 1);
Craig Mautner722285e2012-09-07 13:55:58 -070010893 removeWindowLocked(win.mSession, win);
10894 }
Craig Mautnera91f9e22012-09-14 16:22:08 -070010895 mAnimator.removeDisplayLocked(displayId);
Craig Mautner722285e2012-09-07 13:55:58 -070010896 }
10897
10898 @Override
10899 public void onDisplayChanged(int displayId) {
10900 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_CHANGED, displayId, 0));
10901 }
10902
10903 private void handleDisplayChangedLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010904 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner722285e2012-09-07 13:55:58 -070010905 if (displayContent != null) {
10906 displayContent.updateDisplayInfo();
10907 }
10908 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010909}