blob: 680ae4c0ab3314fd6fe3d58b32d0c6103359994d [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;
Dianne Hackborn5fd21692011-06-07 14:09:47 -070021import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
23import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
25import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070026import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
28import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
30import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Daniel Sandler7d276c32012-01-30 14:33:52 -050031import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
33import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070034import static android.view.WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070035import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036
37import com.android.internal.app.IBatteryStats;
38import com.android.internal.policy.PolicyManager;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080039import com.android.internal.policy.impl.PhoneWindowManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import com.android.internal.view.IInputContext;
41import com.android.internal.view.IInputMethodClient;
42import com.android.internal.view.IInputMethodManager;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080043import com.android.internal.view.WindowManagerPolicyThread;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080044import com.android.server.AttributeCache;
45import com.android.server.EventLogTags;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080046import com.android.server.Watchdog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047import com.android.server.am.BatteryStatsService;
Jeff Brownfa25bf52012-07-23 19:26:30 -070048import com.android.server.display.DisplayDeviceInfo;
49import com.android.server.display.DisplayManagerService;
Jeff Brown4532e612012-04-05 14:27:12 -070050import com.android.server.input.InputManagerService;
Jeff Brown4f8ecd82012-06-18 18:29:13 -070051import com.android.server.power.PowerManagerService;
52import com.android.server.power.ShutdownThread;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053
54import android.Manifest;
55import android.app.ActivityManagerNative;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070056import android.app.ActivityOptions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.app.IActivityManager;
Joe Onoratoac0ee892011-01-30 15:38:30 -080058import android.app.StatusBarManager;
Jim Millerd6b57052010-06-07 17:52:42 -070059import android.app.admin.DevicePolicyManager;
Jim Miller284b62e2010-06-08 14:27:42 -070060import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.content.Context;
Jim Miller284b62e2010-06-08 14:27:42 -070062import android.content.Intent;
63import android.content.IntentFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import android.content.pm.ActivityInfo;
65import android.content.pm.PackageManager;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070066import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import android.content.res.Configuration;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080068import android.graphics.Bitmap;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070069import android.graphics.Canvas;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070import android.graphics.Matrix;
71import android.graphics.PixelFormat;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -070072import android.graphics.Point;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.graphics.Rect;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070074import android.graphics.RectF;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.graphics.Region;
76import android.os.BatteryStats;
77import android.os.Binder;
Dianne Hackborn75804932009-10-20 20:15:20 -070078import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079import android.os.Debug;
80import android.os.Handler;
81import android.os.IBinder;
Dianne Hackborn38e29a62011-09-18 14:43:08 -070082import android.os.IRemoteCallback;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083import android.os.Looper;
84import android.os.Message;
85import android.os.Parcel;
86import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087import android.os.PowerManager;
88import android.os.Process;
89import android.os.RemoteException;
90import android.os.ServiceManager;
Brad Fitzpatrickec062f62010-11-03 09:56:54 -070091import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import android.os.SystemClock;
93import android.os.SystemProperties;
94import android.os.TokenWatcher;
Dianne Hackborn1ded0b12012-04-26 14:14:50 -070095import android.os.Trace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096import android.provider.Settings;
Dianne Hackborn723738c2009-06-25 19:48:04 -070097import android.util.DisplayMetrics;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098import android.util.EventLog;
Michael Jurka4accb6a2012-03-26 09:18:46 -070099import android.util.FloatMath;
Jim Millerd6b57052010-06-07 17:52:42 -0700100import android.util.Log;
Craig Mautner59c00972012-07-30 12:10:24 -0700101import android.util.SparseArray;
Craig Mautner711f90a2012-07-03 18:43:52 -0700102//import android.util.LogPrinter;
Dianne Hackborn38e29a62011-09-18 14:43:08 -0700103import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800104import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import android.util.SparseIntArray;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700106import android.util.TypedValue;
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800107import android.view.Choreographer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.view.Display;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700109import android.view.DisplayInfo;
Adam Powelldfee59a2011-08-05 20:48:30 -0700110import android.view.Gravity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111import android.view.IApplicationToken;
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -0700112import android.view.IInputFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113import android.view.IOnKeyguardExitResult;
114import android.view.IRotationWatcher;
115import android.view.IWindow;
116import android.view.IWindowManager;
117import android.view.IWindowSession;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700118import android.view.InputChannel;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700119import android.view.InputDevice;
Jeff Brownbbda99d2010-07-28 15:48:59 -0700120import android.view.InputEvent;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800121import android.view.InputEventReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122import android.view.KeyEvent;
123import android.view.MotionEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124import android.view.Surface;
125import android.view.SurfaceSession;
126import android.view.View;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700127import android.view.ViewTreeObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128import android.view.WindowManager;
129import android.view.WindowManagerImpl;
130import android.view.WindowManagerPolicy;
131import android.view.WindowManager.LayoutParams;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700132import android.view.WindowManagerPolicy.FakeWindow;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700133import android.view.animation.AlphaAnimation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134import android.view.animation.Animation;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700135import android.view.animation.AnimationSet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136import android.view.animation.AnimationUtils;
Michael Jurkac016aaa2012-06-05 17:22:24 -0700137import android.view.animation.DecelerateInterpolator;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700138import android.view.animation.Interpolator;
139import android.view.animation.ScaleAnimation;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700140import android.view.animation.Transformation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141
142import java.io.BufferedWriter;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700143import java.io.DataInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144import java.io.File;
145import java.io.FileDescriptor;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700146import java.io.FileInputStream;
147import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148import java.io.IOException;
149import java.io.OutputStream;
150import java.io.OutputStreamWriter;
151import java.io.PrintWriter;
152import java.io.StringWriter;
153import java.net.Socket;
Jeff Brownd7a04de2012-06-17 14:17:52 -0700154import java.text.DateFormat;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155import java.util.ArrayList;
Jeff Brownd7a04de2012-06-17 14:17:52 -0700156import java.util.Date;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157import java.util.HashMap;
158import java.util.HashSet;
159import java.util.Iterator;
160import java.util.List;
Craig Mautner59c00972012-07-30 12:10:24 -0700161import java.util.NoSuchElementException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162
163/** {@hide} */
Dianne Hackbornddca3ee2009-07-23 19:01:31 -0700164public class WindowManagerService extends IWindowManager.Stub
Jeff Brown4a06c802012-02-15 15:06:01 -0800165 implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 static final String TAG = "WindowManager";
167 static final boolean DEBUG = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700168 static final boolean DEBUG_ADD_REMOVE = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800169 static final boolean DEBUG_FOCUS = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 static final boolean DEBUG_ANIM = false;
Dianne Hackborn9b52a212009-12-11 14:51:35 -0800171 static final boolean DEBUG_LAYOUT = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800172 static final boolean DEBUG_RESIZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800173 static final boolean DEBUG_LAYERS = false;
174 static final boolean DEBUG_INPUT = false;
175 static final boolean DEBUG_INPUT_METHOD = false;
176 static final boolean DEBUG_VISIBILITY = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700177 static final boolean DEBUG_WINDOW_MOVEMENT = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800178 static final boolean DEBUG_TOKEN_MOVEMENT = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179 static final boolean DEBUG_ORIENTATION = false;
Dianne Hackbornbc7386c2011-06-06 17:27:54 -0700180 static final boolean DEBUG_APP_ORIENTATION = false;
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700181 static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 static final boolean DEBUG_APP_TRANSITIONS = false;
183 static final boolean DEBUG_STARTING_WINDOW = false;
184 static final boolean DEBUG_REORDER = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800185 static final boolean DEBUG_WALLPAPER = false;
Christopher Tate994ef922011-01-12 20:06:07 -0800186 static final boolean DEBUG_DRAG = false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700187 static final boolean DEBUG_SCREEN_ON = false;
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -0700188 static final boolean DEBUG_SCREENSHOT = false;
Dianne Hackborn38cc8962011-10-13 11:33:55 -0700189 static final boolean DEBUG_BOOT = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700190 static final boolean DEBUG_LAYOUT_REPEATS = true;
Craig Mautner7358fbf2012-04-12 21:06:33 -0700191 static final boolean DEBUG_SURFACE_TRACE = false;
Craig Mautner7d8df392012-04-06 15:26:23 -0700192 static final boolean DEBUG_WINDOW_TRACE = false;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700193 static final boolean SHOW_SURFACE_ALLOC = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800194 static final boolean SHOW_TRANSACTIONS = false;
Dianne Hackborn36991742011-10-11 21:35:26 -0700195 static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700196 static final boolean HIDE_STACK_CRAWLS = true;
Craig Mautnercf8cbbe2012-03-25 21:54:36 -0700197 static final int LAYOUT_REPEAT_THRESHOLD = 4;
Michael Chan53071d62009-05-13 17:29:48 -0700198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199 static final boolean PROFILE_ORIENTATION = false;
Dave Bortcfe65242009-04-09 14:51:04 -0700200 static final boolean localLOGV = DEBUG;
Romain Guy06882f82009-06-10 13:36:04 -0700201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 /** How much to multiply the policy's type layer, to reserve room
203 * for multiple windows of the same type and Z-ordering adjustment
204 * with TYPE_LAYER_OFFSET. */
205 static final int TYPE_LAYER_MULTIPLIER = 10000;
Romain Guy06882f82009-06-10 13:36:04 -0700206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
208 * or below others in the same layer. */
209 static final int TYPE_LAYER_OFFSET = 1000;
Romain Guy06882f82009-06-10 13:36:04 -0700210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 /** How much to increment the layer for each window, to reserve room
212 * for effect surfaces between them.
213 */
214 static final int WINDOW_LAYER_MULTIPLIER = 5;
Romain Guy06882f82009-06-10 13:36:04 -0700215
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800216 /**
217 * Dim surface layer is immediately below target window.
218 */
219 static final int LAYER_OFFSET_DIM = 1;
220
221 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700222 * Blur surface layer is immediately below dim layer.
223 */
224 static final int LAYER_OFFSET_BLUR = 2;
225
226 /**
227 * Animation thumbnail is as far as possible below the window above
228 * the thumbnail (or in other words as far as possible above the window
229 * below it).
230 */
231 static final int LAYER_OFFSET_THUMBNAIL = WINDOW_LAYER_MULTIPLIER-1;
232
233 /**
Dianne Hackborn7916ac62011-05-16 20:45:48 -0700234 * Layer at which to put the rotation freeze snapshot.
235 */
236 static final int FREEZE_LAYER = (TYPE_LAYER_MULTIPLIER * 200) + 1;
237
238 /**
239 * Layer at which to put the mask for emulated screen sizes.
240 */
241 static final int MASK_LAYER = TYPE_LAYER_MULTIPLIER * 200;
242
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243 /** The maximum length we will accept for a loaded animation duration:
244 * this is 10 seconds.
245 */
246 static final int MAX_ANIMATION_DURATION = 10*1000;
247
248 /** Amount of time (in milliseconds) to animate the dim surface from one
249 * value to another, when no window animation is driving it.
250 */
251 static final int DEFAULT_DIM_DURATION = 200;
252
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700253 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
254 * compatible windows.
255 */
256 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
257
Dianne Hackborna1111872010-11-23 20:55:11 -0800258 /**
259 * If true, the window manager will do its own custom freezing and general
260 * management of the screen during rotation.
261 */
262 static final boolean CUSTOM_SCREEN_ROTATION = true;
263
Jeff Brownb09abc12011-01-13 21:08:27 -0800264 // Maximum number of milliseconds to wait for input devices to be enumerated before
265 // proceding with safe mode detection.
266 private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
Jim Miller28637ba2011-07-06 19:57:05 -0700267
Jeff Brown349703e2010-06-22 01:27:15 -0700268 // Default input dispatching timeout in nanoseconds.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800269 static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
Romain Guy06882f82009-06-10 13:36:04 -0700270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271 static final int UPDATE_FOCUS_NORMAL = 0;
272 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
273 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
274 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700277 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278
279 /**
280 * Condition waited on by {@link #reenableKeyguard} to know the call to
281 * the window policy has finished.
Mike Lockwood983ee092009-11-22 01:42:24 -0500282 * This is set to true only if mKeyguardTokenWatcher.acquired() has
283 * actually disabled the keyguard.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 */
Mike Lockwood983ee092009-11-22 01:42:24 -0500285 private boolean mKeyguardDisabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700287 private final boolean mHeadless;
288
Jim Miller284b62e2010-06-08 14:27:42 -0700289 private static final int ALLOW_DISABLE_YES = 1;
290 private static final int ALLOW_DISABLE_NO = 0;
291 private static final int ALLOW_DISABLE_UNKNOWN = -1; // check with DevicePolicyManager
292 private int mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN; // sync'd by mKeyguardTokenWatcher
293
Michael Jurkac016aaa2012-06-05 17:22:24 -0700294 private static final float THUMBNAIL_ANIMATION_DECELERATE_FACTOR = 1.5f;
295
Mike Lockwood983ee092009-11-22 01:42:24 -0500296 final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher(
297 new Handler(), "WindowManagerService.mKeyguardTokenWatcher") {
Craig Mautner2f995a72012-02-21 09:53:21 -0800298 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299 public void acquired() {
Jim Miller284b62e2010-06-08 14:27:42 -0700300 if (shouldAllowDisableKeyguard()) {
301 mPolicy.enableKeyguard(false);
302 mKeyguardDisabled = true;
303 } else {
304 Log.v(TAG, "Not disabling keyguard since device policy is enforced");
305 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 }
Craig Mautner2f995a72012-02-21 09:53:21 -0800307 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308 public void released() {
Dianne Hackborna33e3f72009-09-29 17:28:24 -0700309 mPolicy.enableKeyguard(true);
Mike Lockwood983ee092009-11-22 01:42:24 -0500310 synchronized (mKeyguardTokenWatcher) {
311 mKeyguardDisabled = false;
312 mKeyguardTokenWatcher.notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 }
314 }
315 };
316
Jim Miller284b62e2010-06-08 14:27:42 -0700317 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
318 @Override
319 public void onReceive(Context context, Intent intent) {
320 mPolicy.enableKeyguard(true);
321 synchronized(mKeyguardTokenWatcher) {
322 // lazily evaluate this next time we're asked to disable keyguard
323 mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
324 mKeyguardDisabled = false;
325 }
326 }
327 };
328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 final Context mContext;
330
331 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700332
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700333 final boolean mAllowBootMessages;
334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
338
339 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700340
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700342
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 /**
344 * All currently active sessions with clients.
345 */
346 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800348 /**
349 * Mapping from an IWindow IBinder to the server's Window object.
350 * This is also used as the lock for all of our state.
351 */
352 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
353
354 /**
355 * Mapping from a token IBinder to a WindowToken object.
356 */
357 final HashMap<IBinder, WindowToken> mTokenMap =
358 new HashMap<IBinder, WindowToken>();
359
360 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800361 * Window tokens that are in the process of exiting, but still
362 * on screen for animations.
363 */
364 final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
365
366 /**
Craig Mautneref25d7a2012-05-15 23:01:47 -0700367 * List controlling the ordering of windows in different applications which must
368 * be kept in sync with ActivityManager.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369 */
Craig Mautnerbec53f72012-04-05 11:49:05 -0700370 final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800371
372 /**
Craig Mautneref25d7a2012-05-15 23:01:47 -0700373 * AppWindowTokens in the Z order they were in at the start of an animation. Between
374 * animations this list is maintained in the exact order of mAppTokens. If tokens
375 * are added to mAppTokens during an animation an attempt is made to insert them at the same
376 * logical location in this list. Note that this list is always in sync with mWindows.
377 */
378 ArrayList<AppWindowToken> mAnimatingAppTokens = new ArrayList<AppWindowToken>();
379
380 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800381 * Application tokens that are in the process of exiting, but still
382 * on screen for animations.
383 */
384 final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
385
386 /**
387 * List of window tokens that have finished starting their application,
388 * and now need to have the policy remove their windows.
389 */
390 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
391
392 /**
Dianne Hackborndf89e652011-10-06 22:35:11 -0700393 * Fake windows added to the window manager. Note: ordered from top to
394 * bottom, opposite of mWindows.
395 */
396 final ArrayList<FakeWindowImpl> mFakeWindows = new ArrayList<FakeWindowImpl>();
397
398 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 * Windows that are being resized. Used so we can tell the client about
400 * the resize after closing the transaction in which we resized the
401 * underlying surface.
402 */
403 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
404
405 /**
406 * Windows whose animations have ended and now must be removed.
407 */
408 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
409
410 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800411 * Used when processing mPendingRemove to avoid working on the original array.
412 */
413 WindowState[] mPendingRemoveTmp = new WindowState[20];
414
415 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 * Windows whose surface should be destroyed.
417 */
418 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
419
420 /**
421 * Windows that have lost input focus and are waiting for the new
422 * focus window to be displayed before they are told about this.
423 */
424 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
425
426 /**
427 * This is set when we have run out of memory, and will either be an empty
428 * list or contain windows that need to be force removed.
429 */
430 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700431
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800432 /**
Dianne Hackborn38e29a62011-09-18 14:43:08 -0700433 * Windows that clients are waiting to have drawn.
434 */
435 ArrayList<Pair<WindowState, IRemoteCallback>> mWaitingForDrawn
436 = new ArrayList<Pair<WindowState, IRemoteCallback>>();
437
438 /**
Dianne Hackborn12d3a942012-04-27 14:16:30 -0700439 * Windows that have called relayout() while we were running animations,
440 * so we need to tell when the animation is done.
441 */
442 final ArrayList<WindowState> mRelayoutWhileAnimating = new ArrayList<WindowState>();
443
444 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800445 * Used when rebuilding window list to keep track of windows that have
446 * been removed.
447 */
448 WindowState[] mRebuildTmp = new WindowState[20];
449
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700451
Craig Mautner7358fbf2012-04-12 21:06:33 -0700452 final SurfaceSession mFxSession;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700453 Watermark mWatermark;
Brad Fitzpatrick68044332010-11-22 18:19:48 -0800454 StrictModeFlash mStrictModeFlash;
Romain Guy06882f82009-06-10 13:36:04 -0700455
Dianne Hackborn7916ac62011-05-16 20:45:48 -0700456 BlackFrame mBlackFrame;
457
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458 final float[] mTmpFloats = new float[9];
459
460 boolean mSafeMode;
461 boolean mDisplayEnabled = false;
462 boolean mSystemBooted = false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700463 boolean mForceDisplayEnabled = false;
Dianne Hackborn661cd522011-08-22 00:26:20 -0700464 boolean mShowingBootMessages = false;
Dianne Hackborn1fbee792011-11-30 11:29:58 -0800465
Jeff Brownd7a04de2012-06-17 14:17:52 -0700466 String mLastANRState;
467
Craig Mautner59c00972012-07-30 12:10:24 -0700468 /** All DisplayDontents in the world, kept here */
469 private SparseArray<DisplayContent> mDisplayContents = new SparseArray<DisplayContent>();
Dianne Hackborn1fbee792011-11-30 11:29:58 -0800470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 int mRotation = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborndacea8c2011-04-21 17:26:39 -0700473 boolean mAltOrientation = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 ArrayList<IRotationWatcher> mRotationWatchers
475 = new ArrayList<IRotationWatcher>();
Jeff Brown01a98dd2011-09-20 15:08:29 -0700476 int mDeferredRotationPauseCount;
Romain Guy06882f82009-06-10 13:36:04 -0700477
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700478 final Rect mSystemDecorRect = new Rect();
479 int mSystemDecorLayer = 0;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700480 final Rect mScreenRect = new Rect();
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700481
Craig Mautnere32c3072012-03-12 15:25:35 -0700482 int mPendingLayoutChanges = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800483 boolean mLayoutNeeded = true;
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800484 boolean mTraversalScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 boolean mDisplayFrozen = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800486 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800487 boolean mWindowsFreezingScreen = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488 int mAppsFreezingScreen = 0;
Dianne Hackbornbc7386c2011-06-06 17:27:54 -0700489 int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800491 int mLayoutSeq = 0;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700492
493 int mLastStatusBarVisibility = 0;
494
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800495 // State while inside of layoutAndPlaceSurfacesLocked().
496 boolean mFocusMayChange;
Craig Mautner01cd0e72012-06-18 10:19:11 -0700497
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800498 Configuration mCurConfiguration = new Configuration();
Craig Mautner01cd0e72012-06-18 10:19:11 -0700499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800500 // This is held as long as we have the screen frozen, to give us time to
501 // perform a rotation animation when turning off shows the lock screen which
502 // changes the orientation.
503 PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700504
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800505 // State management of app transitions. When we are preparing for a
506 // transition, mNextAppTransition will be the kind of transition to
507 // perform or TRANSIT_NONE if we are not waiting. If we are waiting,
508 // mOpeningApps and mClosingApps are the lists of tokens that will be
509 // made visible or hidden at the next transition.
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700510 int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700511 int mNextAppTransitionType = ActivityOptions.ANIM_NONE;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700512 String mNextAppTransitionPackage;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700513 Bitmap mNextAppTransitionThumbnail;
Michael Jurka21385cd2012-05-03 10:57:31 -0700514 boolean mNextAppTransitionDelayed;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700515 IRemoteCallback mNextAppTransitionCallback;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700516 int mNextAppTransitionEnter;
517 int mNextAppTransitionExit;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700518 int mNextAppTransitionStartX;
519 int mNextAppTransitionStartY;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700520 int mNextAppTransitionStartWidth;
521 int mNextAppTransitionStartHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800522 boolean mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -0700523 boolean mAppTransitionRunning = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524 boolean mAppTransitionTimeout = false;
525 boolean mStartingIconInTransition = false;
526 boolean mSkipAppTransitionAnimation = false;
527 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
528 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700529
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530 Display mDisplay;
Romain Guy06882f82009-06-10 13:36:04 -0700531
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700532 boolean mIsTouchDevice;
533
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700534 final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Jeff Brownbc68a592011-07-25 12:58:12 -0700535 final DisplayMetrics mRealDisplayMetrics = new DisplayMetrics();
Dianne Hackborn48a76512011-06-08 21:51:44 -0700536 final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics();
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700537 final DisplayMetrics mCompatDisplayMetrics = new DisplayMetrics();
538
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800539 final H mH = new H();
540
541 final Choreographer mChoreographer = Choreographer.getInstance();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542
543 WindowState mCurrentFocus = null;
544 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700545
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800546 /** This just indicates the window the input method is on top of, not
547 * necessarily the window its input is going to. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800548 WindowState mInputMethodTarget = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800549
550 /** If true hold off on modifying the animation layer of mInputMethodTarget */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800551 boolean mInputMethodTargetWaitingAnim;
552 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554 WindowState mInputMethodWindow = null;
555 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
556
Jeff Brown2992ea72011-01-28 22:04:14 -0800557 boolean mHardKeyboardAvailable;
558 boolean mHardKeyboardEnabled;
559 OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
560
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700561 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800562
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700563 // If non-null, this is the currently visible window that is associated
564 // with the wallpaper.
565 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700566 // If non-null, we are in the middle of animating from one wallpaper target
567 // to another, and this is the lower one in Z-order.
Craig Mautner918b53b2012-07-09 14:15:54 -0700568 private WindowState mLowerWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700569 // If non-null, we are in the middle of animating from one wallpaper target
570 // to another, and this is the higher one in Z-order.
Craig Mautner918b53b2012-07-09 14:15:54 -0700571 private WindowState mUpperWallpaperTarget = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700572 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700573 float mLastWallpaperX = -1;
574 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800575 float mLastWallpaperXStep = -1;
576 float mLastWallpaperYStep = -1;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700577 // This is set when we are waiting for a wallpaper to tell us it is done
578 // changing its scroll position.
579 WindowState mWaitingOnWallpaper;
580 // The last time we had a timeout when waiting for a wallpaper.
581 long mLastWallpaperTimeoutTime;
582 // We give a wallpaper up to 150ms to finish scrolling.
583 static final long WALLPAPER_TIMEOUT = 150;
584 // Time we wait after a timeout before trying to wait again.
585 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 AppWindowToken mFocusedApp = null;
588
589 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700590
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800591 float mWindowAnimationScale = 1.0f;
592 float mTransitionAnimationScale = 1.0f;
Chet Haasec38fa1f2012-02-01 16:37:46 -0800593 float mAnimatorDurationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700594
Jeff Brown4532e612012-04-05 14:27:12 -0700595 final InputManagerService mInputManager;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700596 final DisplayManagerService mDisplayManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597
598 // Who is holding the screen on.
599 Session mHoldingScreenOn;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700600 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700601
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700602 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800603
Christopher Tatea53146c2010-09-07 11:57:52 -0700604 DragState mDragState = null;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800605
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800606 /** Pulled out of performLayoutAndPlaceSurfacesLockedInner in order to refactor into multiple
607 * methods. */
Craig Mautnera608b882012-03-30 13:03:49 -0700608 class LayoutFields {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700609 static final int SET_UPDATE_ROTATION = 1 << 0;
610 static final int SET_WALLPAPER_MAY_CHANGE = 1 << 1;
611 static final int SET_FORCE_HIDING_CHANGED = 1 << 2;
Craig Mautner2639da52012-07-09 09:39:06 -0700612 static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3;
Craig Mautner7d8df392012-04-06 15:26:23 -0700613 static final int SET_TURN_ON_SCREEN = 1 << 4;
Craig Mautnera608b882012-03-30 13:03:49 -0700614
Craig Mautner764983d2012-03-22 11:37:36 -0700615 boolean mWallpaperForceHidingChanged = false;
616 boolean mWallpaperMayChange = false;
Craig Mautner764983d2012-03-22 11:37:36 -0700617 boolean mOrientationChangeComplete = true;
Craig Mautnere7ae2502012-03-26 17:11:19 -0700618 int mAdjResult = 0;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800619 private Session mHoldScreen = null;
620 private boolean mObscured = false;
Craig Mautner764983d2012-03-22 11:37:36 -0700621 boolean mDimming = false;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800622 private boolean mSyswin = false;
623 private float mScreenBrightness = -1;
624 private float mButtonBrightness = -1;
Craig Mautnera608b882012-03-30 13:03:49 -0700625 private boolean mUpdateRotation = false;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800626 }
Craig Mautner01cd0e72012-06-18 10:19:11 -0700627 final LayoutFields mInnerFields = new LayoutFields();
628
Craig Mautner322e4032012-07-13 13:35:20 -0700629 static class AppWindowAnimParams {
630 AppWindowAnimator mAppAnimator;
631 ArrayList<WindowStateAnimator> mWinAnimators;
632
633 public AppWindowAnimParams(final AppWindowAnimator appAnimator) {
634 mAppAnimator = appAnimator;
635
636 final AppWindowToken wtoken = appAnimator.mAppToken;
637 mWinAnimators = new ArrayList<WindowStateAnimator>();
638 final int N = wtoken.allAppWindows.size();
639 for (int i = 0; i < N; i++) {
640 mWinAnimators.add(wtoken.allAppWindows.get(i).mWinAnimator);
641 }
642 }
643 }
644
Craig Mautner711f90a2012-07-03 18:43:52 -0700645 static class LayoutToAnimatorParams {
Craig Mautner322e4032012-07-13 13:35:20 -0700646 boolean mParamsModified;
647
Craig Mautner918b53b2012-07-09 14:15:54 -0700648 static final long WALLPAPER_TOKENS_CHANGED = 1 << 0;
649 long mChanges;
650
Craig Mautner711f90a2012-07-03 18:43:52 -0700651 boolean mAnimationScheduled;
Craig Mautner59c00972012-07-30 12:10:24 -0700652 ArrayList<WinAnimatorList> mWinAnimatorLists = new ArrayList<WinAnimatorList>();
Craig Mautner711f90a2012-07-03 18:43:52 -0700653 WindowState mWallpaperTarget;
Craig Mautner918b53b2012-07-09 14:15:54 -0700654 WindowState mLowerWallpaperTarget;
655 WindowState mUpperWallpaperTarget;
Craig Mautner711f90a2012-07-03 18:43:52 -0700656 DimAnimator.Parameters mDimParams;
Craig Mautner918b53b2012-07-09 14:15:54 -0700657 ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Craig Mautner322e4032012-07-13 13:35:20 -0700658 ArrayList<AppWindowAnimParams> mAppWindowAnimParams = new ArrayList<AppWindowAnimParams>();
Craig Mautner711f90a2012-07-03 18:43:52 -0700659 }
Craig Mautner918b53b2012-07-09 14:15:54 -0700660 /** Params from WindowManagerService to WindowAnimator. Do not modify or read without first
661 * locking on either mWindowMap or mAnimator and then on mLayoutToAnim */
Craig Mautner711f90a2012-07-03 18:43:52 -0700662 final LayoutToAnimatorParams mLayoutToAnim = new LayoutToAnimatorParams();
Craig Mautner01cd0e72012-06-18 10:19:11 -0700663
664 /** The lowest wallpaper target with a detached wallpaper animation on it. */
665 WindowState mWindowDetachedWallpaper = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800666
Craig Mautner6fbda632012-07-03 09:26:39 -0700667 /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
668 * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
669 private int mTransactionSequence;
670
Craig Mautnerbb1449b2012-03-23 16:11:14 -0700671 /** Only do a maximum of 6 repeated layouts. After that quit */
672 private int mLayoutRepeatCount;
673
Craig Mautner764983d2012-03-22 11:37:36 -0700674 final WindowAnimator mAnimator;
Jeff Brown4a06c802012-02-15 15:06:01 -0800675
Jeff Brown32cbc38552011-12-01 14:01:49 -0800676 final class DragInputEventReceiver extends InputEventReceiver {
677 public DragInputEventReceiver(InputChannel inputChannel, Looper looper) {
678 super(inputChannel, looper);
679 }
680
Christopher Tatea53146c2010-09-07 11:57:52 -0700681 @Override
Jeff Brown32cbc38552011-12-01 14:01:49 -0800682 public void onInputEvent(InputEvent event) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700683 boolean handled = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700684 try {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800685 if (event instanceof MotionEvent
686 && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
Jeff Brown3915bb82010-11-05 15:02:16 -0700687 && mDragState != null) {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800688 final MotionEvent motionEvent = (MotionEvent)event;
Jeff Brown3915bb82010-11-05 15:02:16 -0700689 boolean endDrag = false;
Jeff Brown4952dfd2011-11-30 19:23:22 -0800690 final float newX = motionEvent.getRawX();
691 final float newY = motionEvent.getRawY();
Jeff Brown3915bb82010-11-05 15:02:16 -0700692
Jeff Brown4952dfd2011-11-30 19:23:22 -0800693 switch (motionEvent.getAction()) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700694 case MotionEvent.ACTION_DOWN: {
695 if (DEBUG_DRAG) {
696 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
697 }
698 } break;
699
700 case MotionEvent.ACTION_MOVE: {
701 synchronized (mWindowMap) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700702 // move the surface and tell the involved window(s) where we are
Christopher Tatea53146c2010-09-07 11:57:52 -0700703 mDragState.notifyMoveLw(newX, newY);
704 }
705 } break;
706
707 case MotionEvent.ACTION_UP: {
708 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
709 + newX + "," + newY);
710 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700711 endDrag = mDragState.notifyDropLw(newX, newY);
Christopher Tatea53146c2010-09-07 11:57:52 -0700712 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700713 } break;
714
715 case MotionEvent.ACTION_CANCEL: {
716 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
717 endDrag = true;
718 } break;
719 }
720
721 if (endDrag) {
722 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
723 // tell all the windows that the drag has ended
Chris Tate59943592010-10-11 20:33:44 -0700724 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700725 mDragState.endDragLw();
Chris Tate59943592010-10-11 20:33:44 -0700726 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700727 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700728
729 handled = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700730 }
731 } catch (Exception e) {
732 Slog.e(TAG, "Exception caught by drag handleMotion", e);
733 } finally {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800734 finishInputEvent(event, handled);
Christopher Tatea53146c2010-09-07 11:57:52 -0700735 }
736 }
Jeff Brown32cbc38552011-12-01 14:01:49 -0800737 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700738
739 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800740 * Whether the UI is currently running in touch mode (not showing
741 * navigational focus because the user is directly pressing the screen).
742 */
Michael Jurkae99adc72011-08-11 18:28:01 -0700743 boolean mInTouchMode = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800744
745 private ViewServer mViewServer;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700746 private ArrayList<WindowChangeListener> mWindowChangeListeners =
747 new ArrayList<WindowChangeListener>();
748 private boolean mWindowsChanged = false;
749
750 public interface WindowChangeListener {
751 public void windowsChanged();
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -0700752 public void focusChanged();
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700753 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754
Dianne Hackbornc485a602009-03-24 22:39:49 -0700755 final Configuration mTempConfiguration = new Configuration();
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700756
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700757 // The desired scaling factor for compatible apps.
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400758 float mCompatibleScreenScale;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700759
Jeff Brown780c46f2012-06-24 12:15:38 -0700760 // If true, only the core apps and services are being launched because the device
761 // is in a special boot mode, such as being encrypted or waiting for a decryption password.
762 // For example, when this flag is true, there will be no wallpaper service.
763 final boolean mOnlyCore;
764
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800765 public static WindowManagerService main(Context context,
Jeff Brownfa25bf52012-07-23 19:26:30 -0700766 PowerManagerService pm, DisplayManagerService dm,
767 boolean haveInputMethods, boolean allowBootMsgs,
Jeff Brown780c46f2012-06-24 12:15:38 -0700768 boolean onlyCore) {
Jeff Brownfa25bf52012-07-23 19:26:30 -0700769 WMThread thr = new WMThread(context, pm, dm, haveInputMethods, allowBootMsgs, onlyCore);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800770 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700771
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800772 synchronized (thr) {
773 while (thr.mService == null) {
774 try {
775 thr.wait();
776 } catch (InterruptedException e) {
777 }
778 }
Jozef BABJAK06e57b52011-01-20 08:09:25 +0100779 return thr.mService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800780 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800781 }
Romain Guy06882f82009-06-10 13:36:04 -0700782
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800783 static class WMThread extends Thread {
784 WindowManagerService mService;
Romain Guy06882f82009-06-10 13:36:04 -0700785
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800786 private final Context mContext;
787 private final PowerManagerService mPM;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700788 private final DisplayManagerService mDisplayManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800789 private final boolean mHaveInputMethods;
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700790 private final boolean mAllowBootMessages;
Jeff Brown780c46f2012-06-24 12:15:38 -0700791 private final boolean mOnlyCore;
Romain Guy06882f82009-06-10 13:36:04 -0700792
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800793 public WMThread(Context context, PowerManagerService pm,
Jeff Brownfa25bf52012-07-23 19:26:30 -0700794 DisplayManagerService dm,
Jeff Brown780c46f2012-06-24 12:15:38 -0700795 boolean haveInputMethods, boolean allowBootMsgs, boolean onlyCore) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800796 super("WindowManager");
797 mContext = context;
798 mPM = pm;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700799 mDisplayManager = dm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800800 mHaveInputMethods = haveInputMethods;
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700801 mAllowBootMessages = allowBootMsgs;
Jeff Brown780c46f2012-06-24 12:15:38 -0700802 mOnlyCore = onlyCore;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800803 }
Romain Guy06882f82009-06-10 13:36:04 -0700804
Craig Mautner2fb98b12012-03-20 17:24:00 -0700805 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800806 public void run() {
807 Looper.prepare();
Craig Mautner6fbda632012-07-03 09:26:39 -0700808 //Looper.myLooper().setMessageLogging(new LogPrinter(
809 // android.util.Log.DEBUG, TAG, android.util.Log.LOG_ID_SYSTEM));
Jeff Brownfa25bf52012-07-23 19:26:30 -0700810 WindowManagerService s = new WindowManagerService(mContext, mPM, mDisplayManager,
Jeff Brown780c46f2012-06-24 12:15:38 -0700811 mHaveInputMethods, mAllowBootMessages, mOnlyCore);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800812 android.os.Process.setThreadPriority(
813 android.os.Process.THREAD_PRIORITY_DISPLAY);
Christopher Tate160edb32010-06-30 17:46:30 -0700814 android.os.Process.setCanSelfBackground(false);
Romain Guy06882f82009-06-10 13:36:04 -0700815
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800816 synchronized (this) {
817 mService = s;
818 notifyAll();
819 }
Romain Guy06882f82009-06-10 13:36:04 -0700820
Brad Fitzpatrickec062f62010-11-03 09:56:54 -0700821 // For debug builds, log event loop stalls to dropbox for analysis.
822 if (StrictMode.conditionallyEnableDebugLogging()) {
823 Slog.i(TAG, "Enabled StrictMode logging for WMThread's Looper");
824 }
825
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800826 Looper.loop();
827 }
828 }
829
830 static class PolicyThread extends Thread {
831 private final WindowManagerPolicy mPolicy;
832 private final WindowManagerService mService;
833 private final Context mContext;
834 private final PowerManagerService mPM;
835 boolean mRunning = false;
Romain Guy06882f82009-06-10 13:36:04 -0700836
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800837 public PolicyThread(WindowManagerPolicy policy,
838 WindowManagerService service, Context context,
839 PowerManagerService pm) {
840 super("WindowManagerPolicy");
841 mPolicy = policy;
842 mService = service;
843 mContext = context;
844 mPM = pm;
845 }
Romain Guy06882f82009-06-10 13:36:04 -0700846
Craig Mautner2fb98b12012-03-20 17:24:00 -0700847 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800848 public void run() {
849 Looper.prepare();
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800850 WindowManagerPolicyThread.set(this, Looper.myLooper());
Craig Mautner711f90a2012-07-03 18:43:52 -0700851
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800852 //Looper.myLooper().setMessageLogging(new LogPrinter(
Joe Onorato8a9b2202010-02-26 18:56:32 -0800853 // Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800854 android.os.Process.setThreadPriority(
Jim Miller54dbbce2012-01-23 15:24:42 -0800855 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -0700856 android.os.Process.setCanSelfBackground(false);
Dianne Hackborndf89e652011-10-06 22:35:11 -0700857 mPolicy.init(mContext, mService, mService, mPM);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700858 mService.mAnimator.mAboveUniverseLayer = mPolicy.getAboveUniverseLayer()
859 * TYPE_LAYER_MULTIPLIER
860 + TYPE_LAYER_OFFSET;
Romain Guy06882f82009-06-10 13:36:04 -0700861
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800862 synchronized (this) {
863 mRunning = true;
864 notifyAll();
865 }
Romain Guy06882f82009-06-10 13:36:04 -0700866
Brad Fitzpatrickec062f62010-11-03 09:56:54 -0700867 // For debug builds, log event loop stalls to dropbox for analysis.
868 if (StrictMode.conditionallyEnableDebugLogging()) {
869 Slog.i(TAG, "Enabled StrictMode for PolicyThread's Looper");
870 }
871
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800872 Looper.loop();
873 }
874 }
875
876 private WindowManagerService(Context context, PowerManagerService pm,
Jeff Brownfa25bf52012-07-23 19:26:30 -0700877 DisplayManagerService displayManager,
Jeff Brown780c46f2012-06-24 12:15:38 -0700878 boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800879 mContext = context;
880 mHaveInputMethods = haveInputMethods;
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700881 mAllowBootMessages = showBootMsgs;
Jeff Brown780c46f2012-06-24 12:15:38 -0700882 mOnlyCore = onlyCore;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800883 mLimitedAlphaCompositing = context.getResources().getBoolean(
884 com.android.internal.R.bool.config_sf_limitedAlpha);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700885 mDisplayManager = displayManager;
886 mHeadless = displayManager.isHeadless();
Romain Guy06882f82009-06-10 13:36:04 -0700887
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800888 mPowerManager = pm;
889 mPowerManager.setPolicy(mPolicy);
890 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
891 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
892 "SCREEN_FROZEN");
893 mScreenFrozenLock.setReferenceCounted(false);
894
895 mActivityManager = ActivityManagerNative.getDefault();
896 mBatteryStats = BatteryStatsService.getService();
897
898 // Get persisted window scale setting
899 mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
900 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
901 mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
902 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Chet Haasec38fa1f2012-02-01 16:37:46 -0800903 mAnimatorDurationScale = Settings.System.getFloat(context.getContentResolver(),
904 Settings.System.ANIMATOR_DURATION_SCALE, mTransitionAnimationScale);
Romain Guy06882f82009-06-10 13:36:04 -0700905
Jim Miller284b62e2010-06-08 14:27:42 -0700906 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
907 IntentFilter filter = new IntentFilter();
908 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
909 mContext.registerReceiver(mBroadcastReceiver, filter);
910
Dianne Hackbornb80395c2012-06-14 19:38:20 -0700911 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
912 | PowerManager.ON_AFTER_RELEASE, "KEEP_SCREEN_ON_FLAG");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700913 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800914
Jeff Brown4532e612012-04-05 14:27:12 -0700915 mInputManager = new InputManagerService(context, mInputMonitor);
Craig Mautner9e809442012-06-22 17:13:04 -0700916 mFxSession = new SurfaceSession();
Craig Mautner918b53b2012-07-09 14:15:54 -0700917 mAnimator = new WindowAnimator(this);
Romain Guy06882f82009-06-10 13:36:04 -0700918
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
920 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700921
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800922 synchronized (thr) {
923 while (!thr.mRunning) {
924 try {
925 thr.wait();
926 } catch (InterruptedException e) {
927 }
928 }
929 }
Romain Guy06882f82009-06-10 13:36:04 -0700930
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700931 mInputManager.start();
Romain Guy06882f82009-06-10 13:36:04 -0700932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 // Add ourself to the Watchdog monitors.
934 Watchdog.getInstance().addMonitor(this);
Craig Mautner7358fbf2012-04-12 21:06:33 -0700935
936 Surface.openTransaction();
937 createWatermark();
938 Surface.closeTransaction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800939 }
940
Jeff Brown4532e612012-04-05 14:27:12 -0700941 public InputManagerService getInputManagerService() {
942 return mInputManager;
943 }
944
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800945 @Override
946 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
947 throws RemoteException {
948 try {
949 return super.onTransact(code, data, reply, flags);
950 } catch (RuntimeException e) {
951 // The window manager only throws security exceptions, so let's
952 // log all others.
953 if (!(e instanceof SecurityException)) {
Dianne Hackborn89620282011-09-11 12:47:45 -0700954 Log.wtf(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800955 }
956 throw e;
957 }
958 }
959
Jeff Browne33348b2010-07-15 23:54:05 -0700960 private void placeWindowAfter(WindowState pos, WindowState window) {
Craig Mautner59c00972012-07-30 12:10:24 -0700961 final WindowList windows = pos.getWindowList();
962 final int i = windows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800963 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800964 TAG, "Adding window " + window + " at "
Craig Mautner59c00972012-07-30 12:10:24 -0700965 + (i+1) + " of " + windows.size() + " (after " + pos + ")");
966 windows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700967 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800968 }
969
Jeff Browne33348b2010-07-15 23:54:05 -0700970 private void placeWindowBefore(WindowState pos, WindowState window) {
Craig Mautner59c00972012-07-30 12:10:24 -0700971 final WindowList windows = pos.getWindowList();
972 final int i = windows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800973 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 TAG, "Adding window " + window + " at "
Craig Mautner59c00972012-07-30 12:10:24 -0700975 + i + " of " + windows.size() + " (before " + pos + ")");
976 windows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700977 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800978 }
979
980 //This method finds out the index of a window that has the same app token as
981 //win. used for z ordering the windows in mWindows
982 private int findIdxBasedOnAppTokens(WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -0700983 WindowList windows = win.getWindowList();
984 for(int j = windows.size() - 1; j >= 0; j--) {
985 WindowState wentry = windows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800986 if(wentry.mAppToken == win.mAppToken) {
987 return j;
988 }
989 }
990 return -1;
991 }
Romain Guy06882f82009-06-10 13:36:04 -0700992
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800993 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
994 final IWindow client = win.mClient;
995 final WindowToken token = win.mToken;
Romain Guy06882f82009-06-10 13:36:04 -0700996
Craig Mautner59c00972012-07-30 12:10:24 -0700997 final WindowList windows = win.getWindowList();
998 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800999 final WindowState attached = win.mAttachedWindow;
1000 int i;
1001 if (attached == null) {
1002 int tokenWindowsPos = token.windows.size();
1003 if (token.appWindowToken != null) {
1004 int index = tokenWindowsPos-1;
1005 if (index >= 0) {
1006 // If this application has existing windows, we
1007 // simply place the new window on top of them... but
1008 // keep the starting window on top.
1009 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
1010 // Base windows go behind everything else.
1011 placeWindowBefore(token.windows.get(0), win);
1012 tokenWindowsPos = 0;
1013 } else {
1014 AppWindowToken atoken = win.mAppToken;
1015 if (atoken != null &&
1016 token.windows.get(index) == atoken.startingWindow) {
1017 placeWindowBefore(token.windows.get(index), win);
1018 tokenWindowsPos--;
1019 } else {
1020 int newIdx = findIdxBasedOnAppTokens(win);
1021 if(newIdx != -1) {
Romain Guy06882f82009-06-10 13:36:04 -07001022 //there is a window above this one associated with the same
1023 //apptoken note that the window could be a floating window
1024 //that was created later or a window at the top of the list of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001025 //windows associated with this token.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001026 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
1027 Slog.v(TAG, "Adding window " + win + " at "
1028 + (newIdx+1) + " of " + N);
1029 }
Craig Mautner59c00972012-07-30 12:10:24 -07001030 windows.add(newIdx+1, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001031 mWindowsChanged = true;
Romain Guy06882f82009-06-10 13:36:04 -07001032 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001033 }
1034 }
1035 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001036 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001037 TAG, "Figuring out where to add app window "
1038 + client.asBinder() + " (token=" + token + ")");
1039 // Figure out where the window should go, based on the
1040 // order of applications.
Craig Mautneref25d7a2012-05-15 23:01:47 -07001041 final int NA = mAnimatingAppTokens.size();
Jeff Browne33348b2010-07-15 23:54:05 -07001042 WindowState pos = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001043 for (i=NA-1; i>=0; i--) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07001044 AppWindowToken t = mAnimatingAppTokens.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001045 if (t == token) {
1046 i--;
1047 break;
1048 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001049
Dianne Hackborna8f60182009-09-01 19:01:50 -07001050 // We haven't reached the token yet; if this token
1051 // is not going to the bottom and has windows, we can
1052 // use it as an anchor for when we do reach the token.
1053 if (!t.sendingToBottom && t.windows.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001054 pos = t.windows.get(0);
1055 }
1056 }
1057 // We now know the index into the apps. If we found
1058 // an app window above, that gives us the position; else
1059 // we need to look some more.
1060 if (pos != null) {
1061 // Move behind any windows attached to this one.
Jeff Browne33348b2010-07-15 23:54:05 -07001062 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001063 if (atoken != null) {
1064 final int NC = atoken.windows.size();
1065 if (NC > 0) {
1066 WindowState bottom = atoken.windows.get(0);
1067 if (bottom.mSubLayer < 0) {
1068 pos = bottom;
1069 }
1070 }
1071 }
1072 placeWindowBefore(pos, win);
1073 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -07001074 // Continue looking down until we find the first
1075 // token that has windows.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001076 while (i >= 0) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07001077 AppWindowToken t = mAnimatingAppTokens.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001078 final int NW = t.windows.size();
1079 if (NW > 0) {
1080 pos = t.windows.get(NW-1);
1081 break;
1082 }
1083 i--;
1084 }
1085 if (pos != null) {
1086 // Move in front of any windows attached to this
1087 // one.
Jeff Browne33348b2010-07-15 23:54:05 -07001088 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001089 if (atoken != null) {
1090 final int NC = atoken.windows.size();
1091 if (NC > 0) {
1092 WindowState top = atoken.windows.get(NC-1);
1093 if (top.mSubLayer >= 0) {
1094 pos = top;
1095 }
1096 }
1097 }
1098 placeWindowAfter(pos, win);
1099 } else {
1100 // Just search for the start of this layer.
1101 final int myLayer = win.mBaseLayer;
1102 for (i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07001103 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001104 if (w.mBaseLayer > myLayer) {
1105 break;
1106 }
1107 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001108 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
1109 Slog.v(TAG, "Adding window " + win + " at "
1110 + i + " of " + N);
1111 }
Craig Mautner59c00972012-07-30 12:10:24 -07001112 windows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001113 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001114 }
1115 }
1116 }
1117 } else {
1118 // Figure out where window should go, based on layer.
1119 final int myLayer = win.mBaseLayer;
1120 for (i=N-1; i>=0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07001121 if (windows.get(i).mBaseLayer <= myLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001122 i++;
1123 break;
1124 }
1125 }
1126 if (i < 0) i = 0;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001127 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001128 TAG, "Adding window " + win + " at "
1129 + i + " of " + N);
Craig Mautner59c00972012-07-30 12:10:24 -07001130 windows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001131 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001132 }
Craig Mautner59c00972012-07-30 12:10:24 -07001133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001134 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001135 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001136 token.windows.add(tokenWindowsPos, win);
1137 }
1138
1139 } else {
1140 // Figure out this window's ordering relative to the window
1141 // it is attached to.
1142 final int NA = token.windows.size();
1143 final int sublayer = win.mSubLayer;
1144 int largestSublayer = Integer.MIN_VALUE;
1145 WindowState windowWithLargestSublayer = null;
1146 for (i=0; i<NA; i++) {
1147 WindowState w = token.windows.get(i);
1148 final int wSublayer = w.mSubLayer;
1149 if (wSublayer >= largestSublayer) {
1150 largestSublayer = wSublayer;
1151 windowWithLargestSublayer = w;
1152 }
1153 if (sublayer < 0) {
1154 // For negative sublayers, we go below all windows
1155 // in the same sublayer.
1156 if (wSublayer >= sublayer) {
1157 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001158 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001159 token.windows.add(i, win);
1160 }
Craig Mautner59c00972012-07-30 12:10:24 -07001161 placeWindowBefore(wSublayer >= 0 ? attached : w, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001162 break;
1163 }
1164 } else {
1165 // For positive sublayers, we go above all windows
1166 // in the same sublayer.
1167 if (wSublayer > sublayer) {
1168 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001169 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001170 token.windows.add(i, win);
1171 }
1172 placeWindowBefore(w, win);
1173 break;
1174 }
1175 }
1176 }
1177 if (i >= NA) {
1178 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001179 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001180 token.windows.add(win);
1181 }
1182 if (sublayer < 0) {
1183 placeWindowBefore(attached, win);
1184 } else {
1185 placeWindowAfter(largestSublayer >= 0
1186 ? windowWithLargestSublayer
1187 : attached,
1188 win);
1189 }
1190 }
1191 }
Romain Guy06882f82009-06-10 13:36:04 -07001192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001193 if (win.mAppToken != null && addToToken) {
1194 win.mAppToken.allAppWindows.add(win);
1195 }
1196 }
Romain Guy06882f82009-06-10 13:36:04 -07001197
Craig Mautneref25d7a2012-05-15 23:01:47 -07001198 /** TODO(cmautner): Is this the same as {@link WindowState#canReceiveKeys()} */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001199 static boolean canBeImeTarget(WindowState w) {
1200 final int fl = w.mAttrs.flags
1201 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
Dianne Hackborne75d8722011-01-27 19:37:40 -08001202 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)
1203 || w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
1204 if (DEBUG_INPUT_METHOD) {
1205 Slog.i(TAG, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
1206 if (!w.isVisibleOrAdding()) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07001207 Slog.i(TAG, " mSurface=" + w.mWinAnimator.mSurface
Dianne Hackborne75d8722011-01-27 19:37:40 -08001208 + " relayoutCalled=" + w.mRelayoutCalled + " viewVis=" + w.mViewVisibility
Dianne Hackbornac920872012-05-22 11:49:49 -07001209 + " policyVis=" + w.mPolicyVisibility
1210 + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim
1211 + " attachHid=" + w.mAttachedHidden
Dianne Hackborne75d8722011-01-27 19:37:40 -08001212 + " exiting=" + w.mExiting + " destroying=" + w.mDestroying);
1213 if (w.mAppToken != null) {
1214 Slog.i(TAG, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
1215 }
1216 }
1217 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001218 return w.isVisibleOrAdding();
1219 }
1220 return false;
1221 }
Romain Guy06882f82009-06-10 13:36:04 -07001222
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001223 /**
1224 * Dig through the WindowStates and find the one that the Input Method will target.
1225 * @param willMove
Craig Mautner59c00972012-07-30 12:10:24 -07001226 * @param windows TODO(cmautner):
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001227 * @return The index+1 in mWindows of the discovered target.
1228 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001229 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001230 // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
1231 // same display. Or even when the current IME/target are not on the same screen as the next
1232 // IME/target. For now only look for input windows on the main screen.
1233 WindowList windows = getDefaultWindowList();
1234 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001235 WindowState w = null;
1236 int i = N;
1237 while (i > 0) {
1238 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07001239 w = windows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -07001240
Dianne Hackborne75d8722011-01-27 19:37:40 -08001241 if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG, "Checking window @" + i
1242 + " " + w + " fl=0x" + Integer.toHexString(w.mAttrs.flags));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001243 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001244 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -07001245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001246 // Yet more tricksyness! If this window is a "starting"
1247 // window, we do actually want to be on top of it, but
1248 // it is not -really- where input will go. So if the caller
1249 // is not actually looking to move the IME, look down below
1250 // for a real window to target...
1251 if (!willMove
1252 && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
1253 && i > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001254 WindowState wb = windows.get(i-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001255 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1256 i--;
1257 w = wb;
1258 }
1259 }
1260 break;
1261 }
1262 }
Romain Guy06882f82009-06-10 13:36:04 -07001263
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001264 // Now w is either mWindows[0] or an IME (or null if mWindows is empty).
1265
Dianne Hackborne75d8722011-01-27 19:37:40 -08001266 if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG, "Proposed new IME target: " + w);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001267
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001268 // Now, a special case -- if the last target's window is in the
1269 // process of exiting, and is above the new target, keep on the
1270 // last target to avoid flicker. Consider for example a Dialog with
1271 // the IME shown: when the Dialog is dismissed, we want to keep
1272 // the IME above it until it is completely gone so it doesn't drop
1273 // behind the dialog or its full-screen scrim.
Craig Mautner59c00972012-07-30 12:10:24 -07001274 final WindowState curTarget = mInputMethodTarget;
1275 if (curTarget != null && w != null
1276 && curTarget.isDisplayedLw()
1277 && curTarget.mExiting) {
1278 if (curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
1279 w = curTarget;
1280 i = windows.indexOf(w);
Dianne Hackborne75d8722011-01-27 19:37:40 -08001281 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Current target higher, switching to: " + w);
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001282 }
1283 }
Romain Guy06882f82009-06-10 13:36:04 -07001284
Joe Onorato8a9b2202010-02-26 18:56:32 -08001285 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001286 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -07001287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001288 if (willMove && w != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07001289 AppWindowToken token = curTarget == null ? null : curTarget.mAppToken;
1290 if (token != null) {
Romain Guy06882f82009-06-10 13:36:04 -07001291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001292 // Now some fun for dealing with window animations that
1293 // modify the Z order. We need to look at all windows below
1294 // the current target that are in this app, finding the highest
1295 // visible one in layering.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001296 WindowState highestTarget = null;
1297 int highestPos = 0;
Craig Mautner59431632012-04-04 11:56:44 -07001298 if (token.mAppAnimator.animating || token.mAppAnimator.animation != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07001299 WindowList curWindows = curTarget.getWindowList();
1300 int pos = curWindows.indexOf(curTarget);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001301 while (pos >= 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001302 WindowState win = curWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001303 if (win.mAppToken != token) {
1304 break;
1305 }
1306 if (!win.mRemoved) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001307 if (highestTarget == null || win.mWinAnimator.mAnimLayer >
1308 highestTarget.mWinAnimator.mAnimLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001309 highestTarget = win;
1310 highestPos = pos;
1311 }
1312 }
1313 pos--;
1314 }
1315 }
Romain Guy06882f82009-06-10 13:36:04 -07001316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001317 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001318 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001319 + mNextAppTransition + " " + highestTarget
Craig Mautnera2c77052012-03-26 12:14:43 -07001320 + " animating=" + highestTarget.mWinAnimator.isAnimating()
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001321 + " layer=" + highestTarget.mWinAnimator.mAnimLayer
1322 + " new layer=" + w.mWinAnimator.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001323
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001324 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001325 // If we are currently setting up for an animation,
1326 // hold everything until we can find out what will happen.
1327 mInputMethodTargetWaitingAnim = true;
1328 mInputMethodTarget = highestTarget;
1329 return highestPos + 1;
Craig Mautnera2c77052012-03-26 12:14:43 -07001330 } else if (highestTarget.mWinAnimator.isAnimating() &&
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001331 highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001332 // If the window we are currently targeting is involved
1333 // with an animation, and it is on top of the next target
1334 // we will be over, then hold off on moving until
1335 // that is done.
Dianne Hackborne75d8722011-01-27 19:37:40 -08001336 mInputMethodTargetWaitingAnim = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001337 mInputMethodTarget = highestTarget;
1338 return highestPos + 1;
1339 }
1340 }
1341 }
1342 }
Romain Guy06882f82009-06-10 13:36:04 -07001343
Joe Onorato8a9b2202010-02-26 18:56:32 -08001344 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001345 if (w != null) {
1346 if (willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001347 if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to "
1348 + w + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 mInputMethodTarget = w;
Dianne Hackborne75d8722011-01-27 19:37:40 -08001350 mInputMethodTargetWaitingAnim = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001351 if (w.mAppToken != null) {
Craig Mautner59431632012-04-04 11:56:44 -07001352 setInputMethodAnimLayerAdjustment(w.mAppToken.mAppAnimator.animLayerAdjustment);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001353 } else {
1354 setInputMethodAnimLayerAdjustment(0);
1355 }
1356 }
1357 return i+1;
1358 }
1359 if (willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001360 if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to null."
1361 + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001362 mInputMethodTarget = null;
1363 setInputMethodAnimLayerAdjustment(0);
1364 }
1365 return -1;
1366 }
Romain Guy06882f82009-06-10 13:36:04 -07001367
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001368 void addInputMethodWindowToListLocked(WindowState win) {
1369 int pos = findDesiredInputMethodWindowIndexLocked(true);
1370 if (pos >= 0) {
1371 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001372 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001373 TAG, "Adding input method window " + win + " at " + pos);
Craig Mautner59c00972012-07-30 12:10:24 -07001374 // TODO(multidisplay): IMEs are only supported on the default display.
1375 getDefaultWindowList().add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001376 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001377 moveInputMethodDialogsLocked(pos+1);
1378 return;
1379 }
1380 win.mTargetAppToken = null;
1381 addWindowToListInOrderLocked(win, true);
1382 moveInputMethodDialogsLocked(pos);
1383 }
Romain Guy06882f82009-06-10 13:36:04 -07001384
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001385 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001386 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001387 mInputMethodAnimLayerAdjustment = adj;
1388 WindowState imw = mInputMethodWindow;
1389 if (imw != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001390 imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001391 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001392 + " anim layer: " + imw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001393 int wi = imw.mChildWindows.size();
1394 while (wi > 0) {
1395 wi--;
Jeff Browne33348b2010-07-15 23:54:05 -07001396 WindowState cw = imw.mChildWindows.get(wi);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001397 cw.mWinAnimator.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001398 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001399 + " anim layer: " + cw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001400 }
1401 }
1402 int di = mInputMethodDialogs.size();
1403 while (di > 0) {
1404 di --;
1405 imw = mInputMethodDialogs.get(di);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001406 imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001407 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001408 + " anim layer: " + imw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001409 }
1410 }
Romain Guy06882f82009-06-10 13:36:04 -07001411
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001412 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -07001413 WindowList windows = win.getWindowList();
1414 int wpos = windows.indexOf(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001415 if (wpos >= 0) {
1416 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001417 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
Craig Mautner59c00972012-07-30 12:10:24 -07001418 windows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001419 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001420 int NC = win.mChildWindows.size();
1421 while (NC > 0) {
1422 NC--;
Jeff Browne33348b2010-07-15 23:54:05 -07001423 WindowState cw = win.mChildWindows.get(NC);
Craig Mautner59c00972012-07-30 12:10:24 -07001424 int cpos = windows.indexOf(cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001425 if (cpos >= 0) {
1426 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001427 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001428 + cpos + ": " + cw);
Craig Mautner59c00972012-07-30 12:10:24 -07001429 windows.remove(cpos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001430 }
1431 }
1432 }
1433 return interestingPos;
1434 }
Romain Guy06882f82009-06-10 13:36:04 -07001435
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001436 private void reAddWindowToListInOrderLocked(WindowState win) {
1437 addWindowToListInOrderLocked(win, false);
1438 // This is a hack to get all of the child windows added as well
1439 // at the right position. Child windows should be rare and
1440 // this case should be rare, so it shouldn't be that big a deal.
Craig Mautner59c00972012-07-30 12:10:24 -07001441 WindowList windows = win.getWindowList();
1442 int wpos = windows.indexOf(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001443 if (wpos >= 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001444 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos + ": " + win);
1445 windows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001446 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001447 reAddWindowLocked(wpos, win);
1448 }
1449 }
Romain Guy06882f82009-06-10 13:36:04 -07001450
Craig Mautner59c00972012-07-30 12:10:24 -07001451 void logWindowList(final WindowList windows, String prefix) {
1452 int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001453 while (N > 0) {
1454 N--;
Craig Mautner59c00972012-07-30 12:10:24 -07001455 Slog.v(TAG, prefix + "#" + N + ": " + windows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456 }
1457 }
Romain Guy06882f82009-06-10 13:36:04 -07001458
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001459 void moveInputMethodDialogsLocked(int pos) {
1460 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001461
Craig Mautner59c00972012-07-30 12:10:24 -07001462 // TODO(multidisplay): IMEs are only supported on the default display.
1463 WindowList windows = getDefaultWindowList();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001464 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001465 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001466 for (int i=0; i<N; i++) {
1467 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1468 }
1469 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001470 Slog.v(TAG, "Window list w/pos=" + pos);
Craig Mautner59c00972012-07-30 12:10:24 -07001471 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001472 }
Romain Guy06882f82009-06-10 13:36:04 -07001473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001474 if (pos >= 0) {
1475 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
Craig Mautner59c00972012-07-30 12:10:24 -07001476 if (pos < windows.size()) {
1477 WindowState wp = windows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001478 if (wp == mInputMethodWindow) {
1479 pos++;
1480 }
1481 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001482 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001483 for (int i=0; i<N; i++) {
1484 WindowState win = dialogs.get(i);
1485 win.mTargetAppToken = targetAppToken;
1486 pos = reAddWindowLocked(pos, win);
1487 }
1488 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001489 Slog.v(TAG, "Final window list:");
Craig Mautner59c00972012-07-30 12:10:24 -07001490 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001491 }
1492 return;
1493 }
1494 for (int i=0; i<N; i++) {
1495 WindowState win = dialogs.get(i);
1496 win.mTargetAppToken = null;
1497 reAddWindowToListInOrderLocked(win);
1498 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001499 Slog.v(TAG, "No IM target, final list:");
Craig Mautner59c00972012-07-30 12:10:24 -07001500 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001501 }
1502 }
1503 }
Romain Guy06882f82009-06-10 13:36:04 -07001504
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1506 final WindowState imWin = mInputMethodWindow;
1507 final int DN = mInputMethodDialogs.size();
1508 if (imWin == null && DN == 0) {
1509 return false;
1510 }
Romain Guy06882f82009-06-10 13:36:04 -07001511
Craig Mautner59c00972012-07-30 12:10:24 -07001512 // TODO(multidisplay): IMEs are only supported on the default display.
1513 WindowList windows = getDefaultWindowList();
1514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001515 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1516 if (imPos >= 0) {
1517 // In this case, the input method windows are to be placed
1518 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001519
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520 // First check to see if the input method windows are already
1521 // located here, and contiguous.
Craig Mautner59c00972012-07-30 12:10:24 -07001522 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001523 WindowState firstImWin = imPos < N
Craig Mautner59c00972012-07-30 12:10:24 -07001524 ? windows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001526 // Figure out the actual input method window that should be
1527 // at the bottom of their stack.
1528 WindowState baseImWin = imWin != null
1529 ? imWin : mInputMethodDialogs.get(0);
1530 if (baseImWin.mChildWindows.size() > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001531 WindowState cw = baseImWin.mChildWindows.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001532 if (cw.mSubLayer < 0) baseImWin = cw;
1533 }
Romain Guy06882f82009-06-10 13:36:04 -07001534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001535 if (firstImWin == baseImWin) {
1536 // The windows haven't moved... but are they still contiguous?
1537 // First find the top IM window.
1538 int pos = imPos+1;
1539 while (pos < N) {
Craig Mautner59c00972012-07-30 12:10:24 -07001540 if (!(windows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001541 break;
1542 }
1543 pos++;
1544 }
1545 pos++;
1546 // Now there should be no more input method windows above.
1547 while (pos < N) {
Craig Mautner59c00972012-07-30 12:10:24 -07001548 if ((windows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001549 break;
1550 }
1551 pos++;
1552 }
1553 if (pos >= N) {
1554 // All is good!
1555 return false;
1556 }
1557 }
Romain Guy06882f82009-06-10 13:36:04 -07001558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001559 if (imWin != null) {
1560 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001561 Slog.v(TAG, "Moving IM from " + imPos);
Craig Mautner59c00972012-07-30 12:10:24 -07001562 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 }
1564 imPos = tmpRemoveWindowLocked(imPos, imWin);
1565 if (DEBUG_INPUT_METHOD) {
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001566 Slog.v(TAG, "List after removing with new pos " + imPos + ":");
Craig Mautner59c00972012-07-30 12:10:24 -07001567 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 }
1569 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1570 reAddWindowLocked(imPos, imWin);
1571 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001572 Slog.v(TAG, "List after moving IM to " + imPos + ":");
Craig Mautner59c00972012-07-30 12:10:24 -07001573 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001574 }
1575 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1576 } else {
1577 moveInputMethodDialogsLocked(imPos);
1578 }
Romain Guy06882f82009-06-10 13:36:04 -07001579
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001580 } else {
1581 // In this case, the input method windows go in a fixed layer,
1582 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001583
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001584 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001585 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001586 tmpRemoveWindowLocked(0, imWin);
1587 imWin.mTargetAppToken = null;
1588 reAddWindowToListInOrderLocked(imWin);
1589 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001590 Slog.v(TAG, "List with no IM target:");
Craig Mautner59c00972012-07-30 12:10:24 -07001591 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001592 }
Craig Mautner01cd0e72012-06-18 10:19:11 -07001593 if (DN > 0) moveInputMethodDialogsLocked(-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001594 } else {
Craig Mautner01cd0e72012-06-18 10:19:11 -07001595 moveInputMethodDialogsLocked(-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001596 }
Romain Guy06882f82009-06-10 13:36:04 -07001597
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001598 }
Romain Guy06882f82009-06-10 13:36:04 -07001599
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001600 if (needAssignLayers) {
Craig Mautner59c00972012-07-30 12:10:24 -07001601 assignLayersLocked(windows);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001602 }
Romain Guy06882f82009-06-10 13:36:04 -07001603
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001604 return true;
1605 }
Romain Guy06882f82009-06-10 13:36:04 -07001606
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001607 void adjustInputMethodDialogsLocked() {
1608 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1609 }
Romain Guy06882f82009-06-10 13:36:04 -07001610
Dianne Hackborn25994b42009-09-04 14:21:19 -07001611 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Craig Mautnerad3a9bb2012-03-09 11:31:06 -08001612 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001613 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1614 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
Craig Mautner59431632012-04-04 11:56:44 -07001615 ? wallpaperTarget.mAppToken.mAppAnimator.animation : null)
Dianne Hackborn25994b42009-09-04 14:21:19 -07001616 + " upper=" + mUpperWallpaperTarget
1617 + " lower=" + mLowerWallpaperTarget);
1618 return (wallpaperTarget != null
1619 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
Craig Mautner59431632012-04-04 11:56:44 -07001620 && wallpaperTarget.mAppToken.mAppAnimator.animation != null)))
Dianne Hackborn25994b42009-09-04 14:21:19 -07001621 || mUpperWallpaperTarget != null
1622 || mLowerWallpaperTarget != null;
1623 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001624
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001625 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1626 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001627
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001628 int adjustWallpaperWindowsLocked() {
Craig Mautnera608b882012-03-30 13:03:49 -07001629 mInnerFields.mWallpaperMayChange = false;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001630 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001631
Craig Mautner59c00972012-07-30 12:10:24 -07001632 // TODO(multidisplay): Wallpapers on main screen only.
1633 final DisplayInfo displayInfo = getDefaultDisplayContent().getDisplayInfo();
1634 final int dw = displayInfo.appWidth;
1635 final int dh = displayInfo.appHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001636
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001637 // First find top-most window that has asked to be on top of the
1638 // wallpaper; all wallpapers go behind it.
Craig Mautner59c00972012-07-30 12:10:24 -07001639 final WindowList windows = getDefaultWindowList();
1640 int N = windows.size();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001641 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001642 WindowState foundW = null;
1643 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001644 WindowState topCurW = null;
1645 int topCurI = 0;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001646 int windowDetachedI = -1;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001647 int i = N;
1648 while (i > 0) {
1649 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07001650 w = windows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001651 if ((w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER)) {
1652 if (topCurW == null) {
1653 topCurW = w;
1654 topCurI = i;
1655 }
1656 continue;
1657 }
1658 topCurW = null;
Craig Mautner01cd0e72012-06-18 10:19:11 -07001659 if (w != mWindowDetachedWallpaper && w.mAppToken != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001660 // If this window's app token is hidden and not animating,
1661 // it is of no interest to us.
Craig Mautner59431632012-04-04 11:56:44 -07001662 if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001663 if (DEBUG_WALLPAPER) Slog.v(TAG,
Craig Mautner1d961d42012-05-27 12:02:11 -07001664 "Skipping hidden and not animating token: " + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001665 continue;
1666 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001667 }
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001668 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win #" + i + " " + w + ": readyfordisplay="
Craig Mautner749a7bb2012-04-02 13:49:53 -07001669 + w.isReadyForDisplay() + " mDrawState=" + w.mWinAnimator.mDrawState);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001670 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07001671 && (mWallpaperTarget == w || w.isDrawnLw())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001672 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001673 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001674 foundW = w;
1675 foundI = i;
Craig Mautner4d7349b2012-04-20 14:52:47 -07001676 if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001677 // The current wallpaper target is animating, so we'll
1678 // look behind it for another possible target and figure
1679 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001680 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001681 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001682 continue;
1683 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001684 break;
Craig Mautner01cd0e72012-06-18 10:19:11 -07001685 } else if (w == mWindowDetachedWallpaper) {
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001686 windowDetachedI = i;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001687 }
1688 }
1689
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001690 if (foundW == null && windowDetachedI >= 0) {
1691 if (DEBUG_WALLPAPER) Slog.v(TAG,
1692 "Found animating detached wallpaper activity: #" + i + "=" + w);
1693 foundW = w;
1694 foundI = windowDetachedI;
1695 }
1696
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001697 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001698 // If we are currently waiting for an app transition, and either
1699 // the current target or the next target are involved with it,
1700 // then hold off on doing anything with the wallpaper.
1701 // Note that we are checking here for just whether the target
1702 // is part of an app token... which is potentially overly aggressive
1703 // (the app token may not be involved in the transition), but good
1704 // enough (we'll just wait until whatever transition is pending
1705 // executes).
1706 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001707 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001708 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001709 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001710 }
1711 if (foundW != null && foundW.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001712 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001713 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001714 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001715 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001716 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001717
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001718 if (mWallpaperTarget != foundW) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001719 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001720 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001721 + " oldTarget: " + mWallpaperTarget);
1722 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001723
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001724 mLowerWallpaperTarget = null;
1725 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001726
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001727 WindowState oldW = mWallpaperTarget;
1728 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001729
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001730 // Now what is happening... if the current and new targets are
1731 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001732 if (foundW != null && oldW != null) {
Craig Mautnera2c77052012-03-26 12:14:43 -07001733 boolean oldAnim = oldW.mWinAnimator.mAnimation != null
Craig Mautner59431632012-04-04 11:56:44 -07001734 || (oldW.mAppToken != null
1735 && oldW.mAppToken.mAppAnimator.animation != null);
Craig Mautnera2c77052012-03-26 12:14:43 -07001736 boolean foundAnim = foundW.mWinAnimator.mAnimation != null
Craig Mautner59431632012-04-04 11:56:44 -07001737 || (foundW.mAppToken != null &&
1738 foundW.mAppToken.mAppAnimator.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001739 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001740 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001741 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001742 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001743 if (foundAnim && oldAnim) {
Craig Mautner59c00972012-07-30 12:10:24 -07001744 int oldI = windows.indexOf(oldW);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001745 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001746 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001747 }
1748 if (oldI >= 0) {
1749 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001750 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001751 + "=" + oldW + "; new#" + foundI
1752 + "=" + foundW);
1753 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001754
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001755 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001756 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001757 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001758 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001759 }
1760 mWallpaperTarget = oldW;
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001761 foundW = oldW;
1762 foundI = oldI;
Craig Mautner711f90a2012-07-03 18:43:52 -07001763 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001764 // Now set the upper and lower wallpaper targets
1765 // correctly, and make sure that we are positioning
1766 // the wallpaper below the lower.
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001767 else if (foundI > oldI) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001768 // The new target is on top of the old one.
1769 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001770 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001771 }
1772 mUpperWallpaperTarget = foundW;
1773 mLowerWallpaperTarget = oldW;
1774 foundW = oldW;
1775 foundI = oldI;
1776 } else {
1777 // The new target is below the old one.
1778 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001779 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001780 }
1781 mUpperWallpaperTarget = oldW;
1782 mLowerWallpaperTarget = foundW;
1783 }
1784 }
1785 }
1786 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001787
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001788 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001789 // Is it time to stop animating?
Craig Mautnera2c77052012-03-26 12:14:43 -07001790 boolean lowerAnimating = mLowerWallpaperTarget.mWinAnimator.mAnimation != null
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001791 || (mLowerWallpaperTarget.mAppToken != null
Craig Mautner59431632012-04-04 11:56:44 -07001792 && mLowerWallpaperTarget.mAppToken.mAppAnimator.animation != null);
Craig Mautnera2c77052012-03-26 12:14:43 -07001793 boolean upperAnimating = mUpperWallpaperTarget.mWinAnimator.mAnimation != null
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001794 || (mUpperWallpaperTarget.mAppToken != null
Craig Mautner59431632012-04-04 11:56:44 -07001795 && mUpperWallpaperTarget.mAppToken.mAppAnimator.animation != null);
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001796 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001797 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001798 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001799 }
1800 mLowerWallpaperTarget = null;
1801 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001802 }
1803 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001804
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001805 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001806 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001807 // The window is visible to the compositor... but is it visible
1808 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001809 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001810 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001811
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001812 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001813 // its layer adjustment. Only do this if we are not transfering
1814 // between two wallpaper targets.
1815 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001816 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Craig Mautner59431632012-04-04 11:56:44 -07001817 ? foundW.mAppToken.mAppAnimator.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001818
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001819 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1820 * TYPE_LAYER_MULTIPLIER
1821 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001822
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001823 // Now w is the window we are supposed to be behind... but we
1824 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001825 // AND any starting window associated with it, AND below the
1826 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001827 while (foundI > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001828 WindowState wb = windows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001829 if (wb.mBaseLayer < maxLayer &&
1830 wb.mAttachedWindow != foundW &&
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001831 (foundW.mAttachedWindow == null ||
1832 wb.mAttachedWindow != foundW.mAttachedWindow) &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001833 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001834 foundW.mToken == null || wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001835 // This window is not related to the previous one in any
1836 // interesting way, so stop here.
1837 break;
1838 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001839 foundW = wb;
1840 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001841 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001842 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001843 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001844 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001845
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001846 if (foundW == null && topCurW != null) {
1847 // There is no wallpaper target, so it goes at the bottom.
1848 // We will assume it is the same place as last time, if known.
1849 foundW = topCurW;
1850 foundI = topCurI+1;
1851 } else {
1852 // Okay i is the position immediately above the wallpaper. Look at
1853 // what is below it for later.
Craig Mautner59c00972012-07-30 12:10:24 -07001854 foundW = foundI > 0 ? windows.get(foundI-1) : null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001855 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001856
Dianne Hackborn284ac932009-08-28 10:34:25 -07001857 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001858 if (mWallpaperTarget.mWallpaperX >= 0) {
1859 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001860 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001861 }
1862 if (mWallpaperTarget.mWallpaperY >= 0) {
1863 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001864 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001865 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001866 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001867
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001868 // Start stepping backwards from here, ensuring that our wallpaper windows
1869 // are correctly placed.
1870 int curTokenIndex = mWallpaperTokens.size();
1871 while (curTokenIndex > 0) {
1872 curTokenIndex--;
1873 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001874 if (token.hidden == visible) {
1875 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1876 token.hidden = !visible;
1877 // Need to do a layout to ensure the wallpaper now has the
1878 // correct size.
1879 mLayoutNeeded = true;
1880 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001881
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001882 int curWallpaperIndex = token.windows.size();
1883 while (curWallpaperIndex > 0) {
1884 curWallpaperIndex--;
1885 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001886
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001887 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001888 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001889 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001890
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001891 // First, make sure the client has the current visibility
1892 // state.
Craig Mautner507a2ee2012-06-13 08:39:38 -07001893 dispatchWallpaperVisibility(wallpaper, visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001894
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001895 wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Craig Mautneref25d7a2012-05-15 23:01:47 -07001896 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "adjustWallpaper win "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001897 + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001898
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001899 // First, if this window is at the current index, then all
1900 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001901 if (wallpaper == foundW) {
1902 foundI--;
1903 foundW = foundI > 0
Craig Mautner59c00972012-07-30 12:10:24 -07001904 ? windows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001905 continue;
1906 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001907
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001908 // The window didn't match... the current wallpaper window,
1909 // wherever it is, is in the wrong place, so make sure it is
1910 // not in the list.
Craig Mautner59c00972012-07-30 12:10:24 -07001911 int oldIndex = windows.indexOf(wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001912 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001913 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001914 + oldIndex + ": " + wallpaper);
Craig Mautner59c00972012-07-30 12:10:24 -07001915 windows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001916 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001917 if (oldIndex < foundI) {
1918 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001919 }
1920 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001921
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001922 // Now stick it in.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001923 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
1924 Slog.v(TAG, "Moving wallpaper " + wallpaper
1925 + " from " + oldIndex + " to " + foundI);
1926 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001927
Craig Mautner59c00972012-07-30 12:10:24 -07001928 windows.add(foundI, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001929 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001930 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001931 }
1932 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001933
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001934 return changed;
1935 }
1936
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001937 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001938 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001939 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001940 mWallpaperAnimLayerAdjustment = adj;
1941 int curTokenIndex = mWallpaperTokens.size();
1942 while (curTokenIndex > 0) {
1943 curTokenIndex--;
1944 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1945 int curWallpaperIndex = token.windows.size();
1946 while (curWallpaperIndex > 0) {
1947 curWallpaperIndex--;
1948 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001949 wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + adj;
Craig Mautneref25d7a2012-05-15 23:01:47 -07001950 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "setWallpaper win "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001951 + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001952 }
1953 }
1954 }
1955
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001956 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
1957 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001958 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001959 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001960 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001961 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackbornffb3d932011-05-17 17:44:51 -07001962 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001963 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
1964 changed = wallpaperWin.mXOffset != offset;
1965 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001966 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001967 + wallpaperWin + " x: " + offset);
1968 wallpaperWin.mXOffset = offset;
1969 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001970 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001971 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001972 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001973 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001974 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001975
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001976 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001977 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001978 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1979 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1980 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001981 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001982 + wallpaperWin + " y: " + offset);
1983 changed = true;
1984 wallpaperWin.mYOffset = offset;
1985 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001986 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001987 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001988 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001989 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001990 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001991
Craig Mautnerbb1449b2012-03-23 16:11:14 -07001992 if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
Chet Haasea8e5a2b2011-10-28 13:18:16 -07001993 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001994 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001995 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001996 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
1997 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001998 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001999 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002000 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002001 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002002 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
2003 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002004 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002005 if (mWaitingOnWallpaper != null) {
2006 long start = SystemClock.uptimeMillis();
2007 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
2008 < start) {
2009 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002010 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07002011 "Waiting for offset complete...");
2012 mWindowMap.wait(WALLPAPER_TIMEOUT);
2013 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002014 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002015 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07002016 if ((start+WALLPAPER_TIMEOUT)
2017 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002018 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07002019 + wallpaperWin);
2020 mLastWallpaperTimeoutTime = start;
2021 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002022 }
Dianne Hackborn75804932009-10-20 20:15:20 -07002023 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002024 }
2025 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002026 } catch (RemoteException e) {
2027 }
2028 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002029
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002030 return changed;
2031 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002032
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002033 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002034 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002035 if (mWaitingOnWallpaper != null &&
2036 mWaitingOnWallpaper.mClient.asBinder() == window) {
2037 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07002038 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002039 }
2040 }
2041 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002042
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002043 void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Craig Mautner59c00972012-07-30 12:10:24 -07002044 final DisplayContent displayContent = changingTarget.mDisplayContent;
2045 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
2046 final int dw = displayInfo.appWidth;
2047 final int dh = displayInfo.appHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002048
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002049 WindowState target = mWallpaperTarget;
2050 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002051 if (target.mWallpaperX >= 0) {
2052 mLastWallpaperX = target.mWallpaperX;
2053 } else if (changingTarget.mWallpaperX >= 0) {
2054 mLastWallpaperX = changingTarget.mWallpaperX;
2055 }
2056 if (target.mWallpaperY >= 0) {
2057 mLastWallpaperY = target.mWallpaperY;
2058 } else if (changingTarget.mWallpaperY >= 0) {
2059 mLastWallpaperY = changingTarget.mWallpaperY;
2060 }
2061 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002062
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002063 int curTokenIndex = mWallpaperTokens.size();
2064 while (curTokenIndex > 0) {
2065 curTokenIndex--;
2066 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2067 int curWallpaperIndex = token.windows.size();
2068 while (curWallpaperIndex > 0) {
2069 curWallpaperIndex--;
2070 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2071 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002072 WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
2073 winAnimator.computeShownFrameLocked();
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002074 // No need to lay out the windows - we can just set the wallpaper position
2075 // directly.
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07002076 // TODO(cmautner): Don't move this from here, just lock the WindowAnimator.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002077 if (winAnimator.mSurfaceX != wallpaper.mShownFrame.left
2078 || winAnimator.mSurfaceY != wallpaper.mShownFrame.top) {
Craig Mautner12670b52012-07-03 19:15:35 -07002079 winAnimator.setWallpaperOffset((int) wallpaper.mShownFrame.left,
Craig Mautner48ba1e72012-04-02 13:18:16 -07002080 (int) wallpaper.mShownFrame.top);
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002081 }
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002082 // We only want to be synchronous with one wallpaper.
2083 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002084 }
2085 }
2086 }
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002087 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002088
Craig Mautner507a2ee2012-06-13 08:39:38 -07002089 /**
2090 * Check wallpaper for visiblity change and notify window if so.
2091 * @param wallpaper The wallpaper to test and notify.
2092 * @param visible Current visibility.
2093 */
2094 void dispatchWallpaperVisibility(final WindowState wallpaper, final boolean visible) {
2095 if (wallpaper.mWallpaperVisible != visible) {
2096 wallpaper.mWallpaperVisible = visible;
2097 try {
2098 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
2099 "Updating visibility of wallpaper " + wallpaper
2100 + ": " + visible + " Callers=" + Debug.getCallers(2));
2101 wallpaper.mClient.dispatchAppVisibility(visible);
2102 } catch (RemoteException e) {
2103 }
2104 }
2105 }
2106
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002107 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07002108 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Craig Mautner59c00972012-07-30 12:10:24 -07002109 final DisplayContent displayContent = mWallpaperTarget.mDisplayContent;
2110 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
2111 final int dw = displayInfo.appWidth;
2112 final int dh = displayInfo.appHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002113
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002114 int curTokenIndex = mWallpaperTokens.size();
2115 while (curTokenIndex > 0) {
2116 curTokenIndex--;
2117 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002118 if (token.hidden == visible) {
2119 token.hidden = !visible;
2120 // Need to do a layout to ensure the wallpaper now has the
2121 // correct size.
2122 mLayoutNeeded = true;
2123 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002124
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002125 int curWallpaperIndex = token.windows.size();
2126 while (curWallpaperIndex > 0) {
2127 curWallpaperIndex--;
2128 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2129 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002130 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002131 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002132
Craig Mautner507a2ee2012-06-13 08:39:38 -07002133 dispatchWallpaperVisibility(wallpaper, visible);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002134 }
2135 }
2136 }
Craig Mautner711f90a2012-07-03 18:43:52 -07002137
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002138 public int addWindow(Session session, IWindow client, int seq,
Craig Mautner6881a102012-07-27 13:04:51 -07002139 WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002140 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002141 int res = mPolicy.checkAddPermission(attrs);
2142 if (res != WindowManagerImpl.ADD_OKAY) {
2143 return res;
2144 }
Romain Guy06882f82009-06-10 13:36:04 -07002145
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002146 boolean reportNewConfig = false;
2147 WindowState attachedWindow = null;
2148 WindowState win = null;
Dianne Hackborn5132b372010-07-29 12:51:35 -07002149 long origId;
Romain Guy06882f82009-06-10 13:36:04 -07002150
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002151 synchronized(mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002152 if (mDisplay == null) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07002153 throw new IllegalStateException("Display has not been initialialized");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002154 }
Romain Guy06882f82009-06-10 13:36:04 -07002155
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002156 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002157 Slog.w(TAG, "Window " + client + " is already added");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002158 return WindowManagerImpl.ADD_DUPLICATE_ADD;
2159 }
2160
2161 if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002162 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002163 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002164 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002165 + attrs.token + ". Aborting.");
2166 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2167 }
2168 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
2169 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002170 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002171 + attrs.token + ". Aborting.");
2172 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2173 }
2174 }
2175
2176 boolean addToken = false;
2177 WindowToken token = mTokenMap.get(attrs.token);
2178 if (token == null) {
2179 if (attrs.type >= FIRST_APPLICATION_WINDOW
2180 && attrs.type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002181 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002182 + attrs.token + ". Aborting.");
2183 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2184 }
2185 if (attrs.type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002186 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002187 + attrs.token + ". Aborting.");
2188 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2189 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002190 if (attrs.type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002191 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002192 + attrs.token + ". Aborting.");
2193 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2194 }
Daniel Sandler7d276c32012-01-30 14:33:52 -05002195 if (attrs.type == TYPE_DREAM) {
2196 Slog.w(TAG, "Attempted to add Dream window with unknown token "
2197 + attrs.token + ". Aborting.");
2198 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2199 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002200 token = new WindowToken(this, attrs.token, -1, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002201 addToken = true;
2202 } else if (attrs.type >= FIRST_APPLICATION_WINDOW
2203 && attrs.type <= LAST_APPLICATION_WINDOW) {
2204 AppWindowToken atoken = token.appWindowToken;
2205 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002206 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002207 + token + ". Aborting.");
2208 return WindowManagerImpl.ADD_NOT_APP_TOKEN;
2209 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002210 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002211 + token + ". Aborting.");
2212 return WindowManagerImpl.ADD_APP_EXITING;
2213 }
2214 if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
2215 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002216 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002217 TAG, "**** NO NEED TO START: " + attrs.getTitle());
2218 return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
2219 }
2220 } else if (attrs.type == TYPE_INPUT_METHOD) {
2221 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002222 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002223 + attrs.token + ". Aborting.");
2224 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2225 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002226 } else if (attrs.type == TYPE_WALLPAPER) {
2227 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002228 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002229 + attrs.token + ". Aborting.");
2230 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2231 }
Daniel Sandler7d276c32012-01-30 14:33:52 -05002232 } else if (attrs.type == TYPE_DREAM) {
2233 if (token.windowType != TYPE_DREAM) {
2234 Slog.w(TAG, "Attempted to add Dream window with bad token "
2235 + attrs.token + ". Aborting.");
2236 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2237 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002238 }
2239
Craig Mautner59c00972012-07-30 12:10:24 -07002240 final DisplayContent displayContent = getDisplayContent(displayId);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002241 win = new WindowState(this, session, client, token,
Craig Mautner59c00972012-07-30 12:10:24 -07002242 attachedWindow, seq, attrs, viewVisibility, displayContent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002243 if (win.mDeathRecipient == null) {
2244 // Client has apparently died, so there is no reason to
2245 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002246 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002247 + " that is dead, aborting.");
2248 return WindowManagerImpl.ADD_APP_EXITING;
2249 }
2250
2251 mPolicy.adjustWindowParamsLw(win.mAttrs);
Romain Guy06882f82009-06-10 13:36:04 -07002252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002253 res = mPolicy.prepareAddWindowLw(win, attrs);
2254 if (res != WindowManagerImpl.ADD_OKAY) {
2255 return res;
2256 }
Craig Mautner918b53b2012-07-09 14:15:54 -07002257
Jeff Browncc4f7db2011-08-30 20:34:48 -07002258 if (outInputChannel != null && (attrs.inputFeatures
2259 & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002260 String name = win.makeInputChannelName();
2261 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
Jeff Browncc4f7db2011-08-30 20:34:48 -07002262 win.setInputChannel(inputChannels[0]);
Jeff Brown0a0ab122011-08-12 18:08:08 -07002263 inputChannels[1].transferTo(outInputChannel);
Craig Mautner918b53b2012-07-09 14:15:54 -07002264
Jeff Brown928e0542011-01-10 11:17:36 -08002265 mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002266 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002267
2268 // From now on, no exceptions or errors allowed!
2269
2270 res = WindowManagerImpl.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002271
Dianne Hackborn5132b372010-07-29 12:51:35 -07002272 origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002273
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002274 if (addToken) {
2275 mTokenMap.put(attrs.token, token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002276 }
2277 win.attach();
2278 mWindowMap.put(client.asBinder(), win);
2279
2280 if (attrs.type == TYPE_APPLICATION_STARTING &&
2281 token.appWindowToken != null) {
2282 token.appWindowToken.startingWindow = win;
Craig Mautner38b24782012-07-02 16:21:28 -07002283 if (DEBUG_STARTING_WINDOW) Slog.v (TAG, "addWindow: " + token.appWindowToken
2284 + " startingWindow=" + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002285 }
2286
2287 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002288
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002289 if (attrs.type == TYPE_INPUT_METHOD) {
satok1bc0a492012-04-25 22:47:12 +09002290 win.mGivenInsetsPending = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002291 mInputMethodWindow = win;
2292 addInputMethodWindowToListLocked(win);
2293 imMayMove = false;
2294 } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
2295 mInputMethodDialogs.add(win);
2296 addWindowToListInOrderLocked(win, true);
2297 adjustInputMethodDialogsLocked();
2298 imMayMove = false;
2299 } else {
2300 addWindowToListInOrderLocked(win, true);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002301 if (attrs.type == TYPE_WALLPAPER) {
2302 mLastWallpaperTimeoutTime = 0;
2303 adjustWallpaperWindowsLocked();
2304 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002305 adjustWallpaperWindowsLocked();
2306 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002307 }
Romain Guy06882f82009-06-10 13:36:04 -07002308
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002309 win.mWinAnimator.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002310
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002311 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
Romain Guy06882f82009-06-10 13:36:04 -07002312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002313 if (mInTouchMode) {
2314 res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
2315 }
Craig Mautner764983d2012-03-22 11:37:36 -07002316 if (win.mAppToken == null || !win.mAppToken.clientHidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002317 res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
2318 }
Romain Guy06882f82009-06-10 13:36:04 -07002319
Jeff Brown2e44b072011-01-24 15:21:56 -08002320 mInputMonitor.setUpdateInputWindowsNeededLw();
2321
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002322 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002323 if (win.canReceiveKeys()) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002324 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
2325 false /*updateInputWindows*/);
Jeff Brown349703e2010-06-22 01:27:15 -07002326 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002327 imMayMove = false;
2328 }
2329 }
Romain Guy06882f82009-06-10 13:36:04 -07002330
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002331 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002332 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002333 }
Romain Guy06882f82009-06-10 13:36:04 -07002334
Craig Mautner59c00972012-07-30 12:10:24 -07002335 assignLayersLocked(displayContent.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002336 // Don't do layout here, the window must call
2337 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002339 //dump();
2340
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002341 if (focusChanged) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002342 finishUpdateFocusedWindowAfterAssignLayersLocked(false /*updateInputWindows*/);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002343 }
Jeff Brown2e44b072011-01-24 15:21:56 -08002344 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08002345
Joe Onorato8a9b2202010-02-26 18:56:32 -08002346 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002347 TAG, "New client " + client.asBinder()
2348 + ": window=" + win);
Craig Mautner9e809442012-06-22 17:13:04 -07002349
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002350 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002351 reportNewConfig = true;
2352 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002353 }
2354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002355 if (reportNewConfig) {
2356 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002357 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07002358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002359 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002360
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002361 return res;
2362 }
Romain Guy06882f82009-06-10 13:36:04 -07002363
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002364 public void removeWindow(Session session, IWindow client) {
2365 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002366 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002367 if (win == null) {
2368 return;
2369 }
2370 removeWindowLocked(session, win);
2371 }
2372 }
Romain Guy06882f82009-06-10 13:36:04 -07002373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002374 public void removeWindowLocked(Session session, WindowState win) {
2375
Joe Onorato8a9b2202010-02-26 18:56:32 -08002376 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002377 TAG, "Remove " + win + " client="
2378 + Integer.toHexString(System.identityHashCode(
2379 win.mClient.asBinder()))
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002380 + ", surface=" + win.mWinAnimator.mSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002381
2382 final long origId = Binder.clearCallingIdentity();
Craig Mautner764983d2012-03-22 11:37:36 -07002383
Jeff Brownc5ed5912010-07-14 18:48:53 -07002384 win.disposeInputChannel();
Romain Guy06882f82009-06-10 13:36:04 -07002385
Joe Onorato8a9b2202010-02-26 18:56:32 -08002386 if (DEBUG_APP_TRANSITIONS) Slog.v(
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002387 TAG, "Remove " + win + ": mSurface=" + win.mWinAnimator.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002388 + " mExiting=" + win.mExiting
Craig Mautnera2c77052012-03-26 12:14:43 -07002389 + " isAnimating=" + win.mWinAnimator.isAnimating()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002390 + " app-animation="
Craig Mautner59431632012-04-04 11:56:44 -07002391 + (win.mAppToken != null ? win.mAppToken.mAppAnimator.animation : null)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002392 + " inPendingTransaction="
2393 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2394 + " mDisplayFrozen=" + mDisplayFrozen);
2395 // Visibility of the removed window. Will be used later to update orientation later on.
2396 boolean wasVisible = false;
2397 // First, see if we need to run an animation. If we do, we have
2398 // to hold off on removing the window until the animation is done.
2399 // If the display is frozen, just remove immediately, since the
2400 // animation wouldn't be seen.
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002401 if (win.mHasSurface && okToDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002402 // If we are not currently running the exit animation, we
2403 // need to see about starting one.
Craig Mautner764983d2012-03-22 11:37:36 -07002404 wasVisible = win.isWinVisibleLw();
2405 if (wasVisible) {
Romain Guy06882f82009-06-10 13:36:04 -07002406
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002407 int transit = WindowManagerPolicy.TRANSIT_EXIT;
Craig Mautnerbb1449b2012-03-23 16:11:14 -07002408 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002409 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2410 }
2411 // Try starting an animation.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002412 if (win.mWinAnimator.applyAnimationLocked(transit, false)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002413 win.mExiting = true;
2414 }
2415 }
Craig Mautnera2c77052012-03-26 12:14:43 -07002416 if (win.mExiting || win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002417 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002418 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002419 win.mExiting = true;
2420 win.mRemoveOnExit = true;
2421 mLayoutNeeded = true;
Jeff Brown3a22cd92011-01-21 13:59:04 -08002422 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2423 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002424 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08002425 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002426 if (win.mAppToken != null) {
2427 win.mAppToken.updateReportedVisibilityLocked();
2428 }
2429 //dump();
2430 Binder.restoreCallingIdentity(origId);
2431 return;
2432 }
2433 }
2434
2435 removeWindowInnerLocked(session, win);
2436 // Removing a visible window will effect the computed orientation
2437 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002438 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002439 != mForcedAppOrientation
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002440 && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002441 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002442 }
Jeff Brown3a22cd92011-01-21 13:59:04 -08002443 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002444 Binder.restoreCallingIdentity(origId);
2445 }
Romain Guy06882f82009-06-10 13:36:04 -07002446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002447 private void removeWindowInnerLocked(Session session, WindowState win) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002448 if (win.mRemoved) {
2449 // Nothing to do.
2450 return;
2451 }
2452
2453 for (int i=win.mChildWindows.size()-1; i>=0; i--) {
2454 WindowState cwin = win.mChildWindows.get(i);
2455 Slog.w(TAG, "Force-removing child win " + cwin + " from container "
2456 + win);
2457 removeWindowInnerLocked(cwin.mSession, cwin);
2458 }
2459
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002460 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002461
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002462 if (mInputMethodTarget == win) {
2463 moveInputMethodWindowsIfNeededLocked(false);
2464 }
Romain Guy06882f82009-06-10 13:36:04 -07002465
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002466 if (false) {
2467 RuntimeException e = new RuntimeException("here");
2468 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002469 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002470 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002472 mPolicy.removeWindowLw(win);
2473 win.removeLocked();
2474
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002475 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002476 mWindowMap.remove(win.mClient.asBinder());
Craig Mautner59c00972012-07-30 12:10:24 -07002477
2478 final WindowList windows = win.getWindowList();
2479 windows.remove(win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002480 mPendingRemove.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002481 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002482 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002483
2484 if (mInputMethodWindow == win) {
2485 mInputMethodWindow = null;
2486 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2487 mInputMethodDialogs.remove(win);
2488 }
Romain Guy06882f82009-06-10 13:36:04 -07002489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002490 final WindowToken token = win.mToken;
2491 final AppWindowToken atoken = win.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002492 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + win + " from " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002493 token.windows.remove(win);
2494 if (atoken != null) {
2495 atoken.allAppWindows.remove(win);
2496 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002497 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002498 TAG, "**** Removing window " + win + ": count="
2499 + token.windows.size());
2500 if (token.windows.size() == 0) {
2501 if (!token.explicit) {
2502 mTokenMap.remove(token.token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002503 } else if (atoken != null) {
2504 atoken.firstWindowDrawn = false;
2505 }
2506 }
2507
2508 if (atoken != null) {
2509 if (atoken.startingWindow == win) {
Craig Mautner38b24782012-07-02 16:21:28 -07002510 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling startingWindow " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002511 atoken.startingWindow = null;
2512 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2513 // If this is the last window and we had requested a starting
2514 // transition window, well there is no point now.
Craig Mautner38b24782012-07-02 16:21:28 -07002515 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling last startingWindow");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002516 atoken.startingData = null;
2517 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2518 // If this is the last window except for a starting transition
2519 // window, we need to get rid of the starting transition.
2520 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002521 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002522 + ": no more real windows");
2523 }
2524 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2525 mH.sendMessage(m);
2526 }
2527 }
Romain Guy06882f82009-06-10 13:36:04 -07002528
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002529 if (win.mAttrs.type == TYPE_WALLPAPER) {
2530 mLastWallpaperTimeoutTime = 0;
2531 adjustWallpaperWindowsLocked();
2532 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002533 adjustWallpaperWindowsLocked();
2534 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002536 if (!mInLayout) {
Craig Mautner59c00972012-07-30 12:10:24 -07002537 assignLayersLocked(windows);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002538 mLayoutNeeded = true;
2539 performLayoutAndPlaceSurfacesLocked();
2540 if (win.mAppToken != null) {
2541 win.mAppToken.updateReportedVisibilityLocked();
2542 }
2543 }
Craig Mautner9e809442012-06-22 17:13:04 -07002544
Jeff Brown2e44b072011-01-24 15:21:56 -08002545 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002546 }
2547
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002548 static void logSurface(WindowState w, String msg, RuntimeException where) {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002549 String str = " SURFACE " + msg + ": " + w;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002550 if (where != null) {
2551 Slog.i(TAG, str, where);
2552 } else {
2553 Slog.i(TAG, str);
2554 }
2555 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002556
2557 static void logSurface(Surface s, String title, String msg, RuntimeException where) {
2558 String str = " SURFACE " + s + ": " + msg + " / " + title;
2559 if (where != null) {
2560 Slog.i(TAG, str, where);
2561 } else {
2562 Slog.i(TAG, str);
2563 }
2564 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07002565
2566 // TODO(cmautner): Move to WindowStateAnimator.
2567 void setTransparentRegionHint(final WindowStateAnimator winAnimator, final Region region) {
2568 mH.sendMessage(mH.obtainMessage(H.SET_TRANSPARENT_REGION,
2569 new Pair<WindowStateAnimator, Region>(winAnimator, region)));
2570 }
2571
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002572 void setTransparentRegionWindow(Session session, IWindow client, Region region) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002573 long origId = Binder.clearCallingIdentity();
2574 try {
2575 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002576 WindowState w = windowForClientLocked(session, client, false);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002577 if ((w != null) && w.mHasSurface) {
Craig Mautner48ba1e72012-04-02 13:18:16 -07002578 setTransparentRegionHint(w.mWinAnimator, region);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002579 }
2580 }
2581 } finally {
2582 Binder.restoreCallingIdentity(origId);
2583 }
2584 }
2585
2586 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002587 int touchableInsets, Rect contentInsets,
Jeff Brownfbf09772011-01-16 14:06:57 -08002588 Rect visibleInsets, Region touchableRegion) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002589 long origId = Binder.clearCallingIdentity();
2590 try {
2591 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002592 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002593 if (w != null) {
2594 w.mGivenInsetsPending = false;
2595 w.mGivenContentInsets.set(contentInsets);
2596 w.mGivenVisibleInsets.set(visibleInsets);
Jeff Brownfbf09772011-01-16 14:06:57 -08002597 w.mGivenTouchableRegion.set(touchableRegion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002598 w.mTouchableInsets = touchableInsets;
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002599 if (w.mGlobalScale != 1) {
2600 w.mGivenContentInsets.scale(w.mGlobalScale);
2601 w.mGivenVisibleInsets.scale(w.mGlobalScale);
2602 w.mGivenTouchableRegion.scale(w.mGlobalScale);
2603 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002604 mLayoutNeeded = true;
2605 performLayoutAndPlaceSurfacesLocked();
2606 }
2607 }
2608 } finally {
2609 Binder.restoreCallingIdentity(origId);
2610 }
2611 }
Romain Guy06882f82009-06-10 13:36:04 -07002612
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002613 public void getWindowDisplayFrame(Session session, IWindow client,
2614 Rect outDisplayFrame) {
2615 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002616 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002617 if (win == null) {
2618 outDisplayFrame.setEmpty();
2619 return;
2620 }
2621 outDisplayFrame.set(win.mDisplayFrame);
2622 }
2623 }
2624
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002625 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2626 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002627 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2628 window.mWallpaperX = x;
2629 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002630 window.mWallpaperXStep = xStep;
2631 window.mWallpaperYStep = yStep;
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002632 updateWallpaperOffsetLocked(window, true);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002633 }
2634 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002635
Dianne Hackborn75804932009-10-20 20:15:20 -07002636 void wallpaperCommandComplete(IBinder window, Bundle result) {
2637 synchronized (mWindowMap) {
2638 if (mWaitingOnWallpaper != null &&
2639 mWaitingOnWallpaper.mClient.asBinder() == window) {
2640 mWaitingOnWallpaper = null;
2641 mWindowMap.notifyAll();
2642 }
2643 }
2644 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002645
Dianne Hackborn75804932009-10-20 20:15:20 -07002646 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2647 String action, int x, int y, int z, Bundle extras, boolean sync) {
2648 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2649 || window == mUpperWallpaperTarget) {
2650 boolean doWait = sync;
2651 int curTokenIndex = mWallpaperTokens.size();
2652 while (curTokenIndex > 0) {
2653 curTokenIndex--;
2654 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2655 int curWallpaperIndex = token.windows.size();
2656 while (curWallpaperIndex > 0) {
2657 curWallpaperIndex--;
2658 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2659 try {
2660 wallpaper.mClient.dispatchWallpaperCommand(action,
2661 x, y, z, extras, sync);
2662 // We only want to be synchronous with one wallpaper.
2663 sync = false;
2664 } catch (RemoteException e) {
2665 }
2666 }
2667 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002668
Dianne Hackborn75804932009-10-20 20:15:20 -07002669 if (doWait) {
2670 // XXX Need to wait for result.
2671 }
2672 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002673
Dianne Hackborn75804932009-10-20 20:15:20 -07002674 return null;
2675 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002676
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002677 public void setUniverseTransformLocked(WindowState window, float alpha,
2678 float offx, float offy, float dsdx, float dtdx, float dsdy, float dtdy) {
2679 Transformation transform = window.mWinAnimator.mUniverseTransform;
2680 transform.setAlpha(alpha);
2681 Matrix matrix = transform.getMatrix();
2682 matrix.getValues(mTmpFloats);
2683 mTmpFloats[Matrix.MTRANS_X] = offx;
2684 mTmpFloats[Matrix.MTRANS_Y] = offy;
2685 mTmpFloats[Matrix.MSCALE_X] = dsdx;
2686 mTmpFloats[Matrix.MSKEW_Y] = dtdx;
2687 mTmpFloats[Matrix.MSKEW_X] = dsdy;
2688 mTmpFloats[Matrix.MSCALE_Y] = dtdy;
2689 matrix.setValues(mTmpFloats);
Craig Mautner59c00972012-07-30 12:10:24 -07002690 final DisplayInfo displayInfo = window.mDisplayContent.getDisplayInfo();
Jeff Brownfa25bf52012-07-23 19:26:30 -07002691 final RectF dispRect = new RectF(0, 0,
Craig Mautner59c00972012-07-30 12:10:24 -07002692 displayInfo.logicalWidth, displayInfo.logicalHeight);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002693 matrix.mapRect(dispRect);
Jeff Brownfa25bf52012-07-23 19:26:30 -07002694 window.mGivenTouchableRegion.set(0, 0,
Craig Mautner59c00972012-07-30 12:10:24 -07002695 displayInfo.logicalWidth, displayInfo.logicalHeight);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002696 window.mGivenTouchableRegion.op((int)dispRect.left, (int)dispRect.top,
2697 (int)dispRect.right, (int)dispRect.bottom, Region.Op.DIFFERENCE);
2698 window.mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
2699 mLayoutNeeded = true;
2700 performLayoutAndPlaceSurfacesLocked();
2701 }
2702
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002703 public int relayoutWindow(Session session, IWindow client, int seq,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002704 WindowManager.LayoutParams attrs, int requestedWidth,
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002705 int requestedHeight, int viewVisibility, int flags,
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07002706 Rect outFrame, Rect outContentInsets,
Dianne Hackborn5c58de32012-04-28 19:52:37 -07002707 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07002708 boolean toBeDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002709 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002710 boolean configChanged;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002711 boolean surfaceChanged = false;
Dianne Hackborn12d3a942012-04-27 14:16:30 -07002712 boolean animating;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002713
2714 // if they don't have this permission, mask out the status bar bits
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002715 int systemUiVisibility = 0;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002716 if (attrs != null) {
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002717 systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
2718 if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -07002719 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
2720 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002721 systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
Dianne Hackborna44abeb2011-08-08 19:24:01 -07002722 }
Joe Onoratoac0ee892011-01-30 15:38:30 -08002723 }
2724 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002725 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002726
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002727 synchronized(mWindowMap) {
Craig Mautner48ba1e72012-04-02 13:18:16 -07002728 // TODO(cmautner): synchronize on mAnimator or win.mWinAnimator.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002729 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002730 if (win == null) {
2731 return 0;
2732 }
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002733 WindowStateAnimator winAnimator = win.mWinAnimator;
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08002734 if (win.mRequestedWidth != requestedWidth
2735 || win.mRequestedHeight != requestedHeight) {
2736 win.mLayoutNeeded = true;
2737 win.mRequestedWidth = requestedWidth;
2738 win.mRequestedHeight = requestedHeight;
2739 }
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002740 if (attrs != null && seq == win.mSeq) {
2741 win.mSystemUiVisibility = systemUiVisibility;
2742 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002743
2744 if (attrs != null) {
2745 mPolicy.adjustWindowParamsLw(attrs);
2746 }
Romain Guy06882f82009-06-10 13:36:04 -07002747
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002748 winAnimator.mSurfaceDestroyDeferred =
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002749 (flags&WindowManagerImpl.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
2750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002751 int attrChanges = 0;
2752 int flagChanges = 0;
2753 if (attrs != null) {
Dianne Hackborn0e60db22011-09-01 11:17:57 -07002754 if (win.mAttrs.type != attrs.type) {
2755 throw new IllegalArgumentException(
2756 "Window type can not be changed after the window is added.");
2757 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002758 flagChanges = win.mAttrs.flags ^= attrs.flags;
2759 attrChanges = win.mAttrs.copyFrom(attrs);
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002760 if ((attrChanges & (WindowManager.LayoutParams.LAYOUT_CHANGED
2761 | WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED)) != 0) {
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08002762 win.mLayoutNeeded = true;
2763 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002764 }
2765
Joe Onorato8a9b2202010-02-26 18:56:32 -08002766 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002767
Dianne Hackborn5fd21692011-06-07 14:09:47 -07002768 win.mEnforceSizeCompat = (win.mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0;
2769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002770 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002771 winAnimator.mAlpha = attrs.alpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002772 }
2773
2774 final boolean scaledWindow =
2775 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2776
2777 if (scaledWindow) {
2778 // requested{Width|Height} Surface's physical size
2779 // attrs.{width|height} Size on screen
2780 win.mHScale = (attrs.width != requestedWidth) ?
2781 (attrs.width / (float)requestedWidth) : 1.0f;
2782 win.mVScale = (attrs.height != requestedHeight) ?
2783 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002784 } else {
2785 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002786 }
2787
2788 boolean imMayMove = (flagChanges&(
2789 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
2790 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002791
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002792 boolean focusMayChange = win.mViewVisibility != viewVisibility
2793 || ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
2794 || (!win.mRelayoutCalled);
Romain Guy06882f82009-06-10 13:36:04 -07002795
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002796 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2797 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07002798 wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002799
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002800 win.mRelayoutCalled = true;
2801 final int oldVisibility = win.mViewVisibility;
2802 win.mViewVisibility = viewVisibility;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07002803 if (DEBUG_SCREEN_ON) {
2804 RuntimeException stack = new RuntimeException();
2805 stack.fillInStackTrace();
2806 Slog.i(TAG, "Relayout " + win + ": oldVis=" + oldVisibility
2807 + " newVis=" + viewVisibility, stack);
2808 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002809 if (viewVisibility == View.VISIBLE &&
2810 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07002811 toBeDisplayed = !win.isVisibleLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002812 if (win.mExiting) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002813 winAnimator.cancelExitAnimationForNextAnimationLocked();
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002814 win.mExiting = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002815 }
2816 if (win.mDestroying) {
2817 win.mDestroying = false;
2818 mDestroySurface.remove(win);
2819 }
2820 if (oldVisibility == View.GONE) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002821 winAnimator.mEnterAnimationPending = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002822 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002823 if (toBeDisplayed) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07002824 if (win.isDrawnLw() && okToDisplay()) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002825 winAnimator.applyEnterAnimationLocked();
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002826 }
2827 if ((win.mAttrs.flags
2828 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2829 if (DEBUG_VISIBILITY) Slog.v(TAG,
2830 "Relayout window turning screen on: " + win);
2831 win.mTurnOnScreen = true;
2832 }
2833 int diff = 0;
2834 if (win.mConfiguration != mCurConfiguration
2835 && (win.mConfiguration == null
2836 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2837 win.mConfiguration = mCurConfiguration;
2838 if (DEBUG_CONFIGURATION) {
2839 Slog.i(TAG, "Window " + win + " visible with new config: "
2840 + win.mConfiguration + " / 0x"
2841 + Integer.toHexString(diff));
2842 }
2843 outConfig.setTo(mCurConfiguration);
2844 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002845 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002846 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2847 // To change the format, we need to re-build the surface.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002848 winAnimator.destroySurfaceLocked();
Craig Mautnerbf08af32012-05-16 19:43:42 -07002849 toBeDisplayed = true;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002850 surfaceChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002851 }
2852 try {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002853 if (!win.mHasSurface) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002854 surfaceChanged = true;
2855 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002856 Surface surface = winAnimator.createSurfaceLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002857 if (surface != null) {
2858 outSurface.copyFrom(surface);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002859 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002860 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002861 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002862 // For some reason there isn't a surface. Clear the
2863 // caller's object so they see the same state.
2864 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002865 }
2866 } catch (Exception e) {
Jeff Brown2e44b072011-01-24 15:21:56 -08002867 mInputMonitor.updateInputWindowsLw(true /*force*/);
Craig Mautner9e809442012-06-22 17:13:04 -07002868
Joe Onorato8a9b2202010-02-26 18:56:32 -08002869 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002870 + client + " (" + win.mAttrs.getTitle() + ")",
2871 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002872 Binder.restoreCallingIdentity(origId);
2873 return 0;
2874 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002875 if (toBeDisplayed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002876 focusMayChange = true;
2877 }
2878 if (win.mAttrs.type == TYPE_INPUT_METHOD
2879 && mInputMethodWindow == null) {
2880 mInputMethodWindow = win;
2881 imMayMove = true;
2882 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002883 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2884 && win.mAppToken != null
2885 && win.mAppToken.startingWindow != null) {
2886 // Special handling of starting window over the base
2887 // window of the app: propagate lock screen flags to it,
2888 // to provide the correct semantics while starting.
2889 final int mask =
2890 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002891 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2892 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002893 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2894 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2895 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002896 } else {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002897 winAnimator.mEnterAnimationPending = false;
2898 if (winAnimator.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002899 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Craig Mautnerbf08af32012-05-16 19:43:42 -07002900 + ": mExiting=" + win.mExiting);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002901 // If we are not currently running the exit animation, we
2902 // need to see about starting one.
Craig Mautnerbf08af32012-05-16 19:43:42 -07002903 if (!win.mExiting) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002904 surfaceChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002905 // Try starting an animation; if there isn't one, we
2906 // can destroy the surface right away.
2907 int transit = WindowManagerPolicy.TRANSIT_EXIT;
Craig Mautnerbb1449b2012-03-23 16:11:14 -07002908 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002909 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2910 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002911 if (win.isWinVisibleLw() &&
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002912 winAnimator.applyAnimationLocked(transit, false)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002913 focusMayChange = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002914 win.mExiting = true;
Craig Mautnera2c77052012-03-26 12:14:43 -07002915 } else if (win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002916 // Currently in a hide animation... turn this into
2917 // an exit.
2918 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002919 } else if (win == mWallpaperTarget) {
2920 // If the wallpaper is currently behind this
2921 // window, we need to change both of them inside
2922 // of a transaction to avoid artifacts.
2923 win.mExiting = true;
Craig Mautnera2c77052012-03-26 12:14:43 -07002924 win.mWinAnimator.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002925 } else {
2926 if (mInputMethodWindow == win) {
2927 mInputMethodWindow = null;
2928 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002929 winAnimator.destroySurfaceLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002930 }
2931 }
2932 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002933
Craig Mautnerbf08af32012-05-16 19:43:42 -07002934 outSurface.release();
2935 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002936 }
2937
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002938 if (focusMayChange) {
2939 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
Jeff Brown3a22cd92011-01-21 13:59:04 -08002940 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2941 false /*updateInputWindows*/)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002942 imMayMove = false;
2943 }
2944 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2945 }
Romain Guy06882f82009-06-10 13:36:04 -07002946
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002947 // updateFocusedWindowLocked() already assigned layers so we only need to
2948 // reassign them at this point if the IM window state gets shuffled
2949 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002950
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002951 if (imMayMove) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07002952 if (moveInputMethodWindowsIfNeededLocked(false) || toBeDisplayed) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002953 // Little hack here -- we -should- be able to rely on the
2954 // function to return true if the IME has moved and needs
2955 // its layer recomputed. However, if the IME was hidden
2956 // and isn't actually moved in the list, its layer may be
2957 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002958 assignLayers = true;
2959 }
2960 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002961 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002962 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002963 assignLayers = true;
2964 }
2965 }
Romain Guy06882f82009-06-10 13:36:04 -07002966
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002967 mLayoutNeeded = true;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002968 win.mGivenInsetsPending = (flags&WindowManagerImpl.RELAYOUT_INSETS_PENDING) != 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002969 if (assignLayers) {
Craig Mautner59c00972012-07-30 12:10:24 -07002970 assignLayersLocked(win.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002971 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002972 configChanged = updateOrientationFromAppTokensLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002973 performLayoutAndPlaceSurfacesLocked();
Craig Mautnerbf08af32012-05-16 19:43:42 -07002974 if (toBeDisplayed && win.mIsWallpaper) {
Craig Mautner59c00972012-07-30 12:10:24 -07002975 DisplayInfo displayInfo = getDefaultDisplayInfo();
Jeff Brownfa25bf52012-07-23 19:26:30 -07002976 updateWallpaperOffsetLocked(win,
Craig Mautner59c00972012-07-30 12:10:24 -07002977 displayInfo.appWidth, displayInfo.appHeight, false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002978 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002979 if (win.mAppToken != null) {
2980 win.mAppToken.updateReportedVisibilityLocked();
2981 }
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002982 outFrame.set(win.mCompatFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002983 outContentInsets.set(win.mContentInsets);
2984 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002985 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002986 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002987 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002988 + ", requestedHeight=" + requestedHeight
2989 + ", viewVisibility=" + viewVisibility
2990 + "\nRelayout returning frame=" + outFrame
2991 + ", surface=" + outSurface);
2992
Joe Onorato8a9b2202010-02-26 18:56:32 -08002993 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002994 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
2995
2996 inTouchMode = mInTouchMode;
Dianne Hackborn12d3a942012-04-27 14:16:30 -07002997 animating = mAnimator.mAnimating;
2998 if (animating && !mRelayoutWhileAnimating.contains(win)) {
2999 mRelayoutWhileAnimating.add(win);
3000 }
3001
Jeff Brown2e44b072011-01-24 15:21:56 -08003002 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003003 }
3004
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003005 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003006 sendNewConfiguration();
3007 }
Romain Guy06882f82009-06-10 13:36:04 -07003008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003009 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07003010
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003011 return (inTouchMode ? WindowManagerImpl.RELAYOUT_RES_IN_TOUCH_MODE : 0)
Craig Mautnerbf08af32012-05-16 19:43:42 -07003012 | (toBeDisplayed ? WindowManagerImpl.RELAYOUT_RES_FIRST_TIME : 0)
Dianne Hackborn12d3a942012-04-27 14:16:30 -07003013 | (surfaceChanged ? WindowManagerImpl.RELAYOUT_RES_SURFACE_CHANGED : 0)
3014 | (animating ? WindowManagerImpl.RELAYOUT_RES_ANIMATING : 0);
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003015 }
3016
3017 public void performDeferredDestroyWindow(Session session, IWindow client) {
3018 long origId = Binder.clearCallingIdentity();
3019
3020 try {
3021 synchronized(mWindowMap) {
3022 WindowState win = windowForClientLocked(session, client, false);
3023 if (win == null) {
3024 return;
3025 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003026 win.mWinAnimator.destroyDeferredSurfaceLocked();
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003027 }
3028 } finally {
3029 Binder.restoreCallingIdentity(origId);
3030 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003031 }
3032
Dianne Hackborn64825172011-03-02 21:32:58 -08003033 public boolean outOfMemoryWindow(Session session, IWindow client) {
3034 long origId = Binder.clearCallingIdentity();
3035
3036 try {
3037 synchronized(mWindowMap) {
3038 WindowState win = windowForClientLocked(session, client, false);
3039 if (win == null) {
3040 return false;
3041 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003042 return reclaimSomeSurfaceMemoryLocked(win.mWinAnimator, "from-client", false);
Dianne Hackborn64825172011-03-02 21:32:58 -08003043 }
3044 } finally {
3045 Binder.restoreCallingIdentity(origId);
3046 }
3047 }
3048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003049 public void finishDrawingWindow(Session session, IWindow client) {
3050 final long origId = Binder.clearCallingIdentity();
3051 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003052 WindowState win = windowForClientLocked(session, client, false);
Craig Mautnera608b882012-03-30 13:03:49 -07003053 if (win != null && win.mWinAnimator.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07003054 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
3055 adjustWallpaperWindowsLocked();
3056 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003057 mLayoutNeeded = true;
3058 performLayoutAndPlaceSurfacesLocked();
3059 }
3060 }
3061 Binder.restoreCallingIdentity(origId);
3062 }
3063
Svetoslav Ganov7961be72011-06-21 12:31:56 -07003064 public float getWindowCompatibilityScale(IBinder windowToken) {
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07003065 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
3066 "getWindowCompatibilityScale()")) {
3067 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
3068 }
Svetoslav Ganov7961be72011-06-21 12:31:56 -07003069 synchronized (mWindowMap) {
3070 WindowState windowState = mWindowMap.get(windowToken);
3071 return (windowState != null) ? windowState.mGlobalScale : 1.0f;
3072 }
3073 }
3074
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003075 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Dianne Hackborn08121bc2011-01-17 17:54:31 -08003076 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: layout params pkg="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003077 + (lp != null ? lp.packageName : null)
3078 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
3079 if (lp != null && lp.windowAnimations != 0) {
3080 // If this is a system resource, don't try to load it from the
3081 // application resources. It is nice to avoid loading application
3082 // resources if we can.
3083 String packageName = lp.packageName != null ? lp.packageName : "android";
3084 int resId = lp.windowAnimations;
3085 if ((resId&0xFF000000) == 0x01000000) {
3086 packageName = "android";
3087 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003088 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003089 + packageName);
3090 return AttributeCache.instance().get(packageName, resId,
3091 com.android.internal.R.styleable.WindowAnimation);
3092 }
3093 return null;
3094 }
Romain Guy06882f82009-06-10 13:36:04 -07003095
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003096 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Dianne Hackborn08121bc2011-01-17 17:54:31 -08003097 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003098 + packageName + " resId=0x" + Integer.toHexString(resId));
3099 if (packageName != null) {
3100 if ((resId&0xFF000000) == 0x01000000) {
3101 packageName = "android";
3102 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003103 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003104 + packageName);
3105 return AttributeCache.instance().get(packageName, resId,
3106 com.android.internal.R.styleable.WindowAnimation);
3107 }
3108 return null;
3109 }
3110
Craig Mautnere7ae2502012-03-26 17:11:19 -07003111 Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003112 int anim = 0;
3113 Context context = mContext;
3114 if (animAttr >= 0) {
3115 AttributeCache.Entry ent = getCachedAnimations(lp);
3116 if (ent != null) {
3117 context = ent.context;
3118 anim = ent.array.getResourceId(animAttr, 0);
3119 }
3120 }
3121 if (anim != 0) {
3122 return AnimationUtils.loadAnimation(context, anim);
3123 }
3124 return null;
3125 }
Romain Guy06882f82009-06-10 13:36:04 -07003126
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003127 private Animation loadAnimation(String packageName, int resId) {
3128 int anim = 0;
3129 Context context = mContext;
3130 if (resId >= 0) {
3131 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
3132 if (ent != null) {
3133 context = ent.context;
3134 anim = resId;
3135 }
3136 }
3137 if (anim != 0) {
3138 return AnimationUtils.loadAnimation(context, anim);
3139 }
3140 return null;
3141 }
3142
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003143 private Animation createExitAnimationLocked(int transit, int duration) {
3144 if (transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN ||
3145 transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE) {
3146 // If we are on top of the wallpaper, we need an animation that
3147 // correctly handles the wallpaper staying static behind all of
3148 // the animated elements. To do this, will just have the existing
3149 // element fade out.
3150 Animation a = new AlphaAnimation(1, 0);
3151 a.setDetachWallpaper(true);
3152 a.setDuration(duration);
3153 return a;
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003154 }
Craig Mautner01cd0e72012-06-18 10:19:11 -07003155 // For normal animations, the exiting element just holds in place.
3156 Animation a = new AlphaAnimation(1, 1);
3157 a.setDuration(duration);
3158 return a;
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003159 }
3160
3161 /**
3162 * Compute the pivot point for an animation that is scaling from a small
3163 * rect on screen to a larger rect. The pivot point varies depending on
3164 * the distance between the inner and outer edges on both sides. This
3165 * function computes the pivot point for one dimension.
3166 * @param startPos Offset from left/top edge of outer rectangle to
3167 * left/top edge of inner rectangle.
3168 * @param finalScale The scaling factor between the size of the outer
3169 * and inner rectangles.
3170 */
3171 private static float computePivot(int startPos, float finalScale) {
3172 final float denom = finalScale-1;
3173 if (Math.abs(denom) < .0001f) {
3174 return startPos;
3175 }
3176 return -startPos / denom;
3177 }
3178
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003179 private Animation createScaleUpAnimationLocked(int transit, boolean enter) {
3180 Animation a;
3181 // Pick the desired duration. If this is an inter-activity transition,
3182 // it is the standard duration for that. Otherwise we use the longer
3183 // task transition duration.
3184 int duration;
3185 switch (transit) {
3186 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3187 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3188 duration = mContext.getResources().getInteger(
3189 com.android.internal.R.integer.config_shortAnimTime);
3190 break;
3191 default:
Winson Chungdc6f79b2012-04-17 17:27:31 -07003192 duration = 300;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003193 break;
3194 }
Craig Mautner59c00972012-07-30 12:10:24 -07003195 // TODO(multidisplay): For now assume all app animation is on main display.
3196 final DisplayInfo displayInfo = getDefaultDisplayInfo();
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003197 if (enter) {
3198 // Entering app zooms out from the center of the initial rect.
Craig Mautner59c00972012-07-30 12:10:24 -07003199 float scaleW = mNextAppTransitionStartWidth / (float) displayInfo.appWidth;
3200 float scaleH = mNextAppTransitionStartHeight / (float) displayInfo.appHeight;
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003201 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
3202 computePivot(mNextAppTransitionStartX, scaleW),
3203 computePivot(mNextAppTransitionStartY, scaleH));
3204 scale.setDuration(duration);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003205 AnimationSet set = new AnimationSet(true);
3206 Animation alpha = new AlphaAnimation(0, 1);
3207 scale.setDuration(duration);
3208 set.addAnimation(scale);
3209 alpha.setDuration(duration);
3210 set.addAnimation(alpha);
Craig Mautnera8033712012-06-12 15:50:45 -07003211 set.setDetachWallpaper(true);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003212 a = set;
3213 } else {
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003214 a = createExitAnimationLocked(transit, duration);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003215 }
3216 a.setFillAfter(true);
3217 final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
Winson Chungdc6f79b2012-04-17 17:27:31 -07003218 com.android.internal.R.interpolator.decelerate_cubic);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003219 a.setInterpolator(interpolator);
Craig Mautner59c00972012-07-30 12:10:24 -07003220 a.initialize(displayInfo.appWidth, displayInfo.appHeight,
3221 displayInfo.appWidth, displayInfo.appHeight);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003222 return a;
3223 }
3224
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003225 private Animation createThumbnailAnimationLocked(int transit,
Michael Jurka21385cd2012-05-03 10:57:31 -07003226 boolean enter, boolean thumb, boolean delayed) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003227 Animation a;
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003228 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
3229 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
3230 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
3231 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003232 // Pick the desired duration. If this is an inter-activity transition,
3233 // it is the standard duration for that. Otherwise we use the longer
3234 // task transition duration.
3235 int duration;
Michael Jurkac016aaa2012-06-05 17:22:24 -07003236 int delayDuration = delayed ? 270 : 0;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003237 switch (transit) {
3238 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3239 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3240 duration = mContext.getResources().getInteger(
3241 com.android.internal.R.integer.config_shortAnimTime);
3242 break;
3243 default:
Michael Jurkac016aaa2012-06-05 17:22:24 -07003244 duration = delayed ? 250 : 300;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003245 break;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003246 }
Craig Mautner59c00972012-07-30 12:10:24 -07003247 // TOOD(multidisplay): For now assume all app animation is on the main screen.
3248 DisplayInfo displayInfo = getDefaultDisplayInfo();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003249 if (thumb) {
3250 // Animation for zooming thumbnail from its initial size to
3251 // filling the screen.
Craig Mautner59c00972012-07-30 12:10:24 -07003252 float scaleW = displayInfo.appWidth/thumbWidth;
3253 float scaleH = displayInfo.appHeight/thumbHeight;
Michael Jurka21385cd2012-05-03 10:57:31 -07003254
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003255 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
3256 computePivot(mNextAppTransitionStartX, 1/scaleW),
3257 computePivot(mNextAppTransitionStartY, 1/scaleH));
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003258 AnimationSet set = new AnimationSet(true);
3259 Animation alpha = new AlphaAnimation(1, 0);
3260 scale.setDuration(duration);
Michael Jurkac016aaa2012-06-05 17:22:24 -07003261 scale.setInterpolator(
3262 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003263 set.addAnimation(scale);
3264 alpha.setDuration(duration);
3265 set.addAnimation(alpha);
Michael Jurka21385cd2012-05-03 10:57:31 -07003266 set.setFillBefore(true);
3267 if (delayDuration > 0) {
3268 set.setStartOffset(delayDuration);
3269 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003270 a = set;
3271 } else if (enter) {
3272 // Entering app zooms out from the center of the thumbnail.
Craig Mautner59c00972012-07-30 12:10:24 -07003273 float scaleW = thumbWidth / displayInfo.appWidth;
3274 float scaleH = thumbHeight / displayInfo.appHeight;
Michael Jurka21385cd2012-05-03 10:57:31 -07003275 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003276 computePivot(mNextAppTransitionStartX, scaleW),
3277 computePivot(mNextAppTransitionStartY, scaleH));
Michael Jurka21385cd2012-05-03 10:57:31 -07003278 scale.setDuration(duration);
Michael Jurkac016aaa2012-06-05 17:22:24 -07003279 scale.setInterpolator(
3280 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
Michael Jurka21385cd2012-05-03 10:57:31 -07003281 scale.setFillBefore(true);
Michael Jurka21385cd2012-05-03 10:57:31 -07003282 if (delayDuration > 0) {
Michael Jurkad5895a72012-05-12 13:24:58 -07003283 scale.setStartOffset(delayDuration);
Michael Jurka21385cd2012-05-03 10:57:31 -07003284 }
Michael Jurkad5895a72012-05-12 13:24:58 -07003285 a = scale;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003286 } else {
Michael Jurkad5895a72012-05-12 13:24:58 -07003287 if (delayed) {
3288 a = new AlphaAnimation(1, 0);
3289 a.setStartOffset(0);
Michael Jurkab9a38c52012-06-14 11:57:50 -07003290 a.setDuration(delayDuration - 120);
Michael Jurkad5895a72012-05-12 13:24:58 -07003291 a.setBackgroundColor(0xFF000000);
3292 } else {
3293 a = createExitAnimationLocked(transit, duration);
Michael Jurka21385cd2012-05-03 10:57:31 -07003294 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003295 }
3296 a.setFillAfter(true);
3297 final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003298 com.android.internal.R.interpolator.decelerate_quad);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003299 a.setInterpolator(interpolator);
Craig Mautner59c00972012-07-30 12:10:24 -07003300 a.initialize(displayInfo.appWidth, displayInfo.appHeight,
3301 displayInfo.appWidth, displayInfo.appHeight);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003302 return a;
3303 }
3304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003305 private boolean applyAnimationLocked(AppWindowToken wtoken,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07003306 WindowManager.LayoutParams lp, int transit, boolean enter) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003307 // Only apply an animation if the display isn't frozen. If it is
3308 // frozen, there is no reason to animate and it can cause strange
3309 // artifacts when we unfreeze the display if some different animation
3310 // is running.
Craig Mautner2fb98b12012-03-20 17:24:00 -07003311 if (okToDisplay()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003312 Animation a;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003313 boolean initialized = false;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003314 if (mNextAppTransitionType == ActivityOptions.ANIM_CUSTOM) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003315 a = loadAnimation(mNextAppTransitionPackage, enter ?
3316 mNextAppTransitionEnter : mNextAppTransitionExit);
Daniel Sandlerab886f52012-06-04 14:36:25 -04003317 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
3318 "applyAnimation: wtoken=" + wtoken
Craig Mautner83339b42012-05-01 22:13:23 -07003319 + " anim=" + a + " nextAppTransition=ANIM_CUSTOM"
3320 + " transit=" + transit + " Callers " + Debug.getCallers(3));
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003321 } else if (mNextAppTransitionType == ActivityOptions.ANIM_SCALE_UP) {
3322 a = createScaleUpAnimationLocked(transit, enter);
3323 initialized = true;
Daniel Sandlerab886f52012-06-04 14:36:25 -04003324 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
3325 "applyAnimation: wtoken=" + wtoken
Craig Mautner83339b42012-05-01 22:13:23 -07003326 + " anim=" + a + " nextAppTransition=ANIM_SCALE_UP"
3327 + " transit=" + transit + " Callers " + Debug.getCallers(3));
Michael Jurka21385cd2012-05-03 10:57:31 -07003328 } else if (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL ||
3329 mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_DELAYED) {
3330 boolean delayed = (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_DELAYED);
3331 a = createThumbnailAnimationLocked(transit, enter, false, delayed);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003332 initialized = true;
Michael Jurka21385cd2012-05-03 10:57:31 -07003333
Daniel Sandlerab886f52012-06-04 14:36:25 -04003334 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
Michael Jurka21385cd2012-05-03 10:57:31 -07003335 String animName = delayed ? "ANIM_THUMBNAIL_DELAYED" : "ANIM_THUMBNAIL";
3336 Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
3337 + " anim=" + a + " nextAppTransition=" + animName
3338 + " transit=" + transit + " Callers " + Debug.getCallers(3));
3339 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003340 } else {
3341 int animAttr = 0;
3342 switch (transit) {
3343 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3344 animAttr = enter
3345 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
3346 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
3347 break;
3348 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3349 animAttr = enter
3350 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
3351 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
3352 break;
3353 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
3354 animAttr = enter
3355 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
3356 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
3357 break;
3358 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
3359 animAttr = enter
3360 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
3361 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
3362 break;
3363 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
3364 animAttr = enter
3365 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
3366 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
3367 break;
3368 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
3369 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07003370 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003371 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
3372 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003373 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003374 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003375 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
3376 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003377 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003378 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003379 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003380 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
3381 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
3382 break;
3383 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
3384 animAttr = enter
3385 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
3386 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
3387 break;
3388 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
3389 animAttr = enter
3390 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
3391 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003392 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003393 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003394 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Daniel Sandlerab886f52012-06-04 14:36:25 -04003395 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
3396 "applyAnimation: wtoken=" + wtoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003397 + " anim=" + a
3398 + " animAttr=0x" + Integer.toHexString(animAttr)
Craig Mautner83339b42012-05-01 22:13:23 -07003399 + " transit=" + transit + " Callers " + Debug.getCallers(3));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003400 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003401 if (a != null) {
3402 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003403 RuntimeException e = null;
3404 if (!HIDE_STACK_CRAWLS) {
3405 e = new RuntimeException();
3406 e.fillInStackTrace();
3407 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003408 Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003409 }
Craig Mautner59431632012-04-04 11:56:44 -07003410 wtoken.mAppAnimator.setAnimation(a, initialized);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003411 }
3412 } else {
Craig Mautner59431632012-04-04 11:56:44 -07003413 wtoken.mAppAnimator.clearAnimation();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003414 }
3415
Craig Mautner59431632012-04-04 11:56:44 -07003416 return wtoken.mAppAnimator.animation != null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003417 }
3418
3419 // -------------------------------------------------------------
3420 // Application Window Tokens
3421 // -------------------------------------------------------------
3422
Dianne Hackbornbe707852011-11-11 14:32:10 -08003423 public void validateAppTokens(List<IBinder> tokens) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003424 int v = tokens.size()-1;
3425 int m = mAppTokens.size()-1;
3426 while (v >= 0 && m >= 0) {
3427 AppWindowToken wtoken = mAppTokens.get(m);
3428 if (wtoken.removed) {
3429 m--;
3430 continue;
3431 }
3432 if (tokens.get(v) != wtoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003433 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003434 + " @ " + v + ", internal is " + wtoken.token + " @ " + m);
3435 }
3436 v--;
3437 m--;
3438 }
3439 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003440 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003441 v--;
3442 }
3443 while (m >= 0) {
3444 AppWindowToken wtoken = mAppTokens.get(m);
3445 if (!wtoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003446 Slog.w(TAG, "Invalid internal token: " + wtoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003447 }
3448 m--;
3449 }
3450 }
3451
3452 boolean checkCallingPermission(String permission, String func) {
3453 // Quick check: if the calling permission is me, it's all okay.
3454 if (Binder.getCallingPid() == Process.myPid()) {
3455 return true;
3456 }
Romain Guy06882f82009-06-10 13:36:04 -07003457
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003458 if (mContext.checkCallingPermission(permission)
3459 == PackageManager.PERMISSION_GRANTED) {
3460 return true;
3461 }
3462 String msg = "Permission Denial: " + func + " from pid="
3463 + Binder.getCallingPid()
3464 + ", uid=" + Binder.getCallingUid()
3465 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003466 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003467 return false;
3468 }
Craig Mautner9e809442012-06-22 17:13:04 -07003469
Craig Mautner2fb98b12012-03-20 17:24:00 -07003470 boolean okToDisplay() {
3471 return !mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully();
3472 }
Romain Guy06882f82009-06-10 13:36:04 -07003473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003474 AppWindowToken findAppWindowToken(IBinder token) {
3475 WindowToken wtoken = mTokenMap.get(token);
3476 if (wtoken == null) {
3477 return null;
3478 }
3479 return wtoken.appWindowToken;
3480 }
Romain Guy06882f82009-06-10 13:36:04 -07003481
Craig Mautnercf8cbbe2012-03-25 21:54:36 -07003482 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003483 public void addWindowToken(IBinder token, int type) {
3484 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3485 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003486 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003487 }
Romain Guy06882f82009-06-10 13:36:04 -07003488
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003489 synchronized(mWindowMap) {
3490 WindowToken wtoken = mTokenMap.get(token);
3491 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003492 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003493 return;
3494 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003495 wtoken = new WindowToken(this, token, type, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003496 mTokenMap.put(token, wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003497 if (type == TYPE_WALLPAPER) {
3498 mWallpaperTokens.add(wtoken);
Craig Mautner918b53b2012-07-09 14:15:54 -07003499 updateLayoutToAnimWallpaperTokens();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003500 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003501 }
3502 }
Romain Guy06882f82009-06-10 13:36:04 -07003503
Craig Mautner9e809442012-06-22 17:13:04 -07003504 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003505 public void removeWindowToken(IBinder token) {
3506 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3507 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003508 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003509 }
3510
3511 final long origId = Binder.clearCallingIdentity();
3512 synchronized(mWindowMap) {
3513 WindowToken wtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003514 if (wtoken != null) {
3515 boolean delayed = false;
3516 if (!wtoken.hidden) {
3517 wtoken.hidden = true;
Romain Guy06882f82009-06-10 13:36:04 -07003518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003519 final int N = wtoken.windows.size();
3520 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003522 for (int i=0; i<N; i++) {
3523 WindowState win = wtoken.windows.get(i);
3524
Craig Mautnera2c77052012-03-26 12:14:43 -07003525 if (win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003526 delayed = true;
3527 }
Romain Guy06882f82009-06-10 13:36:04 -07003528
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003529 if (win.isVisibleNow()) {
Craig Mautner59c00972012-07-30 12:10:24 -07003530 win.mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT,
3531 false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003532 changed = true;
3533 }
3534 }
3535
3536 if (changed) {
3537 mLayoutNeeded = true;
3538 performLayoutAndPlaceSurfacesLocked();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003539 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
3540 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003541 }
Romain Guy06882f82009-06-10 13:36:04 -07003542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003543 if (delayed) {
3544 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003545 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3546 mWallpaperTokens.remove(wtoken);
Craig Mautner918b53b2012-07-09 14:15:54 -07003547 updateLayoutToAnimWallpaperTokens();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003548 }
3549 }
Romain Guy06882f82009-06-10 13:36:04 -07003550
Jeff Brown2e44b072011-01-24 15:21:56 -08003551 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003552 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003553 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003554 }
3555 }
3556 Binder.restoreCallingIdentity(origId);
3557 }
3558
Craig Mautneref25d7a2012-05-15 23:01:47 -07003559 /**
3560 * Find the location to insert a new AppWindowToken into the window-ordered app token list.
3561 * Note that mAppTokens.size() == mAnimatingAppTokens.size() + 1.
3562 * @param addPos The location the token was inserted into in mAppTokens.
3563 * @param wtoken The token to insert.
3564 */
3565 private void addAppTokenToAnimating(final int addPos, final AppWindowToken wtoken) {
3566 if (addPos == 0 || addPos == mAnimatingAppTokens.size()) {
3567 // It was inserted into the beginning or end of mAppTokens. Honor that.
3568 mAnimatingAppTokens.add(addPos, wtoken);
3569 return;
3570 }
3571 // Find the item immediately above the mAppTokens insertion point and put the token
3572 // immediately below that one in mAnimatingAppTokens.
3573 final AppWindowToken aboveAnchor = mAppTokens.get(addPos + 1);
3574 mAnimatingAppTokens.add(mAnimatingAppTokens.indexOf(aboveAnchor), wtoken);
3575 }
3576
3577 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003578 public void addAppToken(int addPos, IApplicationToken token,
3579 int groupId, int requestedOrientation, boolean fullscreen) {
3580 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3581 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003582 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003583 }
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07003584
Jeff Brown349703e2010-06-22 01:27:15 -07003585 // Get the dispatching timeout here while we are not holding any locks so that it
3586 // can be cached by the AppWindowToken. The timeout value is used later by the
3587 // input dispatcher in code that does hold locks. If we did not cache the value
3588 // here we would run the chance of introducing a deadlock between the window manager
3589 // (which holds locks while updating the input dispatcher state) and the activity manager
3590 // (which holds locks while querying the application token).
3591 long inputDispatchingTimeoutNanos;
3592 try {
3593 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3594 } catch (RemoteException ex) {
3595 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3596 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3597 }
Romain Guy06882f82009-06-10 13:36:04 -07003598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003599 synchronized(mWindowMap) {
3600 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3601 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003602 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003603 return;
3604 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003605 wtoken = new AppWindowToken(this, token);
Jeff Brown349703e2010-06-22 01:27:15 -07003606 wtoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003607 wtoken.groupId = groupId;
3608 wtoken.appFullscreen = fullscreen;
3609 wtoken.requestedOrientation = requestedOrientation;
Craig Mautner06a94f72012-05-29 10:46:00 -07003610 if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + wtoken
3611 + " at " + addPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003612 mAppTokens.add(addPos, wtoken);
Craig Mautneref25d7a2012-05-15 23:01:47 -07003613 addAppTokenToAnimating(addPos, wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003614 mTokenMap.put(token.asBinder(), wtoken);
Romain Guy06882f82009-06-10 13:36:04 -07003615
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003616 // Application tokens start out hidden.
3617 wtoken.hidden = true;
3618 wtoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003619
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003620 //dump();
3621 }
3622 }
Romain Guy06882f82009-06-10 13:36:04 -07003623
Craig Mautner9e809442012-06-22 17:13:04 -07003624 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003625 public void setAppGroupId(IBinder token, int groupId) {
3626 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner6fbda632012-07-03 09:26:39 -07003627 "setAppGroupId()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003628 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003629 }
3630
3631 synchronized(mWindowMap) {
3632 AppWindowToken wtoken = findAppWindowToken(token);
3633 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003634 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003635 return;
3636 }
3637 wtoken.groupId = groupId;
3638 }
3639 }
Romain Guy06882f82009-06-10 13:36:04 -07003640
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003641 public int getOrientationFromWindowsLocked() {
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003642 if (mDisplayFrozen || mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
3643 // If the display is frozen, some activities may be in the middle
3644 // of restarting, and thus have removed their old window. If the
3645 // window has the flag to hide the lock screen, then the lock screen
3646 // can re-appear and inflict its own orientation on us. Keep the
3647 // orientation stable until this all settles down.
3648 return mLastWindowForcedOrientation;
3649 }
3650
Craig Mautner59c00972012-07-30 12:10:24 -07003651 // TODO(multidisplay): Change to the correct display.
3652 final WindowList windows = getDefaultWindowList();
3653 int pos = windows.size() - 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003654 while (pos >= 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07003655 WindowState wtoken = windows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003656 pos--;
3657 if (wtoken.mAppToken != null) {
3658 // We hit an application window. so the orientation will be determined by the
3659 // app window. No point in continuing further.
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003660 return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003661 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003662 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003663 continue;
3664 }
3665 int req = wtoken.mAttrs.screenOrientation;
3666 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3667 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3668 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003669 }
Craig Mautner9e809442012-06-22 17:13:04 -07003670
3671 return (mLastWindowForcedOrientation=req);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003672 }
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003673 return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003674 }
Romain Guy06882f82009-06-10 13:36:04 -07003675
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003676 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003677 int curGroup = 0;
3678 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3679 boolean findingBehind = false;
3680 boolean haveGroup = false;
3681 boolean lastFullscreen = false;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07003682 for (int pos = mAppTokens.size() - 1; pos >= 0; pos--) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003683 AppWindowToken wtoken = mAppTokens.get(pos);
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003684
3685 if (DEBUG_APP_ORIENTATION) Slog.v(TAG, "Checking app orientation: " + wtoken);
3686
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003687 // if we're about to tear down this window and not seek for
3688 // the behind activity, don't use it for orientation
3689 if (!findingBehind
3690 && (!wtoken.hidden && wtoken.hiddenRequested)) {
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003691 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + wtoken
3692 + " -- going to hide");
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003693 continue;
3694 }
3695
p134510445bc62012-04-18 15:13:26 +09003696 if (haveGroup == true && curGroup != wtoken.groupId) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003697 // If we have hit a new application group, and the bottom
3698 // of the previous group didn't explicitly say to use
3699 // the orientation behind it, and the last app was
3700 // full screen, then we'll stick with the
3701 // user's orientation.
3702 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3703 && lastFullscreen) {
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003704 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + wtoken
3705 + " -- end of group, return " + lastOrientation);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003706 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003707 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003708 }
p134510445bc62012-04-18 15:13:26 +09003709
3710 // We ignore any hidden applications on the top.
3711 if (wtoken.hiddenRequested || wtoken.willBeHidden) {
3712 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + wtoken
3713 + " -- hidden on top");
3714 continue;
3715 }
3716
3717 if (!haveGroup) {
3718 haveGroup = true;
3719 curGroup = wtoken.groupId;
3720 lastOrientation = wtoken.requestedOrientation;
Craig Mautner918b53b2012-07-09 14:15:54 -07003721 }
p134510445bc62012-04-18 15:13:26 +09003722
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003723 int or = wtoken.requestedOrientation;
3724 // If this application is fullscreen, and didn't explicitly say
3725 // to use the orientation behind it, then just take whatever
3726 // orientation it has and ignores whatever is under it.
3727 lastFullscreen = wtoken.appFullscreen;
3728 if (lastFullscreen
3729 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003730 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + wtoken
3731 + " -- full screen, return " + or);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003732 return or;
3733 }
3734 // If this application has requested an explicit orientation,
3735 // then use it.
Dianne Hackborne5439f22010-10-02 16:53:50 -07003736 if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
3737 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003738 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + wtoken
3739 + " -- explicitly set, return " + or);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003740 return or;
3741 }
3742 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3743 }
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003744 if (DEBUG_ORIENTATION) Slog.v(TAG, "No app is requesting an orientation");
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003745 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003746 }
Romain Guy06882f82009-06-10 13:36:04 -07003747
Craig Mautner711f90a2012-07-03 18:43:52 -07003748 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003749 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003750 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003751 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3752 "updateOrientationFromAppTokens()")) {
3753 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3754 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003755
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003756 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003757 long ident = Binder.clearCallingIdentity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003758
3759 synchronized(mWindowMap) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003760 config = updateOrientationFromAppTokensLocked(currentConfig,
3761 freezeThisOneIfNeeded);
3762 }
3763
3764 Binder.restoreCallingIdentity(ident);
3765 return config;
3766 }
3767
3768 private Configuration updateOrientationFromAppTokensLocked(
3769 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
3770 Configuration config = null;
3771
3772 if (updateOrientationFromAppTokensLocked(false)) {
3773 if (freezeThisOneIfNeeded != null) {
3774 AppWindowToken wtoken = findAppWindowToken(
3775 freezeThisOneIfNeeded);
3776 if (wtoken != null) {
3777 startAppFreezingScreenLocked(wtoken,
3778 ActivityInfo.CONFIG_ORIENTATION);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003779 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003780 }
3781 config = computeNewConfigurationLocked();
3782
3783 } else if (currentConfig != null) {
3784 // No obvious action we need to take, but if our current
3785 // state mismatches the activity manager's, update it,
3786 // disregarding font scale, which should remain set to
3787 // the value of the previous configuration.
3788 mTempConfiguration.setToDefaults();
3789 mTempConfiguration.fontScale = currentConfig.fontScale;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08003790 if (computeScreenConfigurationLocked(mTempConfiguration)) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003791 if (currentConfig.diff(mTempConfiguration) != 0) {
3792 mWaitingForConfig = true;
3793 mLayoutNeeded = true;
3794 startFreezingDisplayLocked(false);
3795 config = new Configuration(mTempConfiguration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003796 }
3797 }
3798 }
3799
Dianne Hackborncfaef692009-06-15 14:24:44 -07003800 return config;
3801 }
3802
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003803 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003804 * Determine the new desired orientation of the display, returning
3805 * a non-null new Configuration if it has changed from the current
3806 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3807 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3808 * SCREEN. This will typically be done for you if you call
3809 * sendNewConfiguration().
3810 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003811 * The orientation is computed from non-application windows first. If none of
3812 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003813 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003814 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3815 * android.os.IBinder)
3816 */
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003817 boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003818 long ident = Binder.clearCallingIdentity();
3819 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003820 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003821
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003822 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003823 mForcedAppOrientation = req;
3824 //send a message to Policy indicating orientation change to take
3825 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003826 mPolicy.setCurrentOrientationLw(req);
Jeff Brown01a98dd2011-09-20 15:08:29 -07003827 if (updateRotationUncheckedLocked(inTransaction)) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003828 // changed
3829 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003830 }
3831 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003832
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003833 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003834 } finally {
3835 Binder.restoreCallingIdentity(ident);
3836 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003837 }
Romain Guy06882f82009-06-10 13:36:04 -07003838
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003839 int computeForcedAppOrientationLocked() {
3840 int req = getOrientationFromWindowsLocked();
3841 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3842 req = getOrientationFromAppTokensLocked();
3843 }
3844 return req;
3845 }
Romain Guy06882f82009-06-10 13:36:04 -07003846
Craig Mautner918b53b2012-07-09 14:15:54 -07003847 @Override
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003848 public void setNewConfiguration(Configuration config) {
3849 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3850 "setNewConfiguration()")) {
3851 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3852 }
3853
3854 synchronized(mWindowMap) {
3855 mCurConfiguration = new Configuration(config);
3856 mWaitingForConfig = false;
3857 performLayoutAndPlaceSurfacesLocked();
3858 }
3859 }
Craig Mautner918b53b2012-07-09 14:15:54 -07003860
3861 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003862 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3863 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3864 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003865 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003866 }
Romain Guy06882f82009-06-10 13:36:04 -07003867
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003868 synchronized(mWindowMap) {
3869 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3870 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003871 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003872 return;
3873 }
Romain Guy06882f82009-06-10 13:36:04 -07003874
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003875 wtoken.requestedOrientation = requestedOrientation;
3876 }
3877 }
Romain Guy06882f82009-06-10 13:36:04 -07003878
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003879 public int getAppOrientation(IApplicationToken token) {
3880 synchronized(mWindowMap) {
3881 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3882 if (wtoken == null) {
3883 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3884 }
Romain Guy06882f82009-06-10 13:36:04 -07003885
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003886 return wtoken.requestedOrientation;
3887 }
3888 }
Romain Guy06882f82009-06-10 13:36:04 -07003889
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003890 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3891 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3892 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003893 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003894 }
3895
3896 synchronized(mWindowMap) {
3897 boolean changed = false;
3898 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003899 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003900 changed = mFocusedApp != null;
3901 mFocusedApp = null;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003902 if (changed) {
3903 mInputMonitor.setFocusedAppLw(null);
Jeff Brown349703e2010-06-22 01:27:15 -07003904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003905 } else {
3906 AppWindowToken newFocus = findAppWindowToken(token);
3907 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003908 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003909 return;
3910 }
3911 changed = mFocusedApp != newFocus;
3912 mFocusedApp = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003913 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003914 if (changed) {
3915 mInputMonitor.setFocusedAppLw(newFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07003916 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003917 }
3918
3919 if (moveFocusNow && changed) {
3920 final long origId = Binder.clearCallingIdentity();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003921 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003922 Binder.restoreCallingIdentity(origId);
3923 }
3924 }
3925 }
3926
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003927 public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003928 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3929 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003930 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003931 }
Romain Guy06882f82009-06-10 13:36:04 -07003932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003933 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003934 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003935 TAG, "Prepare app transition: transit=" + transit
Craig Mautner0afddcb2012-05-08 15:38:00 -07003936 + " mNextAppTransition=" + mNextAppTransition
Craig Mautner1d961d42012-05-27 12:02:11 -07003937 + " alwaysKeepCurrent=" + alwaysKeepCurrent
Craig Mautneref25d7a2012-05-15 23:01:47 -07003938 + " Callers=" + Debug.getCallers(3));
Craig Mautner2fb98b12012-03-20 17:24:00 -07003939 if (okToDisplay()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003940 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
3941 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003942 mNextAppTransition = transit;
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003943 } else if (!alwaysKeepCurrent) {
3944 if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
3945 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
3946 // Opening a new task always supersedes a close for the anim.
3947 mNextAppTransition = transit;
3948 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
3949 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
3950 // Opening a new activity always supersedes a close for the anim.
3951 mNextAppTransition = transit;
3952 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003953 }
3954 mAppTransitionReady = false;
3955 mAppTransitionTimeout = false;
3956 mStartingIconInTransition = false;
3957 mSkipAppTransitionAnimation = false;
3958 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
3959 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
3960 5000);
3961 }
3962 }
3963 }
3964
3965 public int getPendingAppTransition() {
3966 return mNextAppTransition;
3967 }
Romain Guy06882f82009-06-10 13:36:04 -07003968
Dianne Hackborn84375872012-06-01 19:03:50 -07003969 private void scheduleAnimationCallback(IRemoteCallback cb) {
3970 if (cb != null) {
3971 mH.sendMessage(mH.obtainMessage(H.DO_ANIMATION_CALLBACK, cb));
3972 }
3973 }
3974
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003975 public void overridePendingAppTransition(String packageName,
Dianne Hackborn84375872012-06-01 19:03:50 -07003976 int enterAnim, int exitAnim, IRemoteCallback startedCallback) {
3977 synchronized(mWindowMap) {
3978 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
3979 mNextAppTransitionType = ActivityOptions.ANIM_CUSTOM;
3980 mNextAppTransitionPackage = packageName;
3981 mNextAppTransitionThumbnail = null;
3982 mNextAppTransitionEnter = enterAnim;
3983 mNextAppTransitionExit = exitAnim;
3984 scheduleAnimationCallback(mNextAppTransitionCallback);
3985 mNextAppTransitionCallback = startedCallback;
3986 } else {
3987 scheduleAnimationCallback(startedCallback);
3988 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003989 }
3990 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003991
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003992 public void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
3993 int startHeight) {
Dianne Hackborn84375872012-06-01 19:03:50 -07003994 synchronized(mWindowMap) {
3995 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
3996 mNextAppTransitionType = ActivityOptions.ANIM_SCALE_UP;
3997 mNextAppTransitionPackage = null;
3998 mNextAppTransitionThumbnail = null;
3999 mNextAppTransitionStartX = startX;
4000 mNextAppTransitionStartY = startY;
4001 mNextAppTransitionStartWidth = startWidth;
4002 mNextAppTransitionStartHeight = startHeight;
4003 scheduleAnimationCallback(mNextAppTransitionCallback);
4004 mNextAppTransitionCallback = null;
4005 }
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07004006 }
4007 }
4008
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004009 public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX,
Michael Jurka21385cd2012-05-03 10:57:31 -07004010 int startY, IRemoteCallback startedCallback, boolean delayed) {
Dianne Hackborn84375872012-06-01 19:03:50 -07004011 synchronized(mWindowMap) {
4012 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
4013 mNextAppTransitionType = delayed
4014 ? ActivityOptions.ANIM_THUMBNAIL_DELAYED : ActivityOptions.ANIM_THUMBNAIL;
4015 mNextAppTransitionPackage = null;
4016 mNextAppTransitionThumbnail = srcThumb;
4017 mNextAppTransitionDelayed = delayed;
4018 mNextAppTransitionStartX = startX;
4019 mNextAppTransitionStartY = startY;
4020 scheduleAnimationCallback(mNextAppTransitionCallback);
4021 mNextAppTransitionCallback = startedCallback;
4022 } else {
4023 scheduleAnimationCallback(startedCallback);
4024 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004025 }
4026 }
4027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004028 public void executeAppTransition() {
4029 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4030 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004031 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004032 }
Romain Guy06882f82009-06-10 13:36:04 -07004033
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004034 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07004035 if (DEBUG_APP_TRANSITIONS) {
4036 RuntimeException e = new RuntimeException("here");
4037 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004038 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07004039 + mNextAppTransition, e);
4040 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004041 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004042 mAppTransitionReady = true;
4043 final long origId = Binder.clearCallingIdentity();
4044 performLayoutAndPlaceSurfacesLocked();
4045 Binder.restoreCallingIdentity(origId);
4046 }
4047 }
4048 }
4049
4050 public void setAppStartingWindow(IBinder token, String pkg,
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07004051 int theme, CompatibilityInfo compatInfo,
4052 CharSequence nonLocalizedLabel, int labelRes, int icon,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08004053 int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004054 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner6fbda632012-07-03 09:26:39 -07004055 "setAppStartingWindow()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004056 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004057 }
4058
4059 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004060 if (DEBUG_STARTING_WINDOW) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004061 TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
4062 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07004063
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004064 AppWindowToken wtoken = findAppWindowToken(token);
4065 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004066 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004067 return;
4068 }
4069
4070 // If the display is frozen, we won't do anything until the
4071 // actual window is displayed so there is no reason to put in
4072 // the starting window.
Craig Mautner2fb98b12012-03-20 17:24:00 -07004073 if (!okToDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004074 return;
4075 }
Romain Guy06882f82009-06-10 13:36:04 -07004076
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004077 if (wtoken.startingData != null) {
4078 return;
4079 }
Romain Guy06882f82009-06-10 13:36:04 -07004080
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004081 if (transferFrom != null) {
4082 AppWindowToken ttoken = findAppWindowToken(transferFrom);
4083 if (ttoken != null) {
4084 WindowState startingWindow = ttoken.startingWindow;
4085 if (startingWindow != null) {
4086 if (mStartingIconInTransition) {
4087 // In this case, the starting icon has already
4088 // been displayed, so start letting windows get
4089 // shown immediately without any more transitions.
4090 mSkipAppTransitionAnimation = true;
4091 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004092 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004093 "Moving existing starting from " + ttoken
4094 + " to " + wtoken);
4095 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07004096
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004097 // Transfer the starting window over to the new
4098 // token.
4099 wtoken.startingData = ttoken.startingData;
4100 wtoken.startingView = ttoken.startingView;
Craig Mautnerf4120952012-06-21 18:25:39 -07004101 wtoken.startingDisplayed = ttoken.startingDisplayed;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004102 wtoken.startingWindow = startingWindow;
Craig Mautnerf4120952012-06-21 18:25:39 -07004103 wtoken.reportedVisible = ttoken.reportedVisible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004104 ttoken.startingData = null;
4105 ttoken.startingView = null;
4106 ttoken.startingWindow = null;
4107 ttoken.startingMoved = true;
4108 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07004109 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004110 startingWindow.mAppToken = wtoken;
Craig Mautner6fbda632012-07-03 09:26:39 -07004111 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) {
4112 Slog.v(TAG, "Removing starting window: " + startingWindow);
4113 }
Craig Mautner59c00972012-07-30 12:10:24 -07004114 startingWindow.getWindowList().remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004115 mWindowsChanged = true;
Craig Mautner6fbda632012-07-03 09:26:39 -07004116 if (DEBUG_ADD_REMOVE) Slog.v(TAG,
4117 "Removing starting " + startingWindow + " from " + ttoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004118 ttoken.windows.remove(startingWindow);
4119 ttoken.allAppWindows.remove(startingWindow);
4120 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07004121
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004122 // Propagate other interesting state between the
4123 // tokens. If the old token is displayed, we should
4124 // immediately force the new one to be displayed. If
4125 // it is animating, we need to move that animation to
4126 // the new one.
4127 if (ttoken.allDrawn) {
4128 wtoken.allDrawn = true;
4129 }
4130 if (ttoken.firstWindowDrawn) {
4131 wtoken.firstWindowDrawn = true;
4132 }
4133 if (!ttoken.hidden) {
4134 wtoken.hidden = false;
4135 wtoken.hiddenRequested = false;
4136 wtoken.willBeHidden = false;
4137 }
4138 if (wtoken.clientHidden != ttoken.clientHidden) {
4139 wtoken.clientHidden = ttoken.clientHidden;
4140 wtoken.sendAppVisibilityToClients();
4141 }
Craig Mautner59431632012-04-04 11:56:44 -07004142 final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
4143 final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
4144 if (tAppAnimator.animation != null) {
4145 wAppAnimator.animation = tAppAnimator.animation;
4146 wAppAnimator.animating = tAppAnimator.animating;
4147 wAppAnimator.animLayerAdjustment = tAppAnimator.animLayerAdjustment;
4148 tAppAnimator.animation = null;
4149 tAppAnimator.animLayerAdjustment = 0;
4150 wAppAnimator.updateLayers();
4151 tAppAnimator.updateLayers();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004152 }
Romain Guy06882f82009-06-10 13:36:04 -07004153
Jeff Brown3a22cd92011-01-21 13:59:04 -08004154 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4155 true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004156 mLayoutNeeded = true;
4157 performLayoutAndPlaceSurfacesLocked();
4158 Binder.restoreCallingIdentity(origId);
4159 return;
4160 } else if (ttoken.startingData != null) {
4161 // The previous app was getting ready to show a
4162 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004163 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004164 "Moving pending starting from " + ttoken
4165 + " to " + wtoken);
4166 wtoken.startingData = ttoken.startingData;
4167 ttoken.startingData = null;
4168 ttoken.startingMoved = true;
4169 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
4170 // Note: we really want to do sendMessageAtFrontOfQueue() because we
4171 // want to process the message ASAP, before any other queued
4172 // messages.
4173 mH.sendMessageAtFrontOfQueue(m);
4174 return;
4175 }
Craig Mautner59431632012-04-04 11:56:44 -07004176 final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
4177 final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
4178 if (tAppAnimator.thumbnail != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004179 // The old token is animating with a thumbnail, transfer
4180 // that to the new token.
Craig Mautner59431632012-04-04 11:56:44 -07004181 if (wAppAnimator.thumbnail != null) {
4182 wAppAnimator.thumbnail.destroy();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004183 }
Craig Mautner59431632012-04-04 11:56:44 -07004184 wAppAnimator.thumbnail = tAppAnimator.thumbnail;
4185 wAppAnimator.thumbnailX = tAppAnimator.thumbnailX;
4186 wAppAnimator.thumbnailY = tAppAnimator.thumbnailY;
4187 wAppAnimator.thumbnailLayer = tAppAnimator.thumbnailLayer;
4188 wAppAnimator.thumbnailAnimation = tAppAnimator.thumbnailAnimation;
4189 tAppAnimator.thumbnail = null;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004190 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004191 }
4192 }
4193
4194 // There is no existing starting window, and the caller doesn't
4195 // want us to create one, so that's it!
4196 if (!createIfNeeded) {
4197 return;
4198 }
Romain Guy06882f82009-06-10 13:36:04 -07004199
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08004200 // If this is a translucent window, then don't
Dianne Hackborn284ac932009-08-28 10:34:25 -07004201 // show a starting window -- the current effect (a full-screen
4202 // opaque starting window that fades away to the real contents
4203 // when it is ready) does not work for this.
Craig Mautner6fbda632012-07-03 09:26:39 -07004204 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Checking theme of starting window: 0x"
4205 + Integer.toHexString(theme));
Dianne Hackborn284ac932009-08-28 10:34:25 -07004206 if (theme != 0) {
4207 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
4208 com.android.internal.R.styleable.Window);
Dianne Hackborn0b800192012-06-21 15:29:36 -07004209 if (ent == null) {
4210 // Whoops! App doesn't exist. Um. Okay. We'll just
4211 // pretend like we didn't see that.
4212 return;
4213 }
Craig Mautner6fbda632012-07-03 09:26:39 -07004214 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Translucent="
4215 + ent.array.getBoolean(
4216 com.android.internal.R.styleable.Window_windowIsTranslucent, false)
4217 + " Floating="
4218 + ent.array.getBoolean(
4219 com.android.internal.R.styleable.Window_windowIsFloating, false)
4220 + " ShowWallpaper="
4221 + ent.array.getBoolean(
4222 com.android.internal.R.styleable.Window_windowShowWallpaper, false));
Dianne Hackborn284ac932009-08-28 10:34:25 -07004223 if (ent.array.getBoolean(
4224 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
4225 return;
4226 }
4227 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07004228 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
4229 return;
4230 }
4231 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07004232 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08004233 if (mWallpaperTarget == null) {
4234 // If this theme is requesting a wallpaper, and the wallpaper
4235 // is not curently visible, then this effectively serves as
4236 // an opaque window and our starting window transition animation
4237 // can still work. We just need to make sure the starting window
4238 // is also showing the wallpaper.
4239 windowFlags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
4240 } else {
4241 return;
4242 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07004243 }
4244 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004245
Craig Mautner6fbda632012-07-03 09:26:39 -07004246 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Creating StartingData");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004247 mStartingIconInTransition = true;
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07004248 wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08004249 labelRes, icon, windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004250 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
4251 // Note: we really want to do sendMessageAtFrontOfQueue() because we
4252 // want to process the message ASAP, before any other queued
4253 // messages.
Craig Mautner6fbda632012-07-03 09:26:39 -07004254 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Enqueueing ADD_STARTING");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004255 mH.sendMessageAtFrontOfQueue(m);
4256 }
4257 }
4258
4259 public void setAppWillBeHidden(IBinder token) {
4260 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4261 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004262 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004263 }
4264
4265 AppWindowToken wtoken;
4266
4267 synchronized(mWindowMap) {
4268 wtoken = findAppWindowToken(token);
4269 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004270 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 -08004271 return;
4272 }
4273 wtoken.willBeHidden = true;
4274 }
4275 }
Romain Guy06882f82009-06-10 13:36:04 -07004276
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004277 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004278 boolean visible, int transit, boolean performLayout) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004279 boolean delayed = false;
4280
4281 if (wtoken.clientHidden == visible) {
4282 wtoken.clientHidden = !visible;
4283 wtoken.sendAppVisibilityToClients();
4284 }
Romain Guy06882f82009-06-10 13:36:04 -07004285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004286 wtoken.willBeHidden = false;
4287 if (wtoken.hidden == visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004288 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004289 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004290 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
4291 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07004292
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004293 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07004294
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004295 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
Craig Mautnerfbf378c2012-04-23 17:24:21 -07004296 if (wtoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) {
Craig Mautner59431632012-04-04 11:56:44 -07004297 wtoken.mAppAnimator.animation = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004298 }
Craig Mautnerf20588f2012-04-11 17:06:21 -07004299 if (applyAnimationLocked(wtoken, lp, transit, visible)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004300 delayed = runningAppAnimation = true;
4301 }
Craig Mautnerf20588f2012-04-11 17:06:21 -07004302 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004303 }
Romain Guy06882f82009-06-10 13:36:04 -07004304
Craig Mautnerf20588f2012-04-11 17:06:21 -07004305 final int N = wtoken.allAppWindows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004306 for (int i=0; i<N; i++) {
4307 WindowState win = wtoken.allAppWindows.get(i);
4308 if (win == wtoken.startingWindow) {
4309 continue;
4310 }
4311
Joe Onorato8a9b2202010-02-26 18:56:32 -08004312 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004313 //win.dump(" ");
4314 if (visible) {
4315 if (!win.isVisibleNow()) {
4316 if (!runningAppAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07004317 win.mWinAnimator.applyAnimationLocked(
4318 WindowManagerPolicy.TRANSIT_ENTER, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004319 }
4320 changed = true;
4321 }
4322 } else if (win.isVisibleNow()) {
4323 if (!runningAppAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07004324 win.mWinAnimator.applyAnimationLocked(
4325 WindowManagerPolicy.TRANSIT_EXIT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004326 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004327 changed = true;
4328 }
4329 }
4330
4331 wtoken.hidden = wtoken.hiddenRequested = !visible;
4332 if (!visible) {
4333 unsetAppFreezingScreenLocked(wtoken, true, true);
4334 } else {
4335 // If we are being set visible, and the starting window is
4336 // not yet displayed, then make sure it doesn't get displayed.
4337 WindowState swin = wtoken.startingWindow;
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07004338 if (swin != null && !swin.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004339 swin.mPolicyVisibility = false;
4340 swin.mPolicyVisibilityAfterAnim = false;
4341 }
4342 }
Romain Guy06882f82009-06-10 13:36:04 -07004343
Joe Onorato8a9b2202010-02-26 18:56:32 -08004344 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004345 + ": hidden=" + wtoken.hidden + " hiddenRequested="
4346 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07004347
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004348 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004349 mLayoutNeeded = true;
Jeff Brown3a22cd92011-01-21 13:59:04 -08004350 mInputMonitor.setUpdateInputWindowsNeededLw();
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004351 if (performLayout) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08004352 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4353 false /*updateInputWindows*/);
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004354 performLayoutAndPlaceSurfacesLocked();
4355 }
Jeff Brown2e44b072011-01-24 15:21:56 -08004356 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004357 }
4358 }
4359
Craig Mautner59431632012-04-04 11:56:44 -07004360 if (wtoken.mAppAnimator.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004361 delayed = true;
4362 }
Romain Guy06882f82009-06-10 13:36:04 -07004363
Craig Mautnerf20588f2012-04-11 17:06:21 -07004364 for (int i = wtoken.allAppWindows.size() - 1; i >= 0 && !delayed; i--) {
4365 if (wtoken.allAppWindows.get(i).mWinAnimator.isWindowAnimating()) {
4366 delayed = true;
4367 }
4368 }
4369
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004370 return delayed;
4371 }
4372
4373 public void setAppVisibility(IBinder token, boolean visible) {
4374 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4375 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004376 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004377 }
4378
4379 AppWindowToken wtoken;
4380
4381 synchronized(mWindowMap) {
4382 wtoken = findAppWindowToken(token);
4383 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004384 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004385 return;
4386 }
4387
4388 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004389 RuntimeException e = null;
4390 if (!HIDE_STACK_CRAWLS) {
4391 e = new RuntimeException();
4392 e.fillInStackTrace();
4393 }
Craig Mautner0afddcb2012-05-08 15:38:00 -07004394 Slog.v(TAG, "setAppVisibility(" + token + ", visible=" + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004395 + "): mNextAppTransition=" + mNextAppTransition
4396 + " hidden=" + wtoken.hidden
4397 + " hiddenRequested=" + wtoken.hiddenRequested, e);
4398 }
Romain Guy06882f82009-06-10 13:36:04 -07004399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004400 // If we are preparing an app transition, then delay changing
4401 // the visibility of this token until we execute that transition.
Craig Mautner2fb98b12012-03-20 17:24:00 -07004402 if (okToDisplay() && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004403 // Already in requested state, don't do anything more.
4404 if (wtoken.hiddenRequested != visible) {
4405 return;
4406 }
4407 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07004408
Joe Onorato8a9b2202010-02-26 18:56:32 -08004409 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004410 TAG, "Setting dummy animation on: " + wtoken);
Craig Mautnerf4120952012-06-21 18:25:39 -07004411 if (!wtoken.startingDisplayed) {
4412 wtoken.mAppAnimator.setDummyAnimation();
4413 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004414 mOpeningApps.remove(wtoken);
4415 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004416 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004417 wtoken.inPendingTransaction = true;
4418 if (visible) {
4419 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004420 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004421
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004422 // If the token is currently hidden (should be the
4423 // common case), then we need to set up to wait for
4424 // its windows to be ready.
4425 if (wtoken.hidden) {
4426 wtoken.allDrawn = false;
4427 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004428
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004429 if (wtoken.clientHidden) {
4430 // In the case where we are making an app visible
4431 // but holding off for a transition, we still need
4432 // to tell the client to make its windows visible so
4433 // they get drawn. Otherwise, we will wait on
4434 // performing the transition until all windows have
4435 // been drawn, they never will be, and we are sad.
4436 wtoken.clientHidden = false;
4437 wtoken.sendAppVisibilityToClients();
4438 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004439 }
4440 } else {
4441 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004442
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004443 // If the token is currently visible (should be the
4444 // common case), then set up to wait for it to be hidden.
4445 if (!wtoken.hidden) {
4446 wtoken.waitingToHide = true;
4447 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004448 }
4449 return;
4450 }
Romain Guy06882f82009-06-10 13:36:04 -07004451
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004452 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004453 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004454 true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004455 wtoken.updateReportedVisibilityLocked();
4456 Binder.restoreCallingIdentity(origId);
4457 }
4458 }
4459
4460 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
4461 boolean unfreezeSurfaceNow, boolean force) {
Craig Mautner59431632012-04-04 11:56:44 -07004462 if (wtoken.mAppAnimator.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004463 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004464 + " force=" + force);
4465 final int N = wtoken.allAppWindows.size();
4466 boolean unfrozeWindows = false;
4467 for (int i=0; i<N; i++) {
4468 WindowState w = wtoken.allAppWindows.get(i);
4469 if (w.mAppFreezing) {
4470 w.mAppFreezing = false;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07004471 if (w.mHasSurface && !w.mOrientationChanging) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07004472 if (DEBUG_ORIENTATION) Slog.v(TAG, "set mOrientationChanging of " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004473 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07004474 mInnerFields.mOrientationChangeComplete = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004475 }
4476 unfrozeWindows = true;
4477 }
4478 }
4479 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004480 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
Craig Mautner59431632012-04-04 11:56:44 -07004481 wtoken.mAppAnimator.freezingScreen = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004482 mAppsFreezingScreen--;
4483 }
4484 if (unfreezeSurfaceNow) {
4485 if (unfrozeWindows) {
4486 mLayoutNeeded = true;
4487 performLayoutAndPlaceSurfacesLocked();
4488 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004489 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004490 }
4491 }
4492 }
Romain Guy06882f82009-06-10 13:36:04 -07004493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004494 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
4495 int configChanges) {
4496 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004497 RuntimeException e = null;
4498 if (!HIDE_STACK_CRAWLS) {
4499 e = new RuntimeException();
4500 e.fillInStackTrace();
4501 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004502 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004503 + ": hidden=" + wtoken.hidden + " freezing="
Craig Mautner59431632012-04-04 11:56:44 -07004504 + wtoken.mAppAnimator.freezingScreen, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004505 }
4506 if (!wtoken.hiddenRequested) {
Craig Mautner59431632012-04-04 11:56:44 -07004507 if (!wtoken.mAppAnimator.freezingScreen) {
4508 wtoken.mAppAnimator.freezingScreen = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004509 mAppsFreezingScreen++;
4510 if (mAppsFreezingScreen == 1) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08004511 startFreezingDisplayLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004512 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
4513 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
4514 5000);
4515 }
4516 }
4517 final int N = wtoken.allAppWindows.size();
4518 for (int i=0; i<N; i++) {
4519 WindowState w = wtoken.allAppWindows.get(i);
4520 w.mAppFreezing = true;
4521 }
4522 }
4523 }
Romain Guy06882f82009-06-10 13:36:04 -07004524
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004525 public void startAppFreezingScreen(IBinder token, int configChanges) {
4526 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4527 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004528 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004529 }
4530
4531 synchronized(mWindowMap) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07004532 if (configChanges == 0 && okToDisplay()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004533 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004534 return;
4535 }
Romain Guy06882f82009-06-10 13:36:04 -07004536
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004537 AppWindowToken wtoken = findAppWindowToken(token);
4538 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004539 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004540 return;
4541 }
4542 final long origId = Binder.clearCallingIdentity();
4543 startAppFreezingScreenLocked(wtoken, configChanges);
4544 Binder.restoreCallingIdentity(origId);
4545 }
4546 }
Romain Guy06882f82009-06-10 13:36:04 -07004547
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004548 public void stopAppFreezingScreen(IBinder token, boolean force) {
4549 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4550 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004551 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004552 }
4553
4554 synchronized(mWindowMap) {
4555 AppWindowToken wtoken = findAppWindowToken(token);
4556 if (wtoken == null || wtoken.appToken == null) {
4557 return;
4558 }
4559 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004560 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
Craig Mautner59431632012-04-04 11:56:44 -07004561 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.mAppAnimator.freezingScreen);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004562 unsetAppFreezingScreenLocked(wtoken, true, force);
4563 Binder.restoreCallingIdentity(origId);
4564 }
4565 }
Romain Guy06882f82009-06-10 13:36:04 -07004566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004567 public void removeAppToken(IBinder token) {
4568 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4569 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004570 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004571 }
4572
4573 AppWindowToken wtoken = null;
4574 AppWindowToken startingToken = null;
4575 boolean delayed = false;
4576
4577 final long origId = Binder.clearCallingIdentity();
4578 synchronized(mWindowMap) {
4579 WindowToken basewtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004580 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004581 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004582 delayed = setTokenVisibilityLocked(wtoken, null, false,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004583 WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004584 wtoken.inPendingTransaction = false;
4585 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004586 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004587 if (mClosingApps.contains(wtoken)) {
4588 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004589 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004590 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004591 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004592 delayed = true;
4593 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004594 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004595 TAG, "Removing app " + wtoken + " delayed=" + delayed
Craig Mautner59431632012-04-04 11:56:44 -07004596 + " animation=" + wtoken.mAppAnimator.animation
4597 + " animating=" + wtoken.mAppAnimator.animating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004598 if (delayed) {
4599 // set the token aside because it has an active animation to be finished
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004600 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4601 "removeAppToken make exiting: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004602 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004603 } else {
4604 // Make sure there is no animation running on this token,
4605 // so any windows associated with it will be removed as
4606 // soon as their animations are complete
Craig Mautner59431632012-04-04 11:56:44 -07004607 wtoken.mAppAnimator.clearAnimation();
4608 wtoken.mAppAnimator.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004609 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004610 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4611 "removeAppToken: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004612 mAppTokens.remove(wtoken);
Craig Mautneref25d7a2012-05-15 23:01:47 -07004613 mAnimatingAppTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004614 wtoken.removed = true;
4615 if (wtoken.startingData != null) {
4616 startingToken = wtoken;
4617 }
4618 unsetAppFreezingScreenLocked(wtoken, true, true);
4619 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004620 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004621 mFocusedApp = null;
Jeff Brown3a22cd92011-01-21 13:59:04 -08004622 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004623 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004624 }
4625 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004626 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004627 }
Romain Guy06882f82009-06-10 13:36:04 -07004628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004629 if (!delayed && wtoken != null) {
4630 wtoken.updateReportedVisibilityLocked();
4631 }
4632 }
4633 Binder.restoreCallingIdentity(origId);
4634
4635 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004636 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004637 + startingToken + ": app token removed");
4638 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
4639 mH.sendMessage(m);
4640 }
4641 }
4642
4643 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
4644 final int NW = token.windows.size();
Craig Mautneref25d7a2012-05-15 23:01:47 -07004645 if (NW > 0) {
4646 mWindowsChanged = true;
4647 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004648 for (int i=0; i<NW; i++) {
4649 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004650 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
Craig Mautner59c00972012-07-30 12:10:24 -07004651 win.getWindowList().remove(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004652 int j = win.mChildWindows.size();
4653 while (j > 0) {
4654 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004655 WindowState cwin = win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004656 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004657 "Tmp removing child window " + cwin);
Craig Mautner59c00972012-07-30 12:10:24 -07004658 cwin.getWindowList().remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004659 }
4660 }
4661 return NW > 0;
4662 }
4663
4664 void dumpAppTokensLocked() {
4665 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004666 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004667 }
4668 }
Romain Guy06882f82009-06-10 13:36:04 -07004669
Craig Mautneref25d7a2012-05-15 23:01:47 -07004670 void dumpAnimatingAppTokensLocked() {
4671 for (int i=mAnimatingAppTokens.size()-1; i>=0; i--) {
4672 Slog.v(TAG, " #" + i + ": " + mAnimatingAppTokens.get(i).token);
4673 }
4674 }
4675
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004676 void dumpWindowsLocked() {
Craig Mautner59c00972012-07-30 12:10:24 -07004677 int i = 0;
4678 final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
4679 while (iterator.hasNext()) {
4680 final WindowState w = iterator.next();
4681 Slog.v(TAG, " #" + i++ + ": " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004682 }
4683 }
Romain Guy06882f82009-06-10 13:36:04 -07004684
Craig Mautner59c00972012-07-30 12:10:24 -07004685 private int findWindowOffsetLocked(WindowList windows, int tokenPos) {
4686 final int NW = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004687
Craig Mautneref25d7a2012-05-15 23:01:47 -07004688 if (tokenPos >= mAnimatingAppTokens.size()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004689 int i = NW;
4690 while (i > 0) {
4691 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07004692 WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004693 if (win.getAppToken() != null) {
4694 return i+1;
4695 }
4696 }
4697 }
4698
4699 while (tokenPos > 0) {
4700 // Find the first app token below the new position that has
4701 // a window displayed.
Craig Mautner59c00972012-07-30 12:10:24 -07004702 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004703 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004704 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004705 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004706 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07004707 "Skipping token -- currently sending to bottom");
4708 tokenPos--;
4709 continue;
4710 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004711 int i = wtoken.windows.size();
4712 while (i > 0) {
4713 i--;
4714 WindowState win = wtoken.windows.get(i);
4715 int j = win.mChildWindows.size();
4716 while (j > 0) {
4717 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004718 WindowState cwin = win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004719 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004720 for (int pos=NW-1; pos>=0; pos--) {
Craig Mautner59c00972012-07-30 12:10:24 -07004721 if (windows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004722 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004723 "Found child win @" + (pos+1));
4724 return pos+1;
4725 }
4726 }
4727 }
4728 }
4729 for (int pos=NW-1; pos>=0; pos--) {
Craig Mautner59c00972012-07-30 12:10:24 -07004730 if (windows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004731 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004732 return pos+1;
4733 }
4734 }
4735 }
4736 tokenPos--;
4737 }
4738
4739 return 0;
4740 }
4741
4742 private final int reAddWindowLocked(int index, WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -07004743 final WindowList windows = win.getWindowList();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004744 final int NCW = win.mChildWindows.size();
4745 boolean added = false;
4746 for (int j=0; j<NCW; j++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004747 WindowState cwin = win.mChildWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004748 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004749 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004750 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004751 win.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004752 windows.add(index, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004753 index++;
4754 added = true;
4755 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004756 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004757 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004758 cwin.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004759 windows.add(index, cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004760 index++;
4761 }
4762 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004763 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004764 + index + ": " + win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004765 win.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004766 windows.add(index, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004767 index++;
4768 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004769 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004770 return index;
4771 }
Romain Guy06882f82009-06-10 13:36:04 -07004772
Craig Mautner59c00972012-07-30 12:10:24 -07004773 private final int reAddAppWindowsLocked(final DisplayContent displayContent, int index,
4774 WindowToken token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004775 final int NW = token.windows.size();
4776 for (int i=0; i<NW; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07004777 final WindowState win = token.windows.get(i);
4778 if (win.mDisplayContent == displayContent) {
4779 index = reAddWindowLocked(index, token.windows.get(i));
4780 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004781 }
4782 return index;
4783 }
4784
4785 public void moveAppToken(int index, IBinder token) {
4786 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4787 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004788 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004789 }
4790
4791 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004792 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004793 if (DEBUG_REORDER) dumpAppTokensLocked();
4794 final AppWindowToken wtoken = findAppWindowToken(token);
Craig Mautneref25d7a2012-05-15 23:01:47 -07004795 final int oldIndex = mAppTokens.indexOf(wtoken);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004796 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
4797 "Start moving token " + wtoken + " initially at "
Craig Mautneref25d7a2012-05-15 23:01:47 -07004798 + oldIndex);
4799 if (oldIndex > index && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET
4800 && !mAppTransitionRunning) {
4801 // animation towards back has not started, copy old list for duration of animation.
4802 mAnimatingAppTokens.clear();
4803 mAnimatingAppTokens.addAll(mAppTokens);
4804 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004805 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004806 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004807 + token + " (" + wtoken + ")");
4808 return;
4809 }
4810 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004811 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004812 else if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "Moved " + token + " to " + index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004813 if (DEBUG_REORDER) dumpAppTokensLocked();
Craig Mautneref25d7a2012-05-15 23:01:47 -07004814 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET && !mAppTransitionRunning) {
4815 // Not animating, bring animating app list in line with mAppTokens.
4816 mAnimatingAppTokens.clear();
4817 mAnimatingAppTokens.addAll(mAppTokens);
Romain Guy06882f82009-06-10 13:36:04 -07004818
Craig Mautneref25d7a2012-05-15 23:01:47 -07004819 // Bring window ordering, window focus and input window in line with new app token
4820 final long origId = Binder.clearCallingIdentity();
4821 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004822 if (DEBUG_REORDER) dumpWindowsLocked();
Craig Mautneref25d7a2012-05-15 23:01:47 -07004823 if (tmpRemoveAppWindowsLocked(wtoken)) {
4824 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
4825 if (DEBUG_REORDER) dumpWindowsLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07004826 DisplayContentsIterator iterator = new DisplayContentsIterator();
4827 while(iterator.hasNext()) {
4828 final DisplayContent displayContent = iterator.next();
4829 final WindowList windows = displayContent.getWindowList();
4830 final int pos = findWindowOffsetLocked(windows, index);
4831 reAddAppWindowsLocked(displayContent, pos, wtoken);
4832 }
Craig Mautneref25d7a2012-05-15 23:01:47 -07004833 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
4834 if (DEBUG_REORDER) dumpWindowsLocked();
4835 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4836 false /*updateInputWindows*/);
4837 mLayoutNeeded = true;
4838 mInputMonitor.setUpdateInputWindowsNeededLw();
4839 performLayoutAndPlaceSurfacesLocked();
4840 mInputMonitor.updateInputWindowsLw(false /*force*/);
4841 }
4842 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004843 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004844 }
4845 }
4846
4847 private void removeAppTokensLocked(List<IBinder> tokens) {
4848 // XXX This should be done more efficiently!
4849 // (take advantage of the fact that both lists should be
4850 // ordered in the same way.)
4851 int N = tokens.size();
4852 for (int i=0; i<N; i++) {
4853 IBinder token = tokens.get(i);
4854 final AppWindowToken wtoken = findAppWindowToken(token);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004855 if (DEBUG_REORDER || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4856 "Temporarily removing " + wtoken + " from " + mAppTokens.indexOf(wtoken));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004857 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004858 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004859 + token + " (" + wtoken + ")");
4860 i--;
4861 N--;
4862 }
4863 }
4864 }
4865
Dianne Hackborna8f60182009-09-01 19:01:50 -07004866 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
4867 boolean updateFocusAndLayout) {
4868 // First remove all of the windows from the list.
4869 tmpRemoveAppWindowsLocked(wtoken);
4870
Dianne Hackborna8f60182009-09-01 19:01:50 -07004871 // And now add them back at the correct place.
Craig Mautner59c00972012-07-30 12:10:24 -07004872 DisplayContentsIterator iterator = new DisplayContentsIterator();
4873 while (iterator.hasNext()) {
4874 final DisplayContent displayContent = iterator.next();
4875 final WindowList windows = displayContent.getWindowList();
4876 final int pos = findWindowOffsetLocked(windows, tokenPos);
4877 reAddAppWindowsLocked(displayContent, pos, wtoken);
4878
Craig Mautner4f67ba62012-08-02 11:23:00 -07004879 if (updateFocusAndLayout && !updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
Craig Mautner59c00972012-07-30 12:10:24 -07004880 false /*updateInputWindows*/)) {
4881 assignLayersLocked(windows);
4882 }
4883 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07004884
4885 if (updateFocusAndLayout) {
Jeff Brown2e44b072011-01-24 15:21:56 -08004886 mInputMonitor.setUpdateInputWindowsNeededLw();
Craig Mautner59c00972012-07-30 12:10:24 -07004887
4888 // Note that the above updateFocusedWindowLocked conditional used to sit here.
4889
Dianne Hackborna8f60182009-09-01 19:01:50 -07004890 mLayoutNeeded = true;
Craig Mautneref25d7a2012-05-15 23:01:47 -07004891 if (!mInLayout) {
4892 performLayoutAndPlaceSurfacesLocked();
4893 }
Jeff Brown2e44b072011-01-24 15:21:56 -08004894 mInputMonitor.updateInputWindowsLw(false /*force*/);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004895 }
4896 }
4897
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004898 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
4899 // First remove all of the windows from the list.
4900 final int N = tokens.size();
4901 int i;
4902 for (i=0; i<N; i++) {
4903 WindowToken token = mTokenMap.get(tokens.get(i));
4904 if (token != null) {
4905 tmpRemoveAppWindowsLocked(token);
4906 }
4907 }
4908
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004909 // And now add them back at the correct place.
Craig Mautner59c00972012-07-30 12:10:24 -07004910 DisplayContentsIterator iterator = new DisplayContentsIterator();
4911 while (iterator.hasNext()) {
4912 final DisplayContent displayContent = iterator.next();
4913 final WindowList windows = displayContent.getWindowList();
4914 // Where to start adding?
4915 int pos = findWindowOffsetLocked(windows, tokenPos);
4916 for (i=0; i<N; i++) {
4917 WindowToken token = mTokenMap.get(tokens.get(i));
4918 if (token != null) {
4919 pos = reAddAppWindowsLocked(displayContent, pos, token);
4920 }
4921 }
4922 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4923 false /*updateInputWindows*/)) {
4924 assignLayersLocked(windows);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004925 }
4926 }
4927
Jeff Brown2e44b072011-01-24 15:21:56 -08004928 mInputMonitor.setUpdateInputWindowsNeededLw();
Craig Mautner59c00972012-07-30 12:10:24 -07004929
Craig Mautner4f67ba62012-08-02 11:23:00 -07004930 // Note that the above updateFocusedWindowLocked used to sit here.
Craig Mautner59c00972012-07-30 12:10:24 -07004931
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004932 mLayoutNeeded = true;
4933 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08004934 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004935
4936 //dump();
4937 }
4938
4939 public void moveAppTokensToTop(List<IBinder> tokens) {
4940 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4941 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004942 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004943 }
4944
4945 final long origId = Binder.clearCallingIdentity();
4946 synchronized(mWindowMap) {
4947 removeAppTokensLocked(tokens);
4948 final int N = tokens.size();
4949 for (int i=0; i<N; i++) {
4950 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4951 if (wt != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004952 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
4953 "Adding next to top: " + wt);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004954 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004955 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004956 wt.sendingToBottom = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -07004957 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004958 }
4959 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004960
Craig Mautner06a94f72012-05-29 10:46:00 -07004961 if (!mAppTransitionRunning) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07004962 mAnimatingAppTokens.clear();
4963 mAnimatingAppTokens.addAll(mAppTokens);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004964 moveAppWindowsLocked(tokens, mAppTokens.size());
4965 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004966 }
4967 Binder.restoreCallingIdentity(origId);
4968 }
4969
Craig Mautneref25d7a2012-05-15 23:01:47 -07004970 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004971 public void moveAppTokensToBottom(List<IBinder> tokens) {
4972 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4973 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004974 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004975 }
4976
4977 final long origId = Binder.clearCallingIdentity();
4978 synchronized(mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004979 final int N = tokens.size();
Craig Mautner06a94f72012-05-29 10:46:00 -07004980 if (N > 0 && !mAppTransitionRunning) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07004981 // animating towards back, hang onto old list for duration of animation.
4982 mAnimatingAppTokens.clear();
4983 mAnimatingAppTokens.addAll(mAppTokens);
4984 }
4985 removeAppTokensLocked(tokens);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004986 int pos = 0;
4987 for (int i=0; i<N; i++) {
4988 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4989 if (wt != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004990 if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4991 "Adding next to bottom: " + wt + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004992 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004993 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004994 wt.sendingToBottom = true;
4995 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004996 pos++;
4997 }
4998 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004999
Craig Mautner06a94f72012-05-29 10:46:00 -07005000 if (!mAppTransitionRunning) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07005001 mAnimatingAppTokens.clear();
5002 mAnimatingAppTokens.addAll(mAppTokens);
Dianne Hackborna8f60182009-09-01 19:01:50 -07005003 moveAppWindowsLocked(tokens, 0);
5004 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005005 }
5006 Binder.restoreCallingIdentity(origId);
5007 }
5008
5009 // -------------------------------------------------------------
5010 // Misc IWindowSession methods
5011 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07005012
Jim Miller284b62e2010-06-08 14:27:42 -07005013 private boolean shouldAllowDisableKeyguard()
Jim Millerd6b57052010-06-07 17:52:42 -07005014 {
Jim Miller284b62e2010-06-08 14:27:42 -07005015 // We fail safe and prevent disabling keyguard in the unlikely event this gets
5016 // called before DevicePolicyManagerService has started.
5017 if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
5018 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
5019 Context.DEVICE_POLICY_SERVICE);
5020 if (dpm != null) {
5021 mAllowDisableKeyguard = dpm.getPasswordQuality(null)
5022 == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
5023 ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
5024 }
Jim Millerd6b57052010-06-07 17:52:42 -07005025 }
Jim Miller284b62e2010-06-08 14:27:42 -07005026 return mAllowDisableKeyguard == ALLOW_DISABLE_YES;
Jim Millerd6b57052010-06-07 17:52:42 -07005027 }
5028
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005029 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04005030 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005031 != PackageManager.PERMISSION_GRANTED) {
5032 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5033 }
Jim Millerd6b57052010-06-07 17:52:42 -07005034
Jim Miller284b62e2010-06-08 14:27:42 -07005035 synchronized (mKeyguardTokenWatcher) {
5036 mKeyguardTokenWatcher.acquire(token, tag);
Mike Lockwooddd884682009-10-11 16:57:08 -04005037 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005038 }
5039
5040 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04005041 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005042 != PackageManager.PERMISSION_GRANTED) {
5043 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5044 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005045
Jim Miller284b62e2010-06-08 14:27:42 -07005046 synchronized (mKeyguardTokenWatcher) {
5047 mKeyguardTokenWatcher.release(token);
Jim Millerd6b57052010-06-07 17:52:42 -07005048
Jim Miller284b62e2010-06-08 14:27:42 -07005049 if (!mKeyguardTokenWatcher.isAcquired()) {
5050 // If we are the last one to reenable the keyguard wait until
5051 // we have actually finished reenabling until returning.
5052 // It is possible that reenableKeyguard() can be called before
5053 // the previous disableKeyguard() is handled, in which case
5054 // neither mKeyguardTokenWatcher.acquired() or released() would
5055 // be called. In that case mKeyguardDisabled will be false here
5056 // and we have nothing to wait for.
5057 while (mKeyguardDisabled) {
5058 try {
5059 mKeyguardTokenWatcher.wait();
5060 } catch (InterruptedException e) {
5061 Thread.currentThread().interrupt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005062 }
5063 }
5064 }
5065 }
5066 }
5067
5068 /**
5069 * @see android.app.KeyguardManager#exitKeyguardSecurely
5070 */
5071 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04005072 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005073 != PackageManager.PERMISSION_GRANTED) {
5074 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5075 }
5076 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
5077 public void onKeyguardExitResult(boolean success) {
5078 try {
5079 callback.onKeyguardExitResult(success);
5080 } catch (RemoteException e) {
5081 // Client has died, we don't care.
5082 }
5083 }
5084 });
5085 }
5086
5087 public boolean inKeyguardRestrictedInputMode() {
5088 return mPolicy.inKeyguardRestrictedKeyInputMode();
5089 }
Romain Guy06882f82009-06-10 13:36:04 -07005090
Mike Lockwood520d8bc2011-02-18 13:23:13 -05005091 public boolean isKeyguardLocked() {
5092 return mPolicy.isKeyguardLocked();
5093 }
5094
5095 public boolean isKeyguardSecure() {
5096 return mPolicy.isKeyguardSecure();
5097 }
5098
Dianne Hackborn90c52de2011-09-23 12:57:44 -07005099 public void dismissKeyguard() {
5100 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
5101 != PackageManager.PERMISSION_GRANTED) {
5102 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5103 }
5104 synchronized(mWindowMap) {
5105 mPolicy.dismissKeyguardLw();
5106 }
5107 }
5108
Dianne Hackbornffa42482009-09-23 22:20:11 -07005109 public void closeSystemDialogs(String reason) {
5110 synchronized(mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -07005111 final AllWindowsIterator iterator = new AllWindowsIterator();
5112 while (iterator.hasNext()) {
5113 final WindowState w = iterator.next();
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07005114 if (w.mHasSurface) {
Dianne Hackbornffa42482009-09-23 22:20:11 -07005115 try {
5116 w.mClient.closeSystemDialogs(reason);
5117 } catch (RemoteException e) {
5118 }
5119 }
5120 }
5121 }
5122 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005123
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005124 static float fixScale(float scale) {
5125 if (scale < 0) scale = 0;
5126 else if (scale > 20) scale = 20;
5127 return Math.abs(scale);
5128 }
Romain Guy06882f82009-06-10 13:36:04 -07005129
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005130 public void setAnimationScale(int which, float scale) {
5131 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
5132 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005133 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005134 }
5135
5136 if (scale < 0) scale = 0;
5137 else if (scale > 20) scale = 20;
5138 scale = Math.abs(scale);
5139 switch (which) {
5140 case 0: mWindowAnimationScale = fixScale(scale); break;
5141 case 1: mTransitionAnimationScale = fixScale(scale); break;
Chet Haasec38fa1f2012-02-01 16:37:46 -08005142 case 2: mAnimatorDurationScale = fixScale(scale); break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005143 }
Romain Guy06882f82009-06-10 13:36:04 -07005144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005145 // Persist setting
5146 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
5147 }
Romain Guy06882f82009-06-10 13:36:04 -07005148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005149 public void setAnimationScales(float[] scales) {
5150 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
5151 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005152 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005153 }
5154
5155 if (scales != null) {
5156 if (scales.length >= 1) {
5157 mWindowAnimationScale = fixScale(scales[0]);
5158 }
5159 if (scales.length >= 2) {
5160 mTransitionAnimationScale = fixScale(scales[1]);
5161 }
Chet Haasec38fa1f2012-02-01 16:37:46 -08005162 if (scales.length >= 3) {
5163 mAnimatorDurationScale = fixScale(scales[2]);
5164 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005165 }
Romain Guy06882f82009-06-10 13:36:04 -07005166
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005167 // Persist setting
5168 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
5169 }
Romain Guy06882f82009-06-10 13:36:04 -07005170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005171 public float getAnimationScale(int which) {
5172 switch (which) {
5173 case 0: return mWindowAnimationScale;
5174 case 1: return mTransitionAnimationScale;
Chet Haasec38fa1f2012-02-01 16:37:46 -08005175 case 2: return mAnimatorDurationScale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005176 }
5177 return 0;
5178 }
Romain Guy06882f82009-06-10 13:36:04 -07005179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005180 public float[] getAnimationScales() {
Chet Haasec38fa1f2012-02-01 16:37:46 -08005181 return new float[] { mWindowAnimationScale, mTransitionAnimationScale,
5182 mAnimatorDurationScale };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005183 }
Romain Guy06882f82009-06-10 13:36:04 -07005184
Jeff Brownac143512012-04-05 18:57:33 -07005185 // Called by window manager policy. Not exposed externally.
5186 @Override
5187 public int getLidState() {
Jeff Brownc458ce92012-04-30 14:58:40 -07005188 int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY,
5189 InputManagerService.SW_LID);
Jeff Brownac143512012-04-05 18:57:33 -07005190 if (sw > 0) {
Jeff Brown27fd3422012-04-09 11:05:16 -07005191 // Switch state: AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL.
Jeff Brownac143512012-04-05 18:57:33 -07005192 return LID_CLOSED;
Jeff Brown27fd3422012-04-09 11:05:16 -07005193 } else if (sw == 0) {
5194 // Switch state: AKEY_STATE_UP.
5195 return LID_OPEN;
Jeff Brownac143512012-04-05 18:57:33 -07005196 } else {
Jeff Brown27fd3422012-04-09 11:05:16 -07005197 // Switch state: AKEY_STATE_UNKNOWN.
Jeff Brownac143512012-04-05 18:57:33 -07005198 return LID_ABSENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005199 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005200 }
Romain Guy06882f82009-06-10 13:36:04 -07005201
Jeff Brownac143512012-04-05 18:57:33 -07005202 // Called by window manager policy. Not exposed externally.
5203 @Override
Jeff Browna41ca772010-08-11 14:46:32 -07005204 public InputChannel monitorInput(String inputChannelName) {
Jeff Browna41ca772010-08-11 14:46:32 -07005205 return mInputManager.monitorInput(inputChannelName);
5206 }
5207
Jeff Brown7304c342012-05-11 18:42:42 -07005208 // Called by window manager policy. Not exposed externally.
5209 @Override
Jeff Browncf39bdf2012-05-18 14:41:19 -07005210 public void switchKeyboardLayout(int deviceId, int direction) {
5211 mInputManager.switchKeyboardLayout(deviceId, direction);
5212 }
5213
5214 // Called by window manager policy. Not exposed externally.
5215 @Override
Jeff Brown7304c342012-05-11 18:42:42 -07005216 public void shutdown() {
5217 ShutdownThread.shutdown(mContext, true);
5218 }
5219
5220 // Called by window manager policy. Not exposed externally.
5221 @Override
5222 public void rebootSafeMode() {
5223 ShutdownThread.rebootSafeMode(mContext, true);
5224 }
5225
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07005226 public void setInputFilter(IInputFilter filter) {
5227 if (!checkCallingPermission(android.Manifest.permission.FILTER_EVENTS, "setInputFilter()")) {
5228 throw new SecurityException("Requires FILTER_EVENTS permission");
5229 }
Jeff Brown0029c662011-03-30 02:25:18 -07005230 mInputManager.setInputFilter(filter);
5231 }
5232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005233 public void enableScreenAfterBoot() {
5234 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005235 if (DEBUG_BOOT) {
5236 RuntimeException here = new RuntimeException("here");
5237 here.fillInStackTrace();
5238 Slog.i(TAG, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled
5239 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5240 + " mShowingBootMessages=" + mShowingBootMessages
5241 + " mSystemBooted=" + mSystemBooted, here);
5242 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005243 if (mSystemBooted) {
5244 return;
5245 }
5246 mSystemBooted = true;
Dianne Hackborn661cd522011-08-22 00:26:20 -07005247 hideBootMessagesLocked();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005248 // If the screen still doesn't come up after 30 seconds, give
5249 // up and turn it on.
5250 Message msg = mH.obtainMessage(H.BOOT_TIMEOUT);
5251 mH.sendMessageDelayed(msg, 30*1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005252 }
Romain Guy06882f82009-06-10 13:36:04 -07005253
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07005254 mPolicy.systemBooted();
5255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005256 performEnableScreen();
5257 }
Romain Guy06882f82009-06-10 13:36:04 -07005258
Dianne Hackborn661cd522011-08-22 00:26:20 -07005259 void enableScreenIfNeededLocked() {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005260 if (DEBUG_BOOT) {
5261 RuntimeException here = new RuntimeException("here");
5262 here.fillInStackTrace();
5263 Slog.i(TAG, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled
5264 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5265 + " mShowingBootMessages=" + mShowingBootMessages
5266 + " mSystemBooted=" + mSystemBooted, here);
5267 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005268 if (mDisplayEnabled) {
5269 return;
5270 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005271 if (!mSystemBooted && !mShowingBootMessages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005272 return;
5273 }
5274 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
5275 }
Romain Guy06882f82009-06-10 13:36:04 -07005276
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005277 public void performBootTimeout() {
5278 synchronized(mWindowMap) {
Mike Lockwoodd747dc82011-09-13 16:28:22 -04005279 if (mDisplayEnabled || mHeadless) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005280 return;
5281 }
5282 Slog.w(TAG, "***** BOOT TIMEOUT: forcing display enabled");
5283 mForceDisplayEnabled = true;
5284 }
5285 performEnableScreen();
5286 }
5287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005288 public void performEnableScreen() {
5289 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005290 if (DEBUG_BOOT) {
5291 RuntimeException here = new RuntimeException("here");
5292 here.fillInStackTrace();
5293 Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
5294 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5295 + " mShowingBootMessages=" + mShowingBootMessages
Jeff Brown780c46f2012-06-24 12:15:38 -07005296 + " mSystemBooted=" + mSystemBooted
5297 + " mOnlyCore=" + mOnlyCore, here);
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005298 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005299 if (mDisplayEnabled) {
5300 return;
5301 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005302 if (!mSystemBooted && !mShowingBootMessages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005303 return;
5304 }
Romain Guy06882f82009-06-10 13:36:04 -07005305
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005306 if (!mForceDisplayEnabled) {
5307 // Don't enable the screen until all existing windows
5308 // have been drawn.
5309 boolean haveBootMsg = false;
5310 boolean haveApp = false;
Justin Mattson4233f262012-04-09 18:23:16 -07005311 // if the wallpaper service is disabled on the device, we're never going to have
5312 // wallpaper, don't bother waiting for it
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005313 boolean haveWallpaper = false;
Justin Mattson4233f262012-04-09 18:23:16 -07005314 boolean wallpaperEnabled = mContext.getResources().getBoolean(
Jeff Brown780c46f2012-06-24 12:15:38 -07005315 com.android.internal.R.bool.config_enableWallpaperService)
5316 && !mOnlyCore;
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005317 boolean haveKeyguard = true;
Craig Mautner59c00972012-07-30 12:10:24 -07005318 // TODO(multidisplay): Expand to all displays?
5319 final WindowList windows = getDefaultWindowList();
5320 final int N = windows.size();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005321 for (int i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07005322 WindowState w = windows.get(i);
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005323 if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD) {
5324 // Only if there is a keyguard attached to the window manager
5325 // will we consider ourselves as having a keyguard. If it
5326 // isn't attached, we don't know if it wants to be shown or
5327 // hidden. If it is attached, we will say we have a keyguard
5328 // if the window doesn't want to be visible, because in that
5329 // case it explicitly doesn't want to be shown so we should
5330 // not delay turning the screen on for it.
5331 boolean vis = w.mViewVisibility == View.VISIBLE
5332 && w.mPolicyVisibility;
5333 haveKeyguard = !vis;
5334 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005335 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
5336 return;
5337 }
5338 if (w.isDrawnLw()) {
5339 if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_BOOT_PROGRESS) {
5340 haveBootMsg = true;
5341 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION) {
5342 haveApp = true;
5343 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER) {
5344 haveWallpaper = true;
5345 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD) {
5346 haveKeyguard = true;
5347 }
5348 }
5349 }
5350
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005351 if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005352 Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
5353 + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
Justin Mattson4233f262012-04-09 18:23:16 -07005354 + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled
5355 + " haveKeyguard=" + haveKeyguard);
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005356 }
5357
5358 // If we are turning on the screen to show the boot message,
5359 // don't do it until the boot message is actually displayed.
5360 if (!mSystemBooted && !haveBootMsg) {
5361 return;
5362 }
5363
5364 // If we are turning on the screen after the boot is completed
5365 // normally, don't do so until we have the application and
5366 // wallpaper.
Justin Mattson4233f262012-04-09 18:23:16 -07005367 if (mSystemBooted && ((!haveApp && !haveKeyguard) ||
5368 (wallpaperEnabled && !haveWallpaper))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005369 return;
5370 }
5371 }
Romain Guy06882f82009-06-10 13:36:04 -07005372
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005373 mDisplayEnabled = true;
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005374 if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005375 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005376 StringWriter sw = new StringWriter();
5377 PrintWriter pw = new PrintWriter(sw);
5378 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005379 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005380 }
5381 try {
5382 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
5383 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005384 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005385 Parcel data = Parcel.obtain();
5386 data.writeInterfaceToken("android.ui.ISurfaceComposer");
Jeff Brownc042ee22012-05-08 13:03:42 -07005387 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005388 data, null, 0);
5389 data.recycle();
5390 }
5391 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005392 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005393 }
Jeff Brown08a746a2012-06-24 12:14:49 -07005394
5395 // Enable input dispatch.
5396 mInputMonitor.setEventDispatchingLw(mEventDispatchingEnabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005397 }
Romain Guy06882f82009-06-10 13:36:04 -07005398
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005399 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07005400
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005401 // Make sure the last requested orientation has been applied.
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005402 updateRotationUnchecked(false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005403 }
Romain Guy06882f82009-06-10 13:36:04 -07005404
Dianne Hackborn661cd522011-08-22 00:26:20 -07005405 public void showBootMessage(final CharSequence msg, final boolean always) {
5406 boolean first = false;
5407 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005408 if (DEBUG_BOOT) {
5409 RuntimeException here = new RuntimeException("here");
5410 here.fillInStackTrace();
5411 Slog.i(TAG, "showBootMessage: msg=" + msg + " always=" + always
5412 + " mAllowBootMessages=" + mAllowBootMessages
5413 + " mShowingBootMessages=" + mShowingBootMessages
5414 + " mSystemBooted=" + mSystemBooted, here);
5415 }
Dianne Hackborn58f42a52011-10-10 13:46:34 -07005416 if (!mAllowBootMessages) {
5417 return;
5418 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005419 if (!mShowingBootMessages) {
5420 if (!always) {
5421 return;
5422 }
5423 first = true;
5424 }
5425 if (mSystemBooted) {
5426 return;
5427 }
5428 mShowingBootMessages = true;
5429 mPolicy.showBootMessage(msg, always);
5430 }
5431 if (first) {
5432 performEnableScreen();
5433 }
5434 }
5435
5436 public void hideBootMessagesLocked() {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005437 if (DEBUG_BOOT) {
5438 RuntimeException here = new RuntimeException("here");
5439 here.fillInStackTrace();
5440 Slog.i(TAG, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled
5441 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5442 + " mShowingBootMessages=" + mShowingBootMessages
5443 + " mSystemBooted=" + mSystemBooted, here);
5444 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005445 if (mShowingBootMessages) {
5446 mShowingBootMessages = false;
5447 mPolicy.hideBootMessages();
5448 }
5449 }
5450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005451 public void setInTouchMode(boolean mode) {
5452 synchronized(mWindowMap) {
5453 mInTouchMode = mode;
5454 }
5455 }
5456
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005457 // TODO: more accounting of which pid(s) turned it on, keep count,
5458 // only allow disables from pids which have count on, etc.
Craig Mautner0447a812012-05-22 16:01:31 -07005459 @Override
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005460 public void showStrictModeViolation(boolean on) {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07005461 if (mHeadless) return;
Craig Mautner0447a812012-05-22 16:01:31 -07005462 mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, on ? 1 : 0, 0));
5463 }
Mike Lockwood3a74bd32011-08-12 13:55:22 -07005464
Craig Mautner0447a812012-05-22 16:01:31 -07005465 private void showStrictModeViolation(int arg) {
5466 final boolean on = arg != 0;
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005467 int pid = Binder.getCallingPid();
5468 synchronized(mWindowMap) {
5469 // Ignoring requests to enable the red border from clients
5470 // which aren't on screen. (e.g. Broadcast Receivers in
5471 // the background..)
5472 if (on) {
5473 boolean isVisible = false;
Craig Mautner59c00972012-07-30 12:10:24 -07005474 final AllWindowsIterator iterator = new AllWindowsIterator();
5475 while (iterator.hasNext()) {
5476 final WindowState ws = iterator.next();
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005477 if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
5478 isVisible = true;
5479 break;
5480 }
5481 }
5482 if (!isVisible) {
5483 return;
5484 }
5485 }
5486
Dianne Hackborn36991742011-10-11 21:35:26 -07005487 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
5488 ">>> OPEN TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005489 Surface.openTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005490 try {
5491 if (mStrictModeFlash == null) {
5492 mStrictModeFlash = new StrictModeFlash(mDisplay, mFxSession);
5493 }
5494 mStrictModeFlash.setVisibility(on);
5495 } finally {
5496 Surface.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -07005497 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
5498 "<<< CLOSE TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005499 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005500 }
5501 }
5502
Brad Fitzpatrickc1a968a2010-11-24 08:56:40 -08005503 public void setStrictModeVisualIndicatorPreference(String value) {
5504 SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
5505 }
5506
Jim Millere70d5062011-03-08 21:38:39 -08005507 /**
5508 * Takes a snapshot of the screen. In landscape mode this grabs the whole screen.
5509 * In portrait mode, it grabs the upper region of the screen based on the vertical dimension
5510 * of the target image.
5511 *
Craig Mautner59c00972012-07-30 12:10:24 -07005512 * @param displayId the Display to take a screenshot of.
Jim Millere70d5062011-03-08 21:38:39 -08005513 * @param width the width of the target bitmap
5514 * @param height the height of the target bitmap
5515 */
Craig Mautner59c00972012-07-30 12:10:24 -07005516 public Bitmap screenshotApplications(IBinder appToken, int displayId, int width, int height) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005517 if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5518 "screenshotApplications()")) {
5519 throw new SecurityException("Requires READ_FRAME_BUFFER permission");
5520 }
5521
5522 Bitmap rawss;
5523
Dianne Hackbornd2835932010-12-13 16:28:46 -08005524 int maxLayer = 0;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005525 final Rect frame = new Rect();
5526
5527 float scale;
Jim Millere70d5062011-03-08 21:38:39 -08005528 int dw, dh;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005529 int rot;
5530
5531 synchronized(mWindowMap) {
5532 long ident = Binder.clearCallingIdentity();
5533
Craig Mautner59c00972012-07-30 12:10:24 -07005534 final DisplayContent displayContent = getDisplayContent(displayId);
5535 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
5536 dw = displayInfo.logicalWidth;
5537 dh = displayInfo.logicalHeight;
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005538
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005539 int aboveAppLayer = mPolicy.windowTypeToLayerLw(
5540 WindowManager.LayoutParams.TYPE_APPLICATION) * TYPE_LAYER_MULTIPLIER
5541 + TYPE_LAYER_OFFSET;
5542 aboveAppLayer += TYPE_LAYER_MULTIPLIER;
5543
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005544 boolean isImeTarget = mInputMethodTarget != null
5545 && mInputMethodTarget.mAppToken != null
5546 && mInputMethodTarget.mAppToken.appToken != null
5547 && mInputMethodTarget.mAppToken.appToken.asBinder() == appToken;
5548
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005549 // Figure out the part of the screen that is actually the app.
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005550 boolean including = false;
Craig Mautner59c00972012-07-30 12:10:24 -07005551 final WindowList windows = displayContent.getWindowList();
5552 for (int i = windows.size() - 1; i >= 0; i--) {
5553 WindowState ws = windows.get(i);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07005554 if (!ws.mHasSurface) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005555 continue;
5556 }
5557 if (ws.mLayer >= aboveAppLayer) {
Dianne Hackbornd2835932010-12-13 16:28:46 -08005558 continue;
5559 }
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005560 // When we will skip windows: when we are not including
5561 // ones behind a window we didn't skip, and we are actually
5562 // taking a screenshot of a specific app.
5563 if (!including && appToken != null) {
5564 // Also, we can possibly skip this window if it is not
5565 // an IME target or the application for the screenshot
5566 // is not the current IME target.
5567 if (!ws.mIsImWindow || !isImeTarget) {
5568 // And finally, this window is of no interest if it
5569 // is not associated with the screenshot app.
5570 if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
5571 continue;
5572 }
5573 }
5574 }
5575
5576 // We keep on including windows until we go past a full-screen
5577 // window.
5578 including = !ws.mIsImWindow && !ws.isFullscreen(dw, dh);
5579
Craig Mautner88165682012-05-31 14:25:31 -07005580 if (maxLayer < ws.mWinAnimator.mSurfaceLayer) {
5581 maxLayer = ws.mWinAnimator.mSurfaceLayer;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005582 }
Jim Miller2aded182011-03-08 15:32:42 -08005583
5584 // Don't include wallpaper in bounds calculation
5585 if (!ws.mIsWallpaper) {
Dianne Hackbornffb3d932011-05-17 17:44:51 -07005586 final Rect wf = ws.mFrame;
Jim Miller2aded182011-03-08 15:32:42 -08005587 final Rect cr = ws.mContentInsets;
5588 int left = wf.left + cr.left;
5589 int top = wf.top + cr.top;
5590 int right = wf.right - cr.right;
5591 int bottom = wf.bottom - cr.bottom;
5592 frame.union(left, top, right, bottom);
5593 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005594 }
5595 Binder.restoreCallingIdentity(ident);
5596
Dianne Hackborndd962ee2011-02-02 11:11:50 -08005597 // Constrain frame to the screen size.
5598 frame.intersect(0, 0, dw, dh);
Jim Millere70d5062011-03-08 21:38:39 -08005599
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005600 if (frame.isEmpty() || maxLayer == 0) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005601 return null;
5602 }
5603
5604 // The screenshot API does not apply the current screen rotation.
5605 rot = mDisplay.getRotation();
5606 int fw = frame.width();
5607 int fh = frame.height();
5608
Jim Miller28637ba2011-07-06 19:57:05 -07005609 // Constrain thumbnail to smaller of screen width or height. Assumes aspect
5610 // of thumbnail is the same as the screen (in landscape) or square.
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005611 float targetWidthScale = width / (float) fw;
5612 float targetHeightScale = height / (float) fh;
Jim Miller28637ba2011-07-06 19:57:05 -07005613 if (dw <= dh) {
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005614 scale = targetWidthScale;
5615 // If aspect of thumbnail is the same as the screen (in landscape),
5616 // select the slightly larger value so we fill the entire bitmap
5617 if (targetHeightScale > scale && (int) (targetHeightScale * fw) == width) {
5618 scale = targetHeightScale;
5619 }
Jim Miller28637ba2011-07-06 19:57:05 -07005620 } else {
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005621 scale = targetHeightScale;
5622 // If aspect of thumbnail is the same as the screen (in landscape),
5623 // select the slightly larger value so we fill the entire bitmap
5624 if (targetWidthScale > scale && (int) (targetWidthScale * fh) == height) {
5625 scale = targetWidthScale;
5626 }
Jim Miller28637ba2011-07-06 19:57:05 -07005627 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005628
5629 // The screen shot will contain the entire screen.
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005630 dw = (int)(dw*scale);
5631 dh = (int)(dh*scale);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005632 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
5633 int tmp = dw;
5634 dw = dh;
5635 dh = tmp;
5636 rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
5637 }
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -07005638 if (DEBUG_SCREENSHOT) {
5639 Slog.i(TAG, "Screenshot: " + dw + "x" + dh + " from 0 to " + maxLayer);
Craig Mautner59c00972012-07-30 12:10:24 -07005640 for (int i = 0; i < windows.size(); i++) {
5641 WindowState win = windows.get(i);
5642 Slog.i(TAG, win + ": " + win.mLayer
5643 + " animLayer=" + win.mWinAnimator.mAnimLayer
5644 + " surfaceLayer=" + win.mWinAnimator.mSurfaceLayer);
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -07005645 }
5646 }
Dianne Hackbornd2835932010-12-13 16:28:46 -08005647 rawss = Surface.screenshot(dw, dh, 0, maxLayer);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005648 }
5649
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005650 if (rawss == null) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07005651 Slog.w(TAG, "Failure taking screenshot for (" + dw + "x" + dh
Dianne Hackborn88b03bd2010-12-16 11:15:18 -08005652 + ") to layer " + maxLayer);
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005653 return null;
5654 }
Jim Millere70d5062011-03-08 21:38:39 -08005655
5656 Bitmap bm = Bitmap.createBitmap(width, height, rawss.getConfig());
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005657 Matrix matrix = new Matrix();
5658 ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
Michael Jurka4accb6a2012-03-26 09:18:46 -07005659 matrix.postTranslate(-FloatMath.ceil(frame.left*scale), -FloatMath.ceil(frame.top*scale));
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005660 Canvas canvas = new Canvas(bm);
5661 canvas.drawBitmap(rawss, matrix, null);
Dianne Hackborn6311d0a2011-08-02 16:37:58 -07005662 canvas.setBitmap(null);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005663
5664 rawss.recycle();
5665 return bm;
5666 }
5667
Jeff Brown01a98dd2011-09-20 15:08:29 -07005668 /**
5669 * Freeze rotation changes. (Enable "rotation lock".)
5670 * Persists across reboots.
Jeff Brown4dfce202011-10-05 12:00:10 -07005671 * @param rotation The desired rotation to freeze to, or -1 to use the
5672 * current rotation.
Jeff Brown01a98dd2011-09-20 15:08:29 -07005673 */
Jeff Brown4dfce202011-10-05 12:00:10 -07005674 public void freezeRotation(int rotation) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005675 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005676 "freezeRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005677 throw new SecurityException("Requires SET_ORIENTATION permission");
5678 }
Jeff Brown4dfce202011-10-05 12:00:10 -07005679 if (rotation < -1 || rotation > Surface.ROTATION_270) {
5680 throw new IllegalArgumentException("Rotation argument must be -1 or a valid "
5681 + "rotation constant.");
5682 }
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005683
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005684 if (DEBUG_ORIENTATION) Slog.v(TAG, "freezeRotation: mRotation=" + mRotation);
5685
Jeff Brown4dfce202011-10-05 12:00:10 -07005686 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED,
5687 rotation == -1 ? mRotation : rotation);
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005688 updateRotationUnchecked(false, false);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005689 }
5690
Jeff Brown01a98dd2011-09-20 15:08:29 -07005691 /**
5692 * Thaw rotation changes. (Disable "rotation lock".)
5693 * Persists across reboots.
5694 */
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005695 public void thawRotation() {
5696 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005697 "thawRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005698 throw new SecurityException("Requires SET_ORIENTATION permission");
5699 }
5700
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005701 if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation);
5702
5703 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 777); // rot not used
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005704 updateRotationUnchecked(false, false);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005705 }
5706
Jeff Brown01a98dd2011-09-20 15:08:29 -07005707 /**
5708 * Recalculate the current rotation.
5709 *
5710 * Called by the window manager policy whenever the state of the system changes
5711 * such that the current rotation might need to be updated, such as when the
5712 * device is docked or rotated into a new posture.
5713 */
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005714 public void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
5715 updateRotationUnchecked(alwaysSendConfiguration, forceRelayout);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005716 }
5717
5718 /**
5719 * Temporarily pauses rotation changes until resumed.
5720 *
5721 * This can be used to prevent rotation changes from occurring while the user is
5722 * performing certain operations, such as drag and drop.
5723 *
5724 * This call nests and must be matched by an equal number of calls to {@link #resumeRotation}.
5725 */
5726 void pauseRotationLocked() {
5727 mDeferredRotationPauseCount += 1;
5728 }
5729
5730 /**
5731 * Resumes normal rotation changes after being paused.
5732 */
5733 void resumeRotationLocked() {
5734 if (mDeferredRotationPauseCount > 0) {
5735 mDeferredRotationPauseCount -= 1;
5736 if (mDeferredRotationPauseCount == 0) {
5737 boolean changed = updateRotationUncheckedLocked(false);
5738 if (changed) {
5739 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
5740 }
5741 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005742 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005743 }
Romain Guy06882f82009-06-10 13:36:04 -07005744
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005745 public void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005746 if(DEBUG_ORIENTATION) Slog.v(TAG, "updateRotationUnchecked("
5747 + "alwaysSendConfiguration=" + alwaysSendConfiguration + ")");
Romain Guy06882f82009-06-10 13:36:04 -07005748
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005749 long origId = Binder.clearCallingIdentity();
5750 boolean changed;
5751 synchronized(mWindowMap) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005752 changed = updateRotationUncheckedLocked(false);
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005753 if (!changed || forceRelayout) {
5754 mLayoutNeeded = true;
5755 performLayoutAndPlaceSurfacesLocked();
5756 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005757 }
Romain Guy06882f82009-06-10 13:36:04 -07005758
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005759 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005760 sendNewConfiguration();
5761 }
Romain Guy06882f82009-06-10 13:36:04 -07005762
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005763 Binder.restoreCallingIdentity(origId);
5764 }
Romain Guy06882f82009-06-10 13:36:04 -07005765
Craig Mautner59c00972012-07-30 12:10:24 -07005766 // TODO(multidisplay): Rotate any display?
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005767 /**
Jeff Brown01a98dd2011-09-20 15:08:29 -07005768 * Updates the current rotation.
5769 *
5770 * Returns true if the rotation has been changed. In this case YOU
5771 * MUST CALL sendNewConfiguration() TO UNFREEZE THE SCREEN.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005772 */
Jeff Brown01a98dd2011-09-20 15:08:29 -07005773 public boolean updateRotationUncheckedLocked(boolean inTransaction) {
5774 if (mDeferredRotationPauseCount > 0) {
5775 // Rotation updates have been paused temporarily. Defer the update until
5776 // updates have been resumed.
5777 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, rotation is paused.");
Christopher Tateccd24de2011-01-12 15:02:55 -08005778 return false;
5779 }
5780
Craig Mautner764983d2012-03-22 11:37:36 -07005781 if (mAnimator.mScreenRotationAnimation != null &&
5782 mAnimator.mScreenRotationAnimation.isAnimating()) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005783 // Rotation updates cannot be performed while the previous rotation change
5784 // animation is still in progress. Skip this update. We will try updating
5785 // again after the animation is finished and the display is unfrozen.
5786 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, animation in progress.");
5787 return false;
5788 }
5789
5790 if (!mDisplayEnabled) {
5791 // No point choosing a rotation if the display is not enabled.
5792 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, display is not enabled.");
5793 return false;
5794 }
5795
5796 // TODO: Implement forced rotation changes.
5797 // Set mAltOrientation to indicate that the application is receiving
5798 // an orientation that has different metrics than it expected.
5799 // eg. Portrait instead of Landscape.
5800
5801 int rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, mRotation);
5802 boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
5803 mForcedAppOrientation, rotation);
5804
5805 if (DEBUG_ORIENTATION) {
5806 Slog.v(TAG, "Application requested orientation "
5807 + mForcedAppOrientation + ", got rotation " + rotation
5808 + " which has " + (altOrientation ? "incompatible" : "compatible")
5809 + " metrics");
5810 }
5811
5812 if (mRotation == rotation && mAltOrientation == altOrientation) {
5813 // No change.
5814 return false;
5815 }
5816
5817 if (DEBUG_ORIENTATION) {
5818 Slog.v(TAG,
5819 "Rotation changed to " + rotation + (altOrientation ? " (alt)" : "")
5820 + " from " + mRotation + (mAltOrientation ? " (alt)" : "")
5821 + ", forceApp=" + mForcedAppOrientation);
5822 }
5823
5824 mRotation = rotation;
5825 mAltOrientation = altOrientation;
Jeff Brownc0347aa2011-09-23 17:26:09 -07005826 mPolicy.setRotationLw(mRotation);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005827
5828 mWindowsFreezingScreen = true;
5829 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
5830 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT), 2000);
5831 mWaitingForConfig = true;
5832 mLayoutNeeded = true;
5833 startFreezingDisplayLocked(inTransaction);
Jeff Brownfa25bf52012-07-23 19:26:30 -07005834 mInputManager.setDisplayOrientation(0, rotation, Surface.ROTATION_0);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005835
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08005836 // We need to update our screen size information to match the new
5837 // rotation. Note that this is redundant with the later call to
5838 // sendNewConfiguration() that must be called after this function
5839 // returns... however we need to do the screen size part of that
5840 // before then so we have the correct size to use when initializiation
5841 // the rotation animation for the new rotation.
5842 computeScreenConfigurationLocked(null);
5843
Jamie Gennise2909e12011-10-10 15:48:06 -07005844 if (!inTransaction) {
Dianne Hackborn36991742011-10-11 21:35:26 -07005845 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Jamie Gennise2909e12011-10-10 15:48:06 -07005846 ">>> OPEN TRANSACTION setRotationUnchecked");
5847 Surface.openTransaction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005848 }
Craig Mautner59c00972012-07-30 12:10:24 -07005849 final DisplayContent displayContent = getDefaultDisplayContent();
5850 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
Jamie Gennise2909e12011-10-10 15:48:06 -07005851 try {
5852 // NOTE: We disable the rotation in the emulator because
5853 // it doesn't support hardware OpenGL emulation yet.
Craig Mautner764983d2012-03-22 11:37:36 -07005854 if (CUSTOM_SCREEN_ROTATION && mAnimator.mScreenRotationAnimation != null
5855 && mAnimator.mScreenRotationAnimation.hasScreenshot()) {
5856 if (mAnimator.mScreenRotationAnimation.setRotation(rotation, mFxSession,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08005857 MAX_ANIMATION_DURATION, mTransitionAnimationScale,
Craig Mautner59c00972012-07-30 12:10:24 -07005858 displayInfo.logicalWidth, displayInfo.logicalHeight)) {
Craig Mautner711f90a2012-07-03 18:43:52 -07005859 updateLayoutToAnimationLocked();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08005860 }
Jamie Gennise2909e12011-10-10 15:48:06 -07005861 }
5862 Surface.setOrientation(0, rotation);
5863 } finally {
5864 if (!inTransaction) {
5865 Surface.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -07005866 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Jamie Gennise2909e12011-10-10 15:48:06 -07005867 "<<< CLOSE TRANSACTION setRotationUnchecked");
5868 }
5869 }
5870
Craig Mautner2fb98b12012-03-20 17:24:00 -07005871 rebuildBlackFrame();
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005872
Craig Mautner59c00972012-07-30 12:10:24 -07005873 final WindowList windows = displayContent.getWindowList();
5874 for (int i = windows.size() - 1; i >= 0; i--) {
5875 WindowState w = windows.get(i);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07005876 if (w.mHasSurface) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07005877 if (DEBUG_ORIENTATION) Slog.v(TAG, "Set mOrientationChanging of " + w);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005878 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07005879 mInnerFields.mOrientationChangeComplete = false;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005880 }
5881 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07005882 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
5883 try {
5884 mRotationWatchers.get(i).onRotationChanged(rotation);
5885 } catch (RemoteException e) {
5886 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005887 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07005888 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005889 }
Romain Guy06882f82009-06-10 13:36:04 -07005890
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005891 public int getRotation() {
5892 return mRotation;
5893 }
5894
5895 public int watchRotation(IRotationWatcher watcher) {
5896 final IBinder watcherBinder = watcher.asBinder();
5897 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
5898 public void binderDied() {
5899 synchronized (mWindowMap) {
5900 for (int i=0; i<mRotationWatchers.size(); i++) {
5901 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07005902 IRotationWatcher removed = mRotationWatchers.remove(i);
5903 if (removed != null) {
5904 removed.asBinder().unlinkToDeath(this, 0);
5905 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005906 i--;
5907 }
5908 }
5909 }
5910 }
5911 };
Romain Guy06882f82009-06-10 13:36:04 -07005912
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005913 synchronized (mWindowMap) {
5914 try {
5915 watcher.asBinder().linkToDeath(dr, 0);
5916 mRotationWatchers.add(watcher);
5917 } catch (RemoteException e) {
5918 // Client died, no cleanup needed.
5919 }
Romain Guy06882f82009-06-10 13:36:04 -07005920
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005921 return mRotation;
5922 }
5923 }
5924
5925 /**
Adam Powelldfee59a2011-08-05 20:48:30 -07005926 * Apps that use the compact menu panel (as controlled by the panelMenuIsCompact
5927 * theme attribute) on devices that feature a physical options menu key attempt to position
5928 * their menu panel window along the edge of the screen nearest the physical menu key.
5929 * This lowers the travel distance between invoking the menu panel and selecting
5930 * a menu option.
5931 *
5932 * This method helps control where that menu is placed. Its current implementation makes
5933 * assumptions about the menu key and its relationship to the screen based on whether
5934 * the device's natural orientation is portrait (width < height) or landscape.
5935 *
5936 * The menu key is assumed to be located along the bottom edge of natural-portrait
5937 * devices and along the right edge of natural-landscape devices. If these assumptions
5938 * do not hold for the target device, this method should be changed to reflect that.
5939 *
5940 * @return A {@link Gravity} value for placing the options menu window
5941 */
5942 public int getPreferredOptionsPanelGravity() {
5943 synchronized (mWindowMap) {
5944 final int rotation = getRotation();
5945
Craig Mautner59c00972012-07-30 12:10:24 -07005946 // TODO(multidisplay): Assume that such devices physical keys are on the main screen.
5947 final DisplayContent displayContent = getDefaultDisplayContent();
5948 if (displayContent.mInitialDisplayWidth < displayContent.mInitialDisplayHeight) {
Adam Powelldfee59a2011-08-05 20:48:30 -07005949 // On devices with a natural orientation of portrait
5950 switch (rotation) {
5951 default:
5952 case Surface.ROTATION_0:
5953 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
5954 case Surface.ROTATION_90:
Adam Powell67ed6c72011-08-28 13:21:56 -07005955 return Gravity.RIGHT | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07005956 case Surface.ROTATION_180:
Adam Powell67ed6c72011-08-28 13:21:56 -07005957 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07005958 case Surface.ROTATION_270:
Fabrice Di Meglioaac0d4e2012-07-19 19:21:26 -07005959 return Gravity.START | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07005960 }
5961 } else {
5962 // On devices with a natural orientation of landscape
5963 switch (rotation) {
5964 default:
5965 case Surface.ROTATION_0:
Adam Powell67ed6c72011-08-28 13:21:56 -07005966 return Gravity.RIGHT | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07005967 case Surface.ROTATION_90:
5968 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
5969 case Surface.ROTATION_180:
Fabrice Di Meglioaac0d4e2012-07-19 19:21:26 -07005970 return Gravity.START | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07005971 case Surface.ROTATION_270:
Adam Powell67ed6c72011-08-28 13:21:56 -07005972 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07005973 }
5974 }
5975 }
5976 }
5977
5978 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005979 * Starts the view server on the specified port.
5980 *
5981 * @param port The port to listener to.
5982 *
5983 * @return True if the server was successfully started, false otherwise.
5984 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08005985 * @see com.android.server.wm.ViewServer
5986 * @see com.android.server.wm.ViewServer#VIEW_SERVER_DEFAULT_PORT
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005987 */
5988 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07005989 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005990 return false;
5991 }
5992
5993 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
5994 return false;
5995 }
5996
5997 if (port < 1024) {
5998 return false;
5999 }
6000
6001 if (mViewServer != null) {
6002 if (!mViewServer.isRunning()) {
6003 try {
6004 return mViewServer.start();
6005 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006006 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006007 }
6008 }
6009 return false;
6010 }
6011
6012 try {
6013 mViewServer = new ViewServer(this, port);
6014 return mViewServer.start();
6015 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006016 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006017 }
6018 return false;
6019 }
6020
Romain Guy06882f82009-06-10 13:36:04 -07006021 private boolean isSystemSecure() {
6022 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
6023 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6024 }
6025
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006026 /**
6027 * Stops the view server if it exists.
6028 *
6029 * @return True if the server stopped, false if it wasn't started or
6030 * couldn't be stopped.
6031 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08006032 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006033 */
6034 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07006035 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006036 return false;
6037 }
6038
6039 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
6040 return false;
6041 }
6042
6043 if (mViewServer != null) {
6044 return mViewServer.stop();
6045 }
6046 return false;
6047 }
6048
6049 /**
6050 * Indicates whether the view server is running.
6051 *
6052 * @return True if the server is running, false otherwise.
6053 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08006054 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006055 */
6056 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07006057 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006058 return false;
6059 }
6060
6061 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
6062 return false;
6063 }
6064
6065 return mViewServer != null && mViewServer.isRunning();
6066 }
6067
6068 /**
6069 * Lists all availble windows in the system. The listing is written in the
6070 * specified Socket's output stream with the following syntax:
6071 * windowHashCodeInHexadecimal windowName
6072 * Each line of the ouput represents a different window.
6073 *
6074 * @param client The remote client to send the listing to.
6075 * @return False if an error occured, true otherwise.
6076 */
6077 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07006078 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006079 return false;
6080 }
6081
6082 boolean result = true;
6083
Craig Mautner59c00972012-07-30 12:10:24 -07006084 WindowList windows = new WindowList();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006085 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006086 //noinspection unchecked
Craig Mautner59c00972012-07-30 12:10:24 -07006087 DisplayContentsIterator iterator = new DisplayContentsIterator();
6088 while(iterator.hasNext()) {
6089 windows.addAll(iterator.next().getWindowList());
6090 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006091 }
6092
6093 BufferedWriter out = null;
6094
6095 // Any uncaught exception will crash the system process
6096 try {
6097 OutputStream clientStream = client.getOutputStream();
6098 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
6099
Craig Mautner59c00972012-07-30 12:10:24 -07006100 final int count = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006101 for (int i = 0; i < count; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07006102 final WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006103 out.write(Integer.toHexString(System.identityHashCode(w)));
6104 out.write(' ');
6105 out.append(w.mAttrs.getTitle());
6106 out.write('\n');
6107 }
6108
6109 out.write("DONE.\n");
6110 out.flush();
6111 } catch (Exception e) {
6112 result = false;
6113 } finally {
6114 if (out != null) {
6115 try {
6116 out.close();
6117 } catch (IOException e) {
6118 result = false;
6119 }
6120 }
6121 }
6122
6123 return result;
6124 }
6125
Craig Mautner59c00972012-07-30 12:10:24 -07006126 // TODO(multidisplay): Extend to multiple displays.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006127 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07006128 * Returns the focused window in the following format:
6129 * windowHashCodeInHexadecimal windowName
6130 *
6131 * @param client The remote client to send the listing to.
6132 * @return False if an error occurred, true otherwise.
6133 */
6134 boolean viewServerGetFocusedWindow(Socket client) {
6135 if (isSystemSecure()) {
6136 return false;
6137 }
6138
6139 boolean result = true;
6140
6141 WindowState focusedWindow = getFocusedWindow();
6142
6143 BufferedWriter out = null;
6144
6145 // Any uncaught exception will crash the system process
6146 try {
6147 OutputStream clientStream = client.getOutputStream();
6148 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
6149
6150 if(focusedWindow != null) {
6151 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
6152 out.write(' ');
6153 out.append(focusedWindow.mAttrs.getTitle());
6154 }
6155 out.write('\n');
6156 out.flush();
6157 } catch (Exception e) {
6158 result = false;
6159 } finally {
6160 if (out != null) {
6161 try {
6162 out.close();
6163 } catch (IOException e) {
6164 result = false;
6165 }
6166 }
6167 }
6168
6169 return result;
6170 }
6171
6172 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006173 * Sends a command to a target window. The result of the command, if any, will be
6174 * written in the output stream of the specified socket.
6175 *
6176 * The parameters must follow this syntax:
6177 * windowHashcode extra
6178 *
6179 * Where XX is the length in characeters of the windowTitle.
6180 *
6181 * The first parameter is the target window. The window with the specified hashcode
6182 * will be the target. If no target can be found, nothing happens. The extra parameters
6183 * will be delivered to the target window and as parameters to the command itself.
6184 *
6185 * @param client The remote client to sent the result, if any, to.
6186 * @param command The command to execute.
6187 * @param parameters The command parameters.
6188 *
6189 * @return True if the command was successfully delivered, false otherwise. This does
6190 * not indicate whether the command itself was successful.
6191 */
6192 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
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 boolean success = true;
6198 Parcel data = null;
6199 Parcel reply = null;
6200
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006201 BufferedWriter out = null;
6202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006203 // Any uncaught exception will crash the system process
6204 try {
6205 // Find the hashcode of the window
6206 int index = parameters.indexOf(' ');
6207 if (index == -1) {
6208 index = parameters.length();
6209 }
6210 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08006211 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006212
6213 // Extract the command's parameter after the window description
6214 if (index < parameters.length()) {
6215 parameters = parameters.substring(index + 1);
6216 } else {
6217 parameters = "";
6218 }
6219
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006220 final WindowState window = findWindow(hashCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006221 if (window == null) {
6222 return false;
6223 }
6224
6225 data = Parcel.obtain();
6226 data.writeInterfaceToken("android.view.IWindow");
6227 data.writeString(command);
6228 data.writeString(parameters);
6229 data.writeInt(1);
6230 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
6231
6232 reply = Parcel.obtain();
6233
6234 final IBinder binder = window.mClient.asBinder();
6235 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
6236 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
6237
6238 reply.readException();
6239
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006240 if (!client.isOutputShutdown()) {
6241 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
6242 out.write("DONE\n");
6243 out.flush();
6244 }
6245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006246 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006247 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006248 success = false;
6249 } finally {
6250 if (data != null) {
6251 data.recycle();
6252 }
6253 if (reply != null) {
6254 reply.recycle();
6255 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006256 if (out != null) {
6257 try {
6258 out.close();
6259 } catch (IOException e) {
6260
6261 }
6262 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006263 }
6264
6265 return success;
6266 }
6267
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07006268 public void addWindowChangeListener(WindowChangeListener listener) {
6269 synchronized(mWindowMap) {
6270 mWindowChangeListeners.add(listener);
6271 }
6272 }
6273
6274 public void removeWindowChangeListener(WindowChangeListener listener) {
6275 synchronized(mWindowMap) {
6276 mWindowChangeListeners.remove(listener);
6277 }
6278 }
6279
6280 private void notifyWindowsChanged() {
6281 WindowChangeListener[] windowChangeListeners;
6282 synchronized(mWindowMap) {
6283 if(mWindowChangeListeners.isEmpty()) {
6284 return;
6285 }
6286 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
6287 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
6288 }
6289 int N = windowChangeListeners.length;
6290 for(int i = 0; i < N; i++) {
6291 windowChangeListeners[i].windowsChanged();
6292 }
6293 }
6294
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07006295 private void notifyFocusChanged() {
6296 WindowChangeListener[] windowChangeListeners;
6297 synchronized(mWindowMap) {
6298 if(mWindowChangeListeners.isEmpty()) {
6299 return;
6300 }
6301 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
6302 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
6303 }
6304 int N = windowChangeListeners.length;
6305 for(int i = 0; i < N; i++) {
6306 windowChangeListeners[i].focusChanged();
6307 }
6308 }
6309
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006310 private WindowState findWindow(int hashCode) {
6311 if (hashCode == -1) {
Craig Mautner59c00972012-07-30 12:10:24 -07006312 // TODO(multidisplay): Extend to multiple displays.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006313 return getFocusedWindow();
6314 }
6315
6316 synchronized (mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -07006317 final AllWindowsIterator iterator = new AllWindowsIterator();
6318 while (iterator.hasNext()) {
6319 final WindowState w = iterator.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006320 if (System.identityHashCode(w) == hashCode) {
6321 return w;
6322 }
6323 }
6324 }
6325
6326 return null;
6327 }
6328
6329 /*
6330 * Instruct the Activity Manager to fetch the current configuration and broadcast
6331 * that to config-changed listeners if appropriate.
6332 */
6333 void sendNewConfiguration() {
6334 try {
6335 mActivityManager.updateConfiguration(null);
6336 } catch (RemoteException e) {
6337 }
6338 }
Romain Guy06882f82009-06-10 13:36:04 -07006339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006340 public Configuration computeNewConfiguration() {
6341 synchronized (mWindowMap) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006342 Configuration config = computeNewConfigurationLocked();
6343 if (config == null && mWaitingForConfig) {
6344 // Nothing changed but we are waiting for something... stop that!
6345 mWaitingForConfig = false;
6346 performLayoutAndPlaceSurfacesLocked();
6347 }
6348 return config;
Dianne Hackbornc485a602009-03-24 22:39:49 -07006349 }
6350 }
Romain Guy06882f82009-06-10 13:36:04 -07006351
Dianne Hackbornc485a602009-03-24 22:39:49 -07006352 Configuration computeNewConfigurationLocked() {
6353 Configuration config = new Configuration();
Dianne Hackborn09e5b9d2011-10-04 16:32:01 -07006354 config.fontScale = 0;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006355 if (!computeScreenConfigurationLocked(config)) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07006356 return null;
6357 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07006358 return config;
6359 }
Romain Guy06882f82009-06-10 13:36:04 -07006360
Craig Mautner59c00972012-07-30 12:10:24 -07006361 private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation, int dw, int dh) {
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006362 final int width = mPolicy.getConfigDisplayWidth(dw, dh, rotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006363 if (width < displayInfo.smallestNominalAppWidth) {
6364 displayInfo.smallestNominalAppWidth = width;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006365 }
Craig Mautner59c00972012-07-30 12:10:24 -07006366 if (width > displayInfo.largestNominalAppWidth) {
6367 displayInfo.largestNominalAppWidth = width;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006368 }
6369 final int height = mPolicy.getConfigDisplayHeight(dw, dh, rotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006370 if (height < displayInfo.smallestNominalAppHeight) {
6371 displayInfo.smallestNominalAppHeight = height;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006372 }
Craig Mautner59c00972012-07-30 12:10:24 -07006373 if (height > displayInfo.largestNominalAppHeight) {
6374 displayInfo.largestNominalAppHeight = height;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006375 }
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006376 }
6377
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006378 private int reduceConfigLayout(int curLayout, int rotation, float density,
6379 int dw, int dh) {
6380 // Get the app screen size at this rotation.
6381 int w = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
6382 int h = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
6383
6384 // Compute the screen layout size class for this rotation.
6385 int screenLayoutSize;
6386 boolean screenLayoutLong;
6387 boolean screenLayoutCompatNeeded;
6388 int longSize = w;
6389 int shortSize = h;
6390 if (longSize < shortSize) {
6391 int tmp = longSize;
6392 longSize = shortSize;
6393 shortSize = tmp;
6394 }
6395 longSize = (int)(longSize/density);
6396 shortSize = (int)(shortSize/density);
6397
6398 // These semi-magic numbers define our compatibility modes for
6399 // applications with different screens. These are guarantees to
6400 // app developers about the space they can expect for a particular
6401 // configuration. DO NOT CHANGE!
6402 if (longSize < 470) {
6403 // This is shorter than an HVGA normal density screen (which
6404 // is 480 pixels on its long side).
6405 screenLayoutSize = Configuration.SCREENLAYOUT_SIZE_SMALL;
6406 screenLayoutLong = false;
6407 screenLayoutCompatNeeded = false;
6408 } else {
6409 // What size is this screen screen?
6410 if (longSize >= 960 && shortSize >= 720) {
6411 // 1.5xVGA or larger screens at medium density are the point
6412 // at which we consider it to be an extra large screen.
6413 screenLayoutSize = Configuration.SCREENLAYOUT_SIZE_XLARGE;
6414 } else if (longSize >= 640 && shortSize >= 480) {
6415 // VGA or larger screens at medium density are the point
6416 // at which we consider it to be a large screen.
6417 screenLayoutSize = Configuration.SCREENLAYOUT_SIZE_LARGE;
6418 } else {
6419 screenLayoutSize = Configuration.SCREENLAYOUT_SIZE_NORMAL;
6420 }
6421
6422 // If this screen is wider than normal HVGA, or taller
6423 // than FWVGA, then for old apps we want to run in size
6424 // compatibility mode.
6425 if (shortSize > 321 || longSize > 570) {
6426 screenLayoutCompatNeeded = true;
6427 } else {
6428 screenLayoutCompatNeeded = false;
6429 }
6430
6431 // Is this a long screen?
6432 if (((longSize*3)/5) >= (shortSize-1)) {
6433 // Anything wider than WVGA (5:3) is considering to be long.
6434 screenLayoutLong = true;
6435 } else {
6436 screenLayoutLong = false;
6437 }
6438 }
6439
6440 // Now reduce the last screenLayout to not be better than what we
6441 // have found.
6442 if (!screenLayoutLong) {
6443 curLayout = (curLayout&~Configuration.SCREENLAYOUT_LONG_MASK)
6444 | Configuration.SCREENLAYOUT_LONG_NO;
6445 }
6446 if (screenLayoutCompatNeeded) {
6447 curLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
6448 }
6449 int curSize = curLayout&Configuration.SCREENLAYOUT_SIZE_MASK;
6450 if (screenLayoutSize < curSize) {
6451 curLayout = (curLayout&~Configuration.SCREENLAYOUT_SIZE_MASK)
6452 | screenLayoutSize;
6453 }
6454 return curLayout;
6455 }
6456
Craig Mautner59c00972012-07-30 12:10:24 -07006457 private void computeSizeRangesAndScreenLayout(DisplayInfo displayInfo, boolean rotated,
6458 int dw, int dh, float density, Configuration outConfig) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006459 // We need to determine the smallest width that will occur under normal
6460 // operation. To this, start with the base screen size and compute the
6461 // width under the different possible rotations. We need to un-rotate
6462 // the current screen dimensions before doing this.
6463 int unrotDw, unrotDh;
6464 if (rotated) {
6465 unrotDw = dh;
6466 unrotDh = dw;
6467 } else {
6468 unrotDw = dw;
6469 unrotDh = dh;
6470 }
Craig Mautner59c00972012-07-30 12:10:24 -07006471 displayInfo.smallestNominalAppWidth = 1<<30;
6472 displayInfo.smallestNominalAppHeight = 1<<30;
6473 displayInfo.largestNominalAppWidth = 0;
6474 displayInfo.largestNominalAppHeight = 0;
6475 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, unrotDw, unrotDh);
6476 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, unrotDh, unrotDw);
6477 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, unrotDw, unrotDh);
6478 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, unrotDh, unrotDw);
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006479 int sl = Configuration.SCREENLAYOUT_SIZE_XLARGE
6480 | Configuration.SCREENLAYOUT_LONG_YES;
6481 sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh);
6482 sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw);
6483 sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh);
6484 sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw);
Craig Mautner59c00972012-07-30 12:10:24 -07006485 outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006486 outConfig.screenLayout = sl;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006487 }
6488
Dianne Hackborn48a76512011-06-08 21:51:44 -07006489 private int reduceCompatConfigWidthSize(int curSize, int rotation, DisplayMetrics dm,
6490 int dw, int dh) {
Dianne Hackborn1f903c32011-09-13 19:18:06 -07006491 dm.noncompatWidthPixels = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
6492 dm.noncompatHeightPixels = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006493 float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
Dianne Hackborn2b31d532011-06-23 11:58:50 -07006494 int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006495 if (curSize == 0 || size < curSize) {
6496 curSize = size;
6497 }
6498 return curSize;
6499 }
6500
6501 private int computeCompatSmallestWidth(boolean rotated, DisplayMetrics dm, int dw, int dh) {
6502 mTmpDisplayMetrics.setTo(dm);
6503 dm = mTmpDisplayMetrics;
6504 int unrotDw, unrotDh;
6505 if (rotated) {
6506 unrotDw = dh;
6507 unrotDh = dw;
6508 } else {
6509 unrotDw = dw;
6510 unrotDh = dh;
6511 }
6512 int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, dm, unrotDw, unrotDh);
6513 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, dm, unrotDh, unrotDw);
6514 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, dm, unrotDw, unrotDh);
6515 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, dm, unrotDh, unrotDw);
6516 return sw;
6517 }
6518
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006519 boolean computeScreenConfigurationLocked(Configuration config) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07006520 if (mDisplay == null) {
6521 return false;
6522 }
Christopher Tateb696aee2010-04-02 19:08:30 -07006523
Craig Mautner59c00972012-07-30 12:10:24 -07006524 // TODO(multidisplay): For now, apply Configuration to main screen only.
6525 final DisplayContent displayContent = getDefaultDisplayContent();
6526
Christopher Tateb696aee2010-04-02 19:08:30 -07006527 // Use the effective "visual" dimensions based on current rotation
6528 final boolean rotated = (mRotation == Surface.ROTATION_90
6529 || mRotation == Surface.ROTATION_270);
Craig Mautner59c00972012-07-30 12:10:24 -07006530 final int realdw = rotated ?
6531 displayContent.mBaseDisplayHeight : displayContent.mBaseDisplayWidth;
6532 final int realdh = rotated ?
6533 displayContent.mBaseDisplayWidth : displayContent.mBaseDisplayHeight;
Jeff Brownfa25bf52012-07-23 19:26:30 -07006534 int dw = realdw;
6535 int dh = realdh;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006536
Jeff Brownfa25bf52012-07-23 19:26:30 -07006537 if (mAltOrientation) {
6538 if (realdw > realdh) {
6539 // Turn landscape into portrait.
6540 int maxw = (int)(realdh/1.3f);
6541 if (maxw < realdw) {
6542 dw = maxw;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006543 }
6544 } else {
Jeff Brownfa25bf52012-07-23 19:26:30 -07006545 // Turn portrait into landscape.
6546 int maxh = (int)(realdw/1.3f);
6547 if (maxh < realdh) {
6548 dh = maxh;
6549 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006550 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006551 }
6552
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006553 if (config != null) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006554 int orientation = Configuration.ORIENTATION_SQUARE;
6555 if (dw < dh) {
6556 orientation = Configuration.ORIENTATION_PORTRAIT;
6557 } else if (dw > dh) {
6558 orientation = Configuration.ORIENTATION_LANDSCAPE;
6559 }
6560 config.orientation = orientation;
Dianne Hackbornc485a602009-03-24 22:39:49 -07006561 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006562
Jeff Brownbc68a592011-07-25 12:58:12 -07006563 // Update application display metrics.
Dianne Hackborn1fbee792011-11-30 11:29:58 -08006564 final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation);
6565 final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006566 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
6567 synchronized(displayContent.mDisplaySizeLock) {
6568 displayInfo.rotation = mRotation;
6569 displayInfo.logicalWidth = dw;
6570 displayInfo.logicalHeight = dh;
Dianne Hackborndde331c2012-08-03 14:01:57 -07006571 displayInfo.logicalDensityDpi = displayContent.mBaseDisplayDensity;
Craig Mautner59c00972012-07-30 12:10:24 -07006572 displayInfo.appWidth = appWidth;
6573 displayInfo.appHeight = appHeight;
6574 displayInfo.getLogicalMetrics(mRealDisplayMetrics, null);
6575 displayInfo.getAppMetrics(mDisplayMetrics, null);
Craig Mautner4f67ba62012-08-02 11:23:00 -07006576 mDisplayManager.setDisplayInfo(displayContent.getDisplayId(), displayInfo);
Jeff Brownfa25bf52012-07-23 19:26:30 -07006577
6578 mAnimator.setDisplayDimensions(dw, dh, appWidth, appHeight);
Dianne Hackborn1fbee792011-11-30 11:29:58 -08006579 }
Dianne Hackborn36991742011-10-11 21:35:26 -07006580 if (false) {
Jeff Brownfa25bf52012-07-23 19:26:30 -07006581 Slog.i(TAG, "Set app display size: " + appWidth + " x " + appHeight);
Dianne Hackborn36991742011-10-11 21:35:26 -07006582 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006583
Jeff Brownfa25bf52012-07-23 19:26:30 -07006584 final DisplayMetrics dm = mDisplayMetrics;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006585 mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm,
6586 mCompatDisplayMetrics);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006587
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006588 if (config != null) {
6589 config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation)
6590 / dm.density);
6591 config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation)
6592 / dm.density);
Craig Mautner59c00972012-07-30 12:10:24 -07006593 computeSizeRangesAndScreenLayout(displayInfo, rotated, dw, dh, dm.density, config);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006594
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006595 config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
6596 config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
6597 config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dm, dw, dh);
Dianne Hackborndde331c2012-08-03 14:01:57 -07006598 config.densityDpi = displayContent.mBaseDisplayDensity;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006599
Jeff Browndaa37532012-05-01 15:54:03 -07006600 // Update the configuration based on available input devices, lid switch,
6601 // and platform configuration.
6602 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
6603 config.keyboard = Configuration.KEYBOARD_NOKEYS;
6604 config.navigation = Configuration.NAVIGATION_NONAV;
6605
6606 int keyboardPresence = 0;
6607 int navigationPresence = 0;
Craig Mautner1d961d42012-05-27 12:02:11 -07006608 final InputDevice[] devices = mInputManager.getInputDevices();
6609 final int len = devices.length;
6610 for (int i = 0; i < len; i++) {
6611 InputDevice device = devices[i];
Jeff Browndaa37532012-05-01 15:54:03 -07006612 if (!device.isVirtual()) {
6613 final int sources = device.getSources();
6614 final int presenceFlag = device.isExternal() ?
6615 WindowManagerPolicy.PRESENCE_EXTERNAL :
6616 WindowManagerPolicy.PRESENCE_INTERNAL;
6617
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -07006618 if (mIsTouchDevice) {
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006619 if ((sources & InputDevice.SOURCE_TOUCHSCREEN) ==
6620 InputDevice.SOURCE_TOUCHSCREEN) {
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -07006621 config.touchscreen = Configuration.TOUCHSCREEN_FINGER;
6622 }
6623 } else {
6624 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
Jeff Browndaa37532012-05-01 15:54:03 -07006625 }
6626
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006627 if ((sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) {
Jeff Browndaa37532012-05-01 15:54:03 -07006628 config.navigation = Configuration.NAVIGATION_TRACKBALL;
6629 navigationPresence |= presenceFlag;
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006630 } else if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD
Jeff Browndaa37532012-05-01 15:54:03 -07006631 && config.navigation == Configuration.NAVIGATION_NONAV) {
6632 config.navigation = Configuration.NAVIGATION_DPAD;
6633 navigationPresence |= presenceFlag;
6634 }
6635
6636 if (device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) {
6637 config.keyboard = Configuration.KEYBOARD_QWERTY;
6638 keyboardPresence |= presenceFlag;
6639 }
6640 }
6641 }
6642
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006643 // Determine whether a hard keyboard is available and enabled.
6644 boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
6645 if (hardKeyboardAvailable != mHardKeyboardAvailable) {
6646 mHardKeyboardAvailable = hardKeyboardAvailable;
6647 mHardKeyboardEnabled = hardKeyboardAvailable;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006648 mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
6649 mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
6650 }
6651 if (!mHardKeyboardEnabled) {
6652 config.keyboard = Configuration.KEYBOARD_NOKEYS;
6653 }
6654
Jeff Browndaa37532012-05-01 15:54:03 -07006655 // Let the policy update hidden states.
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006656 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
6657 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
6658 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO;
Jeff Browndaa37532012-05-01 15:54:03 -07006659 mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence);
Jeff Brown2992ea72011-01-28 22:04:14 -08006660 }
Jeff Brown597eec82011-01-31 17:12:25 -08006661
Dianne Hackbornc485a602009-03-24 22:39:49 -07006662 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006663 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006664
Jeff Brown2992ea72011-01-28 22:04:14 -08006665 public boolean isHardKeyboardAvailable() {
6666 synchronized (mWindowMap) {
6667 return mHardKeyboardAvailable;
6668 }
6669 }
6670
6671 public boolean isHardKeyboardEnabled() {
6672 synchronized (mWindowMap) {
6673 return mHardKeyboardEnabled;
6674 }
6675 }
6676
6677 public void setHardKeyboardEnabled(boolean enabled) {
6678 synchronized (mWindowMap) {
6679 if (mHardKeyboardEnabled != enabled) {
6680 mHardKeyboardEnabled = enabled;
6681 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
6682 }
6683 }
6684 }
6685
6686 public void setOnHardKeyboardStatusChangeListener(
6687 OnHardKeyboardStatusChangeListener listener) {
6688 synchronized (mWindowMap) {
6689 mHardKeyboardStatusChangeListener = listener;
6690 }
6691 }
6692
6693 void notifyHardKeyboardStatusChange() {
6694 final boolean available, enabled;
6695 final OnHardKeyboardStatusChangeListener listener;
6696 synchronized (mWindowMap) {
6697 listener = mHardKeyboardStatusChangeListener;
6698 available = mHardKeyboardAvailable;
6699 enabled = mHardKeyboardEnabled;
6700 }
6701 if (listener != null) {
6702 listener.onHardKeyboardStatusChange(available, enabled);
6703 }
6704 }
6705
Christopher Tatea53146c2010-09-07 11:57:52 -07006706 // -------------------------------------------------------------
6707 // Drag and drop
6708 // -------------------------------------------------------------
6709
6710 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006711 int flags, int width, int height, Surface outSurface) {
Christopher Tatea53146c2010-09-07 11:57:52 -07006712 if (DEBUG_DRAG) {
6713 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006714 + " flags=" + Integer.toHexString(flags) + " win=" + window
Christopher Tatea53146c2010-09-07 11:57:52 -07006715 + " asbinder=" + window.asBinder());
6716 }
6717
6718 final int callerPid = Binder.getCallingPid();
6719 final long origId = Binder.clearCallingIdentity();
6720 IBinder token = null;
6721
6722 try {
6723 synchronized (mWindowMap) {
6724 try {
Christopher Tatea53146c2010-09-07 11:57:52 -07006725 if (mDragState == null) {
Craig Mautner6881a102012-07-27 13:04:51 -07006726 Surface surface = new Surface(session, callerPid, "drag surface",
6727 Display.DEFAULT_DISPLAY,
Christopher Tatea53146c2010-09-07 11:57:52 -07006728 width, height, PixelFormat.TRANSLUCENT, Surface.HIDDEN);
Dianne Hackbornac1471a2011-02-03 13:46:06 -08006729 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DRAG "
6730 + surface + ": CREATE");
Christopher Tatea53146c2010-09-07 11:57:52 -07006731 outSurface.copyFrom(surface);
Chris Tate7b362e42010-11-04 16:02:52 -07006732 final IBinder winBinder = window.asBinder();
Christopher Tatea53146c2010-09-07 11:57:52 -07006733 token = new Binder();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006734 mDragState = new DragState(this, token, surface, /*flags*/ 0, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07006735 token = mDragState.mToken = new Binder();
6736
6737 // 5 second timeout for this window to actually begin the drag
Chris Tate7b362e42010-11-04 16:02:52 -07006738 mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
6739 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07006740 mH.sendMessageDelayed(msg, 5000);
6741 } else {
6742 Slog.w(TAG, "Drag already in progress");
6743 }
6744 } catch (Surface.OutOfResourcesException e) {
6745 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
6746 if (mDragState != null) {
6747 mDragState.reset();
6748 mDragState = null;
6749 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006750 }
6751 }
6752 } finally {
6753 Binder.restoreCallingIdentity(origId);
6754 }
6755
6756 return token;
6757 }
6758
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006759 // -------------------------------------------------------------
6760 // Input Events and Focus Management
6761 // -------------------------------------------------------------
Jeff Brown46b9ac02010-04-22 18:58:52 -07006762
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006763 final InputMonitor mInputMonitor = new InputMonitor(this);
Jeff Brown08a746a2012-06-24 12:14:49 -07006764 private boolean mEventDispatchingEnabled;
6765
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006766 public void pauseKeyDispatching(IBinder _token) {
6767 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6768 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006769 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006770 }
6771
6772 synchronized (mWindowMap) {
6773 WindowToken token = mTokenMap.get(_token);
6774 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006775 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006776 }
6777 }
6778 }
6779
6780 public void resumeKeyDispatching(IBinder _token) {
6781 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6782 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006783 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006784 }
6785
6786 synchronized (mWindowMap) {
6787 WindowToken token = mTokenMap.get(_token);
6788 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006789 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006790 }
6791 }
6792 }
6793
6794 public void setEventDispatching(boolean enabled) {
6795 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner3d7b7d52012-05-24 11:28:26 -07006796 "setEventDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006797 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006798 }
6799
6800 synchronized (mWindowMap) {
Jeff Brown08a746a2012-06-24 12:14:49 -07006801 mEventDispatchingEnabled = enabled;
6802 if (mDisplayEnabled) {
6803 mInputMonitor.setEventDispatchingLw(enabled);
6804 }
Craig Mautner3d7b7d52012-05-24 11:28:26 -07006805 sendScreenStatusToClientsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006806 }
6807 }
Romain Guy06882f82009-06-10 13:36:04 -07006808
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07006809 public IBinder getFocusedWindowToken() {
6810 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
6811 "getFocusedWindowToken()")) {
6812 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
6813 }
Svetoslav Ganove15ccb92012-05-16 15:48:55 -07006814 synchronized (mWindowMap) {
6815 WindowState windowState = getFocusedWindowLocked();
6816 if (windowState != null) {
6817 return windowState.mClient.asBinder();
6818 }
6819 return null;
6820 }
6821 }
6822
Svetoslav Ganov86783472012-06-06 21:12:20 -07006823 public boolean getWindowFrame(IBinder token, Rect outBounds) {
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07006824 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
6825 "getWindowFrame()")) {
6826 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
6827 }
Svetoslav Ganov86783472012-06-06 21:12:20 -07006828 synchronized (mWindowMap) {
6829 WindowState windowState = mWindowMap.get(token);
6830 if (windowState != null) {
6831 outBounds.set(windowState.getFrameLw());
6832 return true;
6833 }
6834 }
6835 return false;
6836 }
6837
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006838 private WindowState getFocusedWindow() {
6839 synchronized (mWindowMap) {
6840 return getFocusedWindowLocked();
6841 }
6842 }
6843
6844 private WindowState getFocusedWindowLocked() {
6845 return mCurrentFocus;
6846 }
Romain Guy06882f82009-06-10 13:36:04 -07006847
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006848 public boolean detectSafeMode() {
Jeff Brownb09abc12011-01-13 21:08:27 -08006849 if (!mInputMonitor.waitForInputDevicesReady(
6850 INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
6851 Slog.w(TAG, "Devices still not ready after waiting "
Jeff Brownac143512012-04-05 18:57:33 -07006852 + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
6853 + " milliseconds before attempting to detect safe mode.");
Jeff Brownb09abc12011-01-13 21:08:27 -08006854 }
6855
Jeff Brownac143512012-04-05 18:57:33 -07006856 int menuState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
6857 KeyEvent.KEYCODE_MENU);
6858 int sState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, KeyEvent.KEYCODE_S);
6859 int dpadState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD,
6860 KeyEvent.KEYCODE_DPAD_CENTER);
6861 int trackballState = mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL,
Jeff Brownc458ce92012-04-30 14:58:40 -07006862 InputManagerService.BTN_MOUSE);
Jeff Brownac143512012-04-05 18:57:33 -07006863 int volumeDownState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
6864 KeyEvent.KEYCODE_VOLUME_DOWN);
6865 mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
6866 || volumeDownState > 0;
Dianne Hackborn19caadc2012-04-20 17:49:10 -07006867 try {
6868 if (SystemProperties.getInt(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, 0) != 0) {
6869 mSafeMode = true;
6870 SystemProperties.set(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, "");
6871 }
6872 } catch (IllegalArgumentException e) {
6873 }
Jeff Brownac143512012-04-05 18:57:33 -07006874 if (mSafeMode) {
6875 Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
6876 + " dpad=" + dpadState + " trackball=" + trackballState + ")");
6877 } else {
6878 Log.i(TAG, "SAFE MODE not enabled");
6879 }
6880 mPolicy.setSafeMode(mSafeMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006881 return mSafeMode;
6882 }
Romain Guy06882f82009-06-10 13:36:04 -07006883
Dianne Hackborn661cd522011-08-22 00:26:20 -07006884 public void displayReady() {
Craig Mautner59c00972012-07-30 12:10:24 -07006885 displayReady(Display.DEFAULT_DISPLAY);
Craig Mautner4f67ba62012-08-02 11:23:00 -07006886
6887 synchronized(mWindowMap) {
6888 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
6889 mDisplay = wm.getDefaultDisplay();
6890 mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
6891 PackageManager.FEATURE_TOUCHSCREEN);
6892
6893 final DisplayInfo displayInfo = getDefaultDisplayInfo();
6894 mAnimator.setDisplayDimensions(displayInfo.logicalWidth, displayInfo.logicalHeight,
6895 displayInfo.appWidth, displayInfo.appHeight);
6896
6897 DisplayDeviceInfo info = new DisplayDeviceInfo();
6898 mDisplayManager.getDefaultExternalDisplayDeviceInfo(info);
6899
6900 final DisplayContent displayContent = getDefaultDisplayContent();
6901 mInputManager.setDisplaySize(Display.DEFAULT_DISPLAY,
6902 displayContent.mInitialDisplayWidth, displayContent.mInitialDisplayHeight,
6903 info.width, info.height);
6904 mInputManager.setDisplayOrientation(Display.DEFAULT_DISPLAY,
6905 mDisplay.getRotation(), Surface.ROTATION_0);
Dianne Hackborndde331c2012-08-03 14:01:57 -07006906 mPolicy.setInitialDisplaySize(mDisplay, displayContent.mInitialDisplayWidth,
6907 displayContent.mInitialDisplayHeight, displayContent.mInitialDisplayDensity);
Craig Mautner4f67ba62012-08-02 11:23:00 -07006908 }
Craig Mautner59c00972012-07-30 12:10:24 -07006909 }
6910
6911 public void displayReady(int displayId) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07006912 synchronized(mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -07006913 final DisplayContent displayContent = getDisplayContent(displayId);
Craig Mautner4f67ba62012-08-02 11:23:00 -07006914 final DisplayInfo displayInfo;
Craig Mautner59c00972012-07-30 12:10:24 -07006915 synchronized(displayContent.mDisplaySizeLock) {
Jeff Brownfa25bf52012-07-23 19:26:30 -07006916 // Bootstrap the default logical display from the display manager.
Craig Mautner4f67ba62012-08-02 11:23:00 -07006917 displayInfo = displayContent.getDisplayInfo();
Craig Mautner59c00972012-07-30 12:10:24 -07006918 mDisplayManager.getDisplayInfo(displayId, displayInfo);
6919 displayContent.mInitialDisplayWidth = displayInfo.logicalWidth;
6920 displayContent.mInitialDisplayHeight = displayInfo.logicalHeight;
Dianne Hackborndde331c2012-08-03 14:01:57 -07006921 displayContent.mInitialDisplayDensity = displayInfo.logicalDensityDpi;
Craig Mautner59c00972012-07-30 12:10:24 -07006922 displayContent.mBaseDisplayWidth = displayContent.mInitialDisplayWidth;
6923 displayContent.mBaseDisplayHeight = displayContent.mInitialDisplayHeight;
Dianne Hackborndde331c2012-08-03 14:01:57 -07006924 displayContent.mBaseDisplayDensity = displayContent.mInitialDisplayDensity;
Dianne Hackborn7916ac62011-05-16 20:45:48 -07006925 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07006926 }
6927
6928 try {
6929 mActivityManager.updateConfiguration(null);
6930 } catch (RemoteException e) {
6931 }
Craig Mautner4f67ba62012-08-02 11:23:00 -07006932
Joe Onorato571ae902011-05-24 13:48:43 -07006933 synchronized (mWindowMap) {
Dianne Hackborndde331c2012-08-03 14:01:57 -07006934 readForcedDisplaySizeAndDensityLocked(getDisplayContent(displayId));
Joe Onorato571ae902011-05-24 13:48:43 -07006935 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07006936 }
6937
Dianne Hackborn661cd522011-08-22 00:26:20 -07006938 public void systemReady() {
6939 mPolicy.systemReady();
6940 }
6941
Craig Mautner59c00972012-07-30 12:10:24 -07006942 // TODO(multidisplay): Call isScreenOn for each display.
Craig Mautner3d7b7d52012-05-24 11:28:26 -07006943 private void sendScreenStatusToClientsLocked() {
Craig Mautner59c00972012-07-30 12:10:24 -07006944 final boolean on = mPowerManager.isScreenOn();
6945 final AllWindowsIterator iterator = new AllWindowsIterator();
6946 while (iterator.hasNext()) {
Romain Guy7e4e5612012-03-05 14:37:29 -08006947 try {
Craig Mautner59c00972012-07-30 12:10:24 -07006948 iterator.next().mClient.dispatchScreenState(on);
Romain Guy7e4e5612012-03-05 14:37:29 -08006949 } catch (RemoteException e) {
6950 // Ignored
6951 }
6952 }
6953 }
6954
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006955 // -------------------------------------------------------------
6956 // Async Handler
6957 // -------------------------------------------------------------
6958
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006959 final class H extends Handler {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006960 public static final int REPORT_FOCUS_CHANGE = 2;
6961 public static final int REPORT_LOSING_FOCUS = 3;
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08006962 public static final int DO_TRAVERSAL = 4;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006963 public static final int ADD_STARTING = 5;
6964 public static final int REMOVE_STARTING = 6;
6965 public static final int FINISHED_STARTING = 7;
6966 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07006967 public static final int REPORT_APPLICATION_TOKEN_DRAWN = 9;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006968 public static final int WINDOW_FREEZE_TIMEOUT = 11;
6969 public static final int HOLD_SCREEN_CHANGED = 12;
6970 public static final int APP_TRANSITION_TIMEOUT = 13;
6971 public static final int PERSIST_ANIMATION_SCALE = 14;
6972 public static final int FORCE_GC = 15;
6973 public static final int ENABLE_SCREEN = 16;
6974 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006975 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07006976 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07006977 public static final int DRAG_START_TIMEOUT = 20;
Chris Tated4533f12010-10-19 15:15:08 -07006978 public static final int DRAG_END_TIMEOUT = 21;
Jeff Brown2992ea72011-01-28 22:04:14 -08006979 public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006980 public static final int BOOT_TIMEOUT = 23;
Dianne Hackborn38e29a62011-09-18 14:43:08 -07006981 public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
Craig Mautner01cd0e72012-06-18 10:19:11 -07006982 public static final int UPDATE_ANIM_PARAMETERS = 25;
Craig Mautner0447a812012-05-22 16:01:31 -07006983 public static final int SHOW_STRICT_MODE_VIOLATION = 26;
Dianne Hackborn84375872012-06-01 19:03:50 -07006984 public static final int DO_ANIMATION_CALLBACK = 27;
Romain Guy06882f82009-06-10 13:36:04 -07006985
Craig Mautner48ba1e72012-04-02 13:18:16 -07006986 public static final int ANIMATOR_WHAT_OFFSET = 100000;
6987 public static final int SET_TRANSPARENT_REGION = ANIMATOR_WHAT_OFFSET + 1;
Craig Mautner12670b52012-07-03 19:15:35 -07006988 public static final int CLEAR_PENDING_ACTIONS = ANIMATOR_WHAT_OFFSET + 2;
Craig Mautner48ba1e72012-04-02 13:18:16 -07006989
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006990 private Session mLastReportedHold;
Romain Guy06882f82009-06-10 13:36:04 -07006991
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006992 public H() {
6993 }
Romain Guy06882f82009-06-10 13:36:04 -07006994
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006995 @Override
6996 public void handleMessage(Message msg) {
Craig Mautner7d8df392012-04-06 15:26:23 -07006997 if (DEBUG_WINDOW_TRACE) {
6998 Slog.v(TAG, "handleMessage: entry what=" + msg.what);
6999 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007000 switch (msg.what) {
7001 case REPORT_FOCUS_CHANGE: {
7002 WindowState lastFocus;
7003 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07007004
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007005 synchronized(mWindowMap) {
7006 lastFocus = mLastFocus;
7007 newFocus = mCurrentFocus;
7008 if (lastFocus == newFocus) {
7009 // Focus is not changing, so nothing to do.
7010 return;
7011 }
7012 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007013 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007014 // + " to " + newFocus);
7015 if (newFocus != null && lastFocus != null
7016 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007017 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007018 mLosingFocus.add(lastFocus);
7019 lastFocus = null;
7020 }
7021 }
7022
7023 if (lastFocus != newFocus) {
7024 //System.out.println("Changing focus from " + lastFocus
7025 // + " to " + newFocus);
7026 if (newFocus != null) {
7027 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007028 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007029 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
7030 } catch (RemoteException e) {
7031 // Ignore if process has died.
7032 }
Konstantin Lopyrev5e7833a2010-08-09 17:01:11 -07007033 notifyFocusChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007034 }
7035
7036 if (lastFocus != null) {
7037 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007038 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007039 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
7040 } catch (RemoteException e) {
7041 // Ignore if process has died.
7042 }
7043 }
7044 }
7045 } break;
7046
7047 case REPORT_LOSING_FOCUS: {
7048 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07007049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007050 synchronized(mWindowMap) {
7051 losers = mLosingFocus;
7052 mLosingFocus = new ArrayList<WindowState>();
7053 }
7054
7055 final int N = losers.size();
7056 for (int i=0; i<N; i++) {
7057 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007058 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007059 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
7060 } catch (RemoteException e) {
7061 // Ignore if process has died.
7062 }
7063 }
7064 } break;
7065
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08007066 case DO_TRAVERSAL: {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007067 synchronized(mWindowMap) {
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08007068 mTraversalScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007069 performLayoutAndPlaceSurfacesLocked();
7070 }
7071 } break;
7072
7073 case ADD_STARTING: {
7074 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7075 final StartingData sd = wtoken.startingData;
7076
7077 if (sd == null) {
7078 // Animation has been canceled... do nothing.
7079 return;
7080 }
Romain Guy06882f82009-06-10 13:36:04 -07007081
Joe Onorato8a9b2202010-02-26 18:56:32 -08007082 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007083 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07007084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007085 View view = null;
7086 try {
7087 view = mPolicy.addStartingWindow(
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07007088 wtoken.token, sd.pkg, sd.theme, sd.compatInfo,
7089 sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007090 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007091 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007092 }
7093
7094 if (view != null) {
7095 boolean abort = false;
7096
7097 synchronized(mWindowMap) {
7098 if (wtoken.removed || wtoken.startingData == null) {
7099 // If the window was successfully added, then
7100 // we need to remove it.
7101 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007102 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007103 "Aborted starting " + wtoken
7104 + ": removed=" + wtoken.removed
7105 + " startingData=" + wtoken.startingData);
7106 wtoken.startingWindow = null;
7107 wtoken.startingData = null;
7108 abort = true;
7109 }
7110 } else {
7111 wtoken.startingView = view;
7112 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007113 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007114 "Added starting " + wtoken
7115 + ": startingWindow="
7116 + wtoken.startingWindow + " startingView="
7117 + wtoken.startingView);
7118 }
7119
7120 if (abort) {
7121 try {
7122 mPolicy.removeStartingWindow(wtoken.token, view);
7123 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007124 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007125 }
7126 }
7127 }
7128 } break;
7129
7130 case REMOVE_STARTING: {
7131 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7132 IBinder token = null;
7133 View view = null;
7134 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007135 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007136 + wtoken + ": startingWindow="
7137 + wtoken.startingWindow + " startingView="
7138 + wtoken.startingView);
7139 if (wtoken.startingWindow != null) {
7140 view = wtoken.startingView;
7141 token = wtoken.token;
7142 wtoken.startingData = null;
7143 wtoken.startingView = null;
7144 wtoken.startingWindow = null;
Craig Mautner38b24782012-07-02 16:21:28 -07007145 wtoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007146 }
7147 }
7148 if (view != null) {
7149 try {
7150 mPolicy.removeStartingWindow(token, view);
7151 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007152 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007153 }
7154 }
7155 } break;
7156
7157 case FINISHED_STARTING: {
7158 IBinder token = null;
7159 View view = null;
7160 while (true) {
7161 synchronized (mWindowMap) {
7162 final int N = mFinishedStarting.size();
7163 if (N <= 0) {
7164 break;
7165 }
7166 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
7167
Joe Onorato8a9b2202010-02-26 18:56:32 -08007168 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007169 "Finished starting " + wtoken
7170 + ": startingWindow=" + wtoken.startingWindow
7171 + " startingView=" + wtoken.startingView);
7172
7173 if (wtoken.startingWindow == null) {
7174 continue;
7175 }
7176
7177 view = wtoken.startingView;
7178 token = wtoken.token;
7179 wtoken.startingData = null;
7180 wtoken.startingView = null;
7181 wtoken.startingWindow = null;
Craig Mautner38b24782012-07-02 16:21:28 -07007182 wtoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007183 }
7184
7185 try {
7186 mPolicy.removeStartingWindow(token, view);
7187 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007188 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007189 }
7190 }
7191 } break;
7192
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07007193 case REPORT_APPLICATION_TOKEN_DRAWN: {
7194 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7195
7196 try {
7197 if (DEBUG_VISIBILITY) Slog.v(
7198 TAG, "Reporting drawn in " + wtoken);
7199 wtoken.appToken.windowsDrawn();
7200 } catch (RemoteException ex) {
7201 }
7202 } break;
7203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007204 case REPORT_APPLICATION_TOKEN_WINDOWS: {
7205 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7206
7207 boolean nowVisible = msg.arg1 != 0;
7208 boolean nowGone = msg.arg2 != 0;
7209
7210 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007211 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007212 TAG, "Reporting visible in " + wtoken
7213 + " visible=" + nowVisible
7214 + " gone=" + nowGone);
7215 if (nowVisible) {
7216 wtoken.appToken.windowsVisible();
7217 } else {
7218 wtoken.appToken.windowsGone();
7219 }
7220 } catch (RemoteException ex) {
7221 }
7222 } break;
Romain Guy06882f82009-06-10 13:36:04 -07007223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007224 case WINDOW_FREEZE_TIMEOUT: {
Craig Mautner59c00972012-07-30 12:10:24 -07007225 // TODO(multidisplay): Can non-default displays rotate?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007226 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007227 Slog.w(TAG, "Window freeze timeout expired.");
Craig Mautner59c00972012-07-30 12:10:24 -07007228 final WindowList windows = getDefaultWindowList();
7229 int i = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007230 while (i > 0) {
7231 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07007232 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007233 if (w.mOrientationChanging) {
7234 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007235 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007236 }
7237 }
7238 performLayoutAndPlaceSurfacesLocked();
7239 }
7240 break;
7241 }
Romain Guy06882f82009-06-10 13:36:04 -07007242
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007243 case HOLD_SCREEN_CHANGED: {
7244 Session oldHold;
7245 Session newHold;
7246 synchronized (mWindowMap) {
7247 oldHold = mLastReportedHold;
7248 newHold = (Session)msg.obj;
7249 mLastReportedHold = newHold;
7250 }
Romain Guy06882f82009-06-10 13:36:04 -07007251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007252 if (oldHold != newHold) {
7253 try {
7254 if (oldHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007255 mBatteryStats.noteStopWakelock(oldHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007256 "window",
7257 BatteryStats.WAKE_TYPE_WINDOW);
7258 }
7259 if (newHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007260 mBatteryStats.noteStartWakelock(newHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007261 "window",
7262 BatteryStats.WAKE_TYPE_WINDOW);
7263 }
7264 } catch (RemoteException e) {
7265 }
7266 }
7267 break;
7268 }
Romain Guy06882f82009-06-10 13:36:04 -07007269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007270 case APP_TRANSITION_TIMEOUT: {
7271 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07007272 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007273 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007274 "*** APP TRANSITION TIMEOUT");
7275 mAppTransitionReady = true;
7276 mAppTransitionTimeout = true;
Craig Mautneref25d7a2012-05-15 23:01:47 -07007277 mAnimatingAppTokens.clear();
7278 mAnimatingAppTokens.addAll(mAppTokens);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007279 performLayoutAndPlaceSurfacesLocked();
7280 }
7281 }
7282 break;
7283 }
Romain Guy06882f82009-06-10 13:36:04 -07007284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007285 case PERSIST_ANIMATION_SCALE: {
7286 Settings.System.putFloat(mContext.getContentResolver(),
7287 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
7288 Settings.System.putFloat(mContext.getContentResolver(),
7289 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Chet Haasec38fa1f2012-02-01 16:37:46 -08007290 Settings.System.putFloat(mContext.getContentResolver(),
7291 Settings.System.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007292 break;
7293 }
Romain Guy06882f82009-06-10 13:36:04 -07007294
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007295 case FORCE_GC: {
Craig Mautner1caa3992012-06-22 09:46:48 -07007296 synchronized (mWindowMap) {
7297 synchronized (mAnimator) {
7298 // Since we're holding both mWindowMap and mAnimator we don't need to
7299 // hold mAnimator.mLayoutToAnim.
Craig Mautner711f90a2012-07-03 18:43:52 -07007300 if (mAnimator.mAnimating || mLayoutToAnim.mAnimationScheduled) {
Craig Mautner1caa3992012-06-22 09:46:48 -07007301 // If we are animating, don't do the gc now but
7302 // delay a bit so we don't interrupt the animation.
7303 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
7304 2000);
7305 return;
7306 }
7307 // If we are currently rotating the display, it will
7308 // schedule a new message when done.
7309 if (mDisplayFrozen) {
7310 return;
7311 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007312 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007313 }
7314 Runtime.getRuntime().gc();
7315 break;
7316 }
Romain Guy06882f82009-06-10 13:36:04 -07007317
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007318 case ENABLE_SCREEN: {
7319 performEnableScreen();
7320 break;
7321 }
Romain Guy06882f82009-06-10 13:36:04 -07007322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007323 case APP_FREEZE_TIMEOUT: {
7324 synchronized (mWindowMap) {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07007325 synchronized (mAnimator) {
7326 Slog.w(TAG, "App freeze timeout expired.");
7327 int i = mAppTokens.size();
7328 while (i > 0) {
7329 i--;
7330 AppWindowToken tok = mAppTokens.get(i);
Craig Mautner59431632012-04-04 11:56:44 -07007331 if (tok.mAppAnimator.freezingScreen) {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07007332 Slog.w(TAG, "Force clearing freeze: " + tok);
7333 unsetAppFreezingScreenLocked(tok, true, true);
7334 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007335 }
7336 }
7337 }
7338 break;
7339 }
Romain Guy06882f82009-06-10 13:36:04 -07007340
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007341 case SEND_NEW_CONFIGURATION: {
7342 removeMessages(SEND_NEW_CONFIGURATION);
7343 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07007344 break;
7345 }
Romain Guy06882f82009-06-10 13:36:04 -07007346
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07007347 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007348 if (mWindowsChanged) {
7349 synchronized (mWindowMap) {
7350 mWindowsChanged = false;
7351 }
7352 notifyWindowsChanged();
7353 }
7354 break;
7355 }
7356
Christopher Tatea53146c2010-09-07 11:57:52 -07007357 case DRAG_START_TIMEOUT: {
7358 IBinder win = (IBinder)msg.obj;
7359 if (DEBUG_DRAG) {
7360 Slog.w(TAG, "Timeout starting drag by win " + win);
7361 }
7362 synchronized (mWindowMap) {
7363 // !!! TODO: ANR the app that has failed to start the drag in time
7364 if (mDragState != null) {
Chris Tated4533f12010-10-19 15:15:08 -07007365 mDragState.unregister();
Jeff Brown2e44b072011-01-24 15:21:56 -08007366 mInputMonitor.updateInputWindowsLw(true /*force*/);
Christopher Tatea53146c2010-09-07 11:57:52 -07007367 mDragState.reset();
7368 mDragState = null;
7369 }
7370 }
Chris Tated4533f12010-10-19 15:15:08 -07007371 break;
Christopher Tatea53146c2010-09-07 11:57:52 -07007372 }
7373
Chris Tated4533f12010-10-19 15:15:08 -07007374 case DRAG_END_TIMEOUT: {
7375 IBinder win = (IBinder)msg.obj;
7376 if (DEBUG_DRAG) {
7377 Slog.w(TAG, "Timeout ending drag to win " + win);
7378 }
7379 synchronized (mWindowMap) {
7380 // !!! TODO: ANR the drag-receiving app
Christopher Tated9be36c2011-08-16 16:09:33 -07007381 if (mDragState != null) {
7382 mDragState.mDragResult = false;
7383 mDragState.endDragLw();
7384 }
Chris Tated4533f12010-10-19 15:15:08 -07007385 }
7386 break;
7387 }
Jeff Brown2992ea72011-01-28 22:04:14 -08007388
7389 case REPORT_HARD_KEYBOARD_STATUS_CHANGE: {
7390 notifyHardKeyboardStatusChange();
7391 break;
7392 }
Dianne Hackborn38e29a62011-09-18 14:43:08 -07007393
7394 case BOOT_TIMEOUT: {
7395 performBootTimeout();
7396 break;
7397 }
7398
7399 case WAITING_FOR_DRAWN_TIMEOUT: {
7400 Pair<WindowState, IRemoteCallback> pair;
7401 synchronized (mWindowMap) {
7402 pair = (Pair<WindowState, IRemoteCallback>)msg.obj;
7403 Slog.w(TAG, "Timeout waiting for drawn: " + pair.first);
7404 if (!mWaitingForDrawn.remove(pair)) {
7405 return;
7406 }
7407 }
7408 try {
7409 pair.second.sendResult(null);
7410 } catch (RemoteException e) {
7411 }
7412 break;
7413 }
Craig Mautnera608b882012-03-30 13:03:49 -07007414
Craig Mautner01cd0e72012-06-18 10:19:11 -07007415 case UPDATE_ANIM_PARAMETERS: {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07007416 // Used to send multiple changes from the animation side to the layout side.
Craig Mautnera608b882012-03-30 13:03:49 -07007417 synchronized (mWindowMap) {
Craig Mautner322e4032012-07-13 13:35:20 -07007418 if (copyAnimToLayoutParamsLocked()) {
7419 mH.sendEmptyMessage(CLEAR_PENDING_ACTIONS);
7420 performLayoutAndPlaceSurfacesLocked();
Craig Mautner73850cb2012-04-10 12:56:27 -07007421 }
Craig Mautnera608b882012-03-30 13:03:49 -07007422 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07007423 break;
7424 }
7425
Craig Mautner0447a812012-05-22 16:01:31 -07007426 case SHOW_STRICT_MODE_VIOLATION: {
7427 showStrictModeViolation(msg.arg1);
7428 break;
7429 }
7430
Craig Mautner48ba1e72012-04-02 13:18:16 -07007431 // Animation messages. Move to Window{State}Animator
7432 case SET_TRANSPARENT_REGION: {
Craig Mautnerbec53f72012-04-05 11:49:05 -07007433 Pair<WindowStateAnimator, Region> pair =
Craig Mautner48ba1e72012-04-02 13:18:16 -07007434 (Pair<WindowStateAnimator, Region>) msg.obj;
Craig Mautnerbec53f72012-04-05 11:49:05 -07007435 final WindowStateAnimator winAnimator = pair.first;
7436 winAnimator.setTransparentRegionHint(pair.second);
Craig Mautner48ba1e72012-04-02 13:18:16 -07007437 break;
7438 }
7439
Craig Mautner4d7349b2012-04-20 14:52:47 -07007440 case CLEAR_PENDING_ACTIONS: {
7441 mAnimator.clearPendingActions();
7442 break;
7443 }
Dianne Hackborn84375872012-06-01 19:03:50 -07007444
7445 case DO_ANIMATION_CALLBACK: {
7446 try {
7447 ((IRemoteCallback)msg.obj).sendResult(null);
7448 } catch (RemoteException e) {
7449 }
7450 break;
7451 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007452 }
Craig Mautner7d8df392012-04-06 15:26:23 -07007453 if (DEBUG_WINDOW_TRACE) {
7454 Slog.v(TAG, "handleMessage: exit");
7455 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007456 }
7457 }
7458
7459 // -------------------------------------------------------------
7460 // IWindowManager API
7461 // -------------------------------------------------------------
7462
Craig Mautner7d8df392012-04-06 15:26:23 -07007463 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007464 public IWindowSession openSession(IInputMethodClient client,
7465 IInputContext inputContext) {
7466 if (client == null) throw new IllegalArgumentException("null client");
7467 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08007468 Session session = new Session(this, client, inputContext);
Jeff Brown46b9ac02010-04-22 18:58:52 -07007469 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007470 }
7471
Craig Mautner7d8df392012-04-06 15:26:23 -07007472 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007473 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
7474 synchronized (mWindowMap) {
7475 // The focus for the client is the window immediately below
7476 // where we would place the input method window.
7477 int idx = findDesiredInputMethodWindowIndexLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007478 if (idx > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07007479 // TODO(multidisplay): IMEs are only supported on the default display.
7480 WindowState imFocus = getDefaultWindowList().get(idx-1);
Dianne Hackbornac920872012-05-22 11:49:49 -07007481 if (DEBUG_INPUT_METHOD) {
7482 Slog.i(TAG, "Desired input method target: " + imFocus);
Craig Mautner59c00972012-07-30 12:10:24 -07007483 Slog.i(TAG, "Current focus: " + mCurrentFocus);
7484 Slog.i(TAG, "Last focus: " + mLastFocus);
Dianne Hackbornac920872012-05-22 11:49:49 -07007485 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007486 if (imFocus != null) {
Dianne Hackborne75d8722011-01-27 19:37:40 -08007487 // This may be a starting window, in which case we still want
7488 // to count it as okay.
7489 if (imFocus.mAttrs.type == LayoutParams.TYPE_APPLICATION_STARTING
7490 && imFocus.mAppToken != null) {
7491 // The client has definitely started, so it really should
7492 // have a window in this app token. Let's look for it.
7493 for (int i=0; i<imFocus.mAppToken.windows.size(); i++) {
7494 WindowState w = imFocus.mAppToken.windows.get(i);
7495 if (w != imFocus) {
Dianne Hackbornac920872012-05-22 11:49:49 -07007496 Log.i(TAG, "Switching to real app window: " + w);
Dianne Hackborne75d8722011-01-27 19:37:40 -08007497 imFocus = w;
7498 break;
7499 }
7500 }
7501 }
Dianne Hackbornac920872012-05-22 11:49:49 -07007502 if (DEBUG_INPUT_METHOD) {
7503 Slog.i(TAG, "IM target client: " + imFocus.mSession.mClient);
7504 if (imFocus.mSession.mClient != null) {
7505 Slog.i(TAG, "IM target client binder: "
7506 + imFocus.mSession.mClient.asBinder());
7507 Slog.i(TAG, "Requesting client binder: " + client.asBinder());
7508 }
7509 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007510 if (imFocus.mSession.mClient != null &&
7511 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
7512 return true;
7513 }
7514 }
7515 }
Craig Mautner59c00972012-07-30 12:10:24 -07007516
7517 // Okay, how about this... what is the current focus?
7518 // It seems in some cases we may not have moved the IM
7519 // target window, such as when it was in a pop-up window,
7520 // so let's also look at the current focus. (An example:
7521 // go to Gmail, start searching so the keyboard goes up,
7522 // press home. Sometimes the IME won't go down.)
7523 // Would be nice to fix this more correctly, but it's
7524 // way at the end of a release, and this should be good enough.
7525 if (mCurrentFocus != null && mCurrentFocus.mSession.mClient != null
7526 && mCurrentFocus.mSession.mClient.asBinder() == client.asBinder()) {
7527 return true;
7528 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007529 }
7530 return false;
7531 }
Romain Guy06882f82009-06-10 13:36:04 -07007532
Craig Mautner59c00972012-07-30 12:10:24 -07007533 public void getInitialDisplaySize(int displayId, Point size) {
7534 // TODO(cmautner): Access to DisplayContent should be locked on mWindowMap. Doing that
7535 // could lead to deadlock since this is called from ActivityManager.
7536 final DisplayContent displayContent = getDisplayContent(displayId);
7537 synchronized(displayContent.mDisplaySizeLock) {
7538 size.x = displayContent.mInitialDisplayWidth;
7539 size.y = displayContent.mInitialDisplayHeight;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007540 }
7541 }
7542
Craig Mautner59c00972012-07-30 12:10:24 -07007543 public void setForcedDisplaySize(int displayId, int longDimen, int shortDimen) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007544 synchronized(mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -07007545 final DisplayContent displayContent = getDisplayContent(displayId);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007546 int width, height;
Craig Mautner59c00972012-07-30 12:10:24 -07007547 if (displayContent.mInitialDisplayWidth < displayContent.mInitialDisplayHeight) {
7548 width = shortDimen < displayContent.mInitialDisplayWidth
7549 ? shortDimen : displayContent.mInitialDisplayWidth;
7550 height = longDimen < displayContent.mInitialDisplayHeight
7551 ? longDimen : displayContent.mInitialDisplayHeight;
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007552 } else {
Craig Mautner59c00972012-07-30 12:10:24 -07007553 width = longDimen < displayContent.mInitialDisplayWidth
7554 ? longDimen : displayContent.mInitialDisplayWidth;
7555 height = shortDimen < displayContent.mInitialDisplayHeight
7556 ? shortDimen : displayContent.mInitialDisplayHeight;
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007557 }
Craig Mautner59c00972012-07-30 12:10:24 -07007558 setForcedDisplaySizeLocked(displayContent, width, height);
Joe Onorato571ae902011-05-24 13:48:43 -07007559 Settings.Secure.putString(mContext.getContentResolver(),
7560 Settings.Secure.DISPLAY_SIZE_FORCED, width + "," + height);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007561 }
7562 }
7563
Craig Mautner2fb98b12012-03-20 17:24:00 -07007564 private void rebuildBlackFrame() {
7565 if (mBlackFrame != null) {
7566 mBlackFrame.kill();
7567 mBlackFrame = null;
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007568 }
Craig Mautner59c00972012-07-30 12:10:24 -07007569 // TODO(multidisplay): For now rotations are only main screen.
7570 final DisplayContent displayContent = getDefaultDisplayContent();
7571 if (displayContent.mBaseDisplayWidth < displayContent.mInitialDisplayWidth
7572 || displayContent.mBaseDisplayHeight < displayContent.mInitialDisplayHeight) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07007573 int initW, initH, baseW, baseH;
7574 final boolean rotated = (mRotation == Surface.ROTATION_90
7575 || mRotation == Surface.ROTATION_270);
7576 if (rotated) {
Craig Mautner59c00972012-07-30 12:10:24 -07007577 initW = displayContent.mInitialDisplayHeight;
7578 initH = displayContent.mInitialDisplayWidth;
7579 baseW = displayContent.mBaseDisplayHeight;
7580 baseH = displayContent.mBaseDisplayWidth;
Craig Mautner2fb98b12012-03-20 17:24:00 -07007581 } else {
Craig Mautner59c00972012-07-30 12:10:24 -07007582 initW = displayContent.mInitialDisplayWidth;
7583 initH = displayContent.mInitialDisplayHeight;
7584 baseW = displayContent.mBaseDisplayWidth;
7585 baseH = displayContent.mBaseDisplayHeight;
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007586 }
Craig Mautner2fb98b12012-03-20 17:24:00 -07007587 Rect outer = new Rect(0, 0, initW, initH);
7588 Rect inner = new Rect(0, 0, baseW, baseH);
7589 try {
7590 mBlackFrame = new BlackFrame(mFxSession, outer, inner, MASK_LAYER);
7591 } catch (Surface.OutOfResourcesException e) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007592 }
7593 }
7594 }
7595
Dianne Hackborndde331c2012-08-03 14:01:57 -07007596 private void readForcedDisplaySizeAndDensityLocked(final DisplayContent displayContent) {
7597 boolean changed = false;
7598 final String sizeStr = Settings.Secure.getString(mContext.getContentResolver(),
Joe Onorato571ae902011-05-24 13:48:43 -07007599 Settings.Secure.DISPLAY_SIZE_FORCED);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007600 if (sizeStr != null && sizeStr.length() > 0) {
7601 final int pos = sizeStr.indexOf(',');
7602 if (pos > 0 && sizeStr.lastIndexOf(',') == pos) {
7603 int width, height;
7604 try {
7605 width = Integer.parseInt(sizeStr.substring(0, pos));
7606 height = Integer.parseInt(sizeStr.substring(pos+1));
7607 synchronized(displayContent.mDisplaySizeLock) {
7608 if (displayContent.mBaseDisplayWidth != width
7609 || displayContent.mBaseDisplayHeight != height) {
7610 changed = true;
7611 Slog.i(TAG, "FORCED DISPLAY SIZE: " + width + "x" + height);
7612 displayContent.mBaseDisplayWidth = width;
7613 displayContent.mBaseDisplayHeight = height;
7614 }
7615 }
7616 } catch (NumberFormatException ex) {
7617 }
7618 }
Joe Onorato571ae902011-05-24 13:48:43 -07007619 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007620 final String densityStr = Settings.Secure.getString(mContext.getContentResolver(),
7621 Settings.Secure.DISPLAY_DENSITY_FORCED);
7622 if (densityStr != null && densityStr.length() > 0) {
7623 int density;
7624 try {
7625 density = Integer.parseInt(densityStr);
7626 synchronized(displayContent.mDisplaySizeLock) {
7627 if (displayContent.mBaseDisplayDensity != density) {
7628 changed = true;
7629 Slog.i(TAG, "FORCED DISPLAY DENSITY: " + density);
7630 displayContent.mBaseDisplayDensity = density;
7631 }
7632 }
7633 } catch (NumberFormatException ex) {
7634 }
Joe Onorato571ae902011-05-24 13:48:43 -07007635 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007636 if (changed) {
7637 reconfigureDisplayLocked(displayContent);
Joe Onorato571ae902011-05-24 13:48:43 -07007638 }
Joe Onorato571ae902011-05-24 13:48:43 -07007639 }
7640
Craig Mautner59c00972012-07-30 12:10:24 -07007641 private void setForcedDisplaySizeLocked(DisplayContent displayContent, int width, int height) {
Joe Onorato571ae902011-05-24 13:48:43 -07007642 Slog.i(TAG, "Using new display size: " + width + "x" + height);
7643
Craig Mautner59c00972012-07-30 12:10:24 -07007644 synchronized(displayContent.mDisplaySizeLock) {
7645 displayContent.mBaseDisplayWidth = width;
7646 displayContent.mBaseDisplayHeight = height;
Dianne Hackborn1fbee792011-11-30 11:29:58 -08007647 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007648 reconfigureDisplayLocked(displayContent);
7649 }
7650
7651 public void clearForcedDisplaySize(int displayId) {
7652 synchronized(mWindowMap) {
7653 final DisplayContent displayContent = getDisplayContent(displayId);
7654 setForcedDisplaySizeLocked(displayContent, displayContent.mInitialDisplayWidth,
7655 displayContent.mInitialDisplayHeight);
7656 Settings.Secure.putString(mContext.getContentResolver(),
7657 Settings.Secure.DISPLAY_SIZE_FORCED, "");
7658 }
7659 }
7660
7661 public void setForcedDisplayDensity(int displayId, int density) {
7662 synchronized(mWindowMap) {
7663 final DisplayContent displayContent = getDisplayContent(displayId);
7664 setForcedDisplayDensityLocked(displayContent, density);
7665 Settings.Secure.putString(mContext.getContentResolver(),
7666 Settings.Secure.DISPLAY_SIZE_FORCED, Integer.toString(density));
7667 }
7668 }
7669
7670 private void setForcedDisplayDensityLocked(DisplayContent displayContent, int density) {
7671 Slog.i(TAG, "Using new display density: " + density);
7672
7673 synchronized(displayContent.mDisplaySizeLock) {
7674 displayContent.mBaseDisplayDensity = density;
7675 }
7676 reconfigureDisplayLocked(displayContent);
7677 }
7678
7679 public void clearForcedDisplayDensity(int displayId) {
7680 synchronized(mWindowMap) {
7681 final DisplayContent displayContent = getDisplayContent(displayId);
7682 setForcedDisplayDensityLocked(displayContent, displayContent.mInitialDisplayDensity);
7683 Settings.Secure.putString(mContext.getContentResolver(),
7684 Settings.Secure.DISPLAY_DENSITY_FORCED, "");
7685 }
7686 }
7687
7688 private void reconfigureDisplayLocked(DisplayContent displayContent) {
Craig Mautner59c00972012-07-30 12:10:24 -07007689 mPolicy.setInitialDisplaySize(mDisplay, displayContent.mBaseDisplayWidth,
Dianne Hackborndde331c2012-08-03 14:01:57 -07007690 displayContent.mBaseDisplayHeight, displayContent.mBaseDisplayDensity);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007691
7692 mLayoutNeeded = true;
7693
7694 boolean configChanged = updateOrientationFromAppTokensLocked(false);
7695 mTempConfiguration.setToDefaults();
7696 mTempConfiguration.fontScale = mCurConfiguration.fontScale;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08007697 if (computeScreenConfigurationLocked(mTempConfiguration)) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007698 if (mCurConfiguration.diff(mTempConfiguration) != 0) {
7699 configChanged = true;
7700 }
7701 }
7702
7703 if (configChanged) {
7704 mWaitingForConfig = true;
7705 startFreezingDisplayLocked(false);
7706 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
7707 }
7708
Craig Mautner2fb98b12012-03-20 17:24:00 -07007709 rebuildBlackFrame();
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007710
7711 performLayoutAndPlaceSurfacesLocked();
7712 }
7713
Dianne Hackbornf87d1962012-04-04 12:48:24 -07007714 public boolean hasSystemNavBar() {
7715 return mPolicy.hasSystemNavBar();
Dianne Hackborn81e56d52011-05-26 00:55:58 -07007716 }
7717
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007718 // -------------------------------------------------------------
7719 // Internals
7720 // -------------------------------------------------------------
7721
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007722 final WindowState windowForClientLocked(Session session, IWindow client,
7723 boolean throwOnError) {
7724 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007725 }
Romain Guy06882f82009-06-10 13:36:04 -07007726
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007727 final WindowState windowForClientLocked(Session session, IBinder client,
7728 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007729 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007730 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007731 TAG, "Looking up client " + client + ": " + win);
7732 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007733 RuntimeException ex = new IllegalArgumentException(
7734 "Requested window " + client + " does not exist");
7735 if (throwOnError) {
7736 throw ex;
7737 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007738 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007739 return null;
7740 }
7741 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007742 RuntimeException ex = new IllegalArgumentException(
7743 "Requested window " + client + " is in session " +
7744 win.mSession + ", not " + session);
7745 if (throwOnError) {
7746 throw ex;
7747 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007748 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007749 return null;
7750 }
7751
7752 return win;
7753 }
7754
Dianne Hackborna8f60182009-09-01 19:01:50 -07007755 final void rebuildAppWindowListLocked() {
Craig Mautner59c00972012-07-30 12:10:24 -07007756 DisplayContentsIterator iterator = new DisplayContentsIterator();
7757 while (iterator.hasNext()) {
7758 rebuildAppWindowListLocked(iterator.next());
7759 }
7760 }
7761
7762 private void rebuildAppWindowListLocked(final DisplayContent displayContent) {
7763 final WindowList windows = displayContent.getWindowList();
7764 int NW = windows.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07007765 int i;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007766 int lastBelow = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007767 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007768
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007769 if (mRebuildTmp.length < NW) {
7770 mRebuildTmp = new WindowState[NW+10];
7771 }
7772
Dianne Hackborna8f60182009-09-01 19:01:50 -07007773 // First remove all existing app windows.
7774 i=0;
7775 while (i < NW) {
Craig Mautner59c00972012-07-30 12:10:24 -07007776 WindowState w = windows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007777 if (w.mAppToken != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07007778 WindowState win = windows.remove(i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007779 win.mRebuilding = true;
7780 mRebuildTmp[numRemoved] = win;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007781 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007782 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007783 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07007784 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007785 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07007786 continue;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007787 } else if (lastBelow == i-1) {
7788 if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER
7789 || w.mAttrs.type == WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND) {
7790 lastBelow = i;
7791 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07007792 }
7793 i++;
7794 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007795
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007796 // Keep whatever windows were below the app windows still below,
7797 // by skipping them.
7798 lastBelow++;
7799 i = lastBelow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007800
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007801 // First add all of the exiting app tokens... these are no longer
7802 // in the main app list, but still have windows shown. We put them
7803 // in the back because now that the animation is over we no longer
7804 // will care about them.
7805 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07007806 for (int j=0; j<NT; j++) {
Craig Mautner59c00972012-07-30 12:10:24 -07007807 i = reAddAppWindowsLocked(displayContent, i, mExitingAppTokens.get(j));
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007808 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007809
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007810 // And add in the still active app tokens in Z order.
Craig Mautneref25d7a2012-05-15 23:01:47 -07007811 NT = mAnimatingAppTokens.size();
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007812 for (int j=0; j<NT; j++) {
Craig Mautner59c00972012-07-30 12:10:24 -07007813 i = reAddAppWindowsLocked(displayContent, i, mAnimatingAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07007814 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007815
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007816 i -= lastBelow;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007817 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007818 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007819 + " windows but added " + i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007820 for (i=0; i<numRemoved; i++) {
7821 WindowState ws = mRebuildTmp[i];
7822 if (ws.mRebuilding) {
7823 StringWriter sw = new StringWriter();
7824 PrintWriter pw = new PrintWriter(sw);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07007825 ws.dump(pw, "", true);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007826 pw.flush();
7827 Slog.w(TAG, "This window was lost: " + ws);
7828 Slog.w(TAG, sw.toString());
Craig Mautnerf20588f2012-04-11 17:06:21 -07007829 ws.mWinAnimator.destroySurfaceLocked();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007830 }
7831 }
7832 Slog.w(TAG, "Current app token list:");
Craig Mautneref25d7a2012-05-15 23:01:47 -07007833 dumpAnimatingAppTokensLocked();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007834 Slog.w(TAG, "Final window list:");
7835 dumpWindowsLocked();
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007836 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07007837 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007838
Craig Mautner59c00972012-07-30 12:10:24 -07007839 private final void assignLayersLocked(WindowList windows) {
7840 int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007841 int curBaseLayer = 0;
7842 int curLayer = 0;
7843 int i;
Romain Guy06882f82009-06-10 13:36:04 -07007844
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007845 if (DEBUG_LAYERS) {
7846 RuntimeException here = new RuntimeException("here");
7847 here.fillInStackTrace();
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07007848 Slog.v(TAG, "Assigning layers", here);
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007849 }
7850
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007851 for (i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07007852 final WindowState w = windows.get(i);
Craig Mautneracafd192012-05-10 10:41:02 -07007853 final WindowStateAnimator winAnimator = w.mWinAnimator;
7854 boolean layerChanged = false;
7855 int oldLayer = w.mLayer;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007856 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
7857 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007858 curLayer += WINDOW_LAYER_MULTIPLIER;
7859 w.mLayer = curLayer;
7860 } else {
7861 curBaseLayer = curLayer = w.mBaseLayer;
7862 w.mLayer = curLayer;
7863 }
Craig Mautneracafd192012-05-10 10:41:02 -07007864 if (w.mLayer != oldLayer) {
7865 layerChanged = true;
7866 }
7867 oldLayer = winAnimator.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007868 if (w.mTargetAppToken != null) {
Craig Mautneracafd192012-05-10 10:41:02 -07007869 winAnimator.mAnimLayer =
Craig Mautner59431632012-04-04 11:56:44 -07007870 w.mLayer + w.mTargetAppToken.mAppAnimator.animLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007871 } else if (w.mAppToken != null) {
Craig Mautneracafd192012-05-10 10:41:02 -07007872 winAnimator.mAnimLayer =
Craig Mautner59431632012-04-04 11:56:44 -07007873 w.mLayer + w.mAppToken.mAppAnimator.animLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007874 } else {
Craig Mautneracafd192012-05-10 10:41:02 -07007875 winAnimator.mAnimLayer = w.mLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007876 }
7877 if (w.mIsImWindow) {
Craig Mautneracafd192012-05-10 10:41:02 -07007878 winAnimator.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007879 } else if (w.mIsWallpaper) {
Craig Mautneracafd192012-05-10 10:41:02 -07007880 winAnimator.mAnimLayer += mWallpaperAnimLayerAdjustment;
7881 }
7882 if (winAnimator.mAnimLayer != oldLayer) {
7883 layerChanged = true;
7884 }
7885 if (layerChanged && mAnimator.isDimming(winAnimator)) {
7886 // Force an animation pass just to update the mDimAnimator layer.
Craig Mautner711f90a2012-07-03 18:43:52 -07007887 updateLayoutToAnimationLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007888 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007889 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
Craig Mautneracafd192012-05-10 10:41:02 -07007890 + winAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007891 //System.out.println(
7892 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
7893 }
7894 }
7895
7896 private boolean mInLayout = false;
7897 private final void performLayoutAndPlaceSurfacesLocked() {
7898 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07007899 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007900 throw new RuntimeException("Recursive call!");
7901 }
Craig Mautneref25d7a2012-05-15 23:01:47 -07007902 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
7903 + Debug.getCallers(3));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007904 return;
7905 }
7906
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007907 if (mWaitingForConfig) {
7908 // Our configuration has changed (most likely rotation), but we
7909 // don't yet have the complete configuration to report to
7910 // applications. Don't do any window layout until we have it.
7911 return;
7912 }
7913
Dianne Hackbornce2ef762010-09-20 11:39:14 -07007914 if (mDisplay == null) {
7915 // Not yet initialized, nothing to do.
7916 return;
7917 }
7918
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07007919 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08007920 mInLayout = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007921 boolean recoveringMemory = false;
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08007922
7923 try {
7924 if (mForceRemoves != null) {
7925 recoveringMemory = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007926 // Wait a little bit for things to settle down, and off we go.
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08007927 for (int i=0; i<mForceRemoves.size(); i++) {
7928 WindowState ws = mForceRemoves.get(i);
7929 Slog.i(TAG, "Force removing: " + ws);
7930 removeWindowInnerLocked(ws.mSession, ws);
7931 }
7932 mForceRemoves = null;
7933 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
7934 Object tmp = new Object();
7935 synchronized (tmp) {
7936 try {
7937 tmp.wait(250);
7938 } catch (InterruptedException e) {
7939 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007940 }
7941 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08007942 } catch (RuntimeException e) {
Dianne Hackborn89620282011-09-11 12:47:45 -07007943 Log.wtf(TAG, "Unhandled exception while force removing for memory", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007944 }
Craig Mautner59c00972012-07-30 12:10:24 -07007945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007946 try {
Craig Mautner59c00972012-07-30 12:10:24 -07007947 DisplayContentsIterator iterator = new DisplayContentsIterator();
7948 while (iterator.hasNext()) {
7949 final DisplayContent displayContent = iterator.next();
7950 performLayoutAndPlaceSurfacesLockedInner(displayContent, recoveringMemory);
Romain Guy06882f82009-06-10 13:36:04 -07007951
Craig Mautner59c00972012-07-30 12:10:24 -07007952 final int N = mPendingRemove.size();
7953 if (N > 0) {
7954 if (mPendingRemoveTmp.length < N) {
7955 mPendingRemoveTmp = new WindowState[N+10];
7956 }
7957 mPendingRemove.toArray(mPendingRemoveTmp);
7958 mPendingRemove.clear();
7959 for (int i=0; i<N; i++) {
7960 WindowState w = mPendingRemoveTmp[i];
7961 removeWindowInnerLocked(w.mSession, w);
7962 }
7963
7964 assignLayersLocked(displayContent.getWindowList());
7965 mLayoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007966 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007967 }
Craig Mautnerbb1449b2012-03-23 16:11:14 -07007968
Craig Mautner59c00972012-07-30 12:10:24 -07007969 mInLayout = false;
7970
Craig Mautnerbb1449b2012-03-23 16:11:14 -07007971 if (mLayoutNeeded) {
7972 if (++mLayoutRepeatCount < 6) {
7973 requestTraversalLocked();
7974 } else {
7975 Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
7976 mLayoutRepeatCount = 0;
7977 }
7978 } else {
7979 mLayoutRepeatCount = 0;
7980 }
Craig Mautnerbb1449b2012-03-23 16:11:14 -07007981
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007982 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07007983 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
7984 mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007985 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007986 } catch (RuntimeException e) {
7987 mInLayout = false;
Dianne Hackborn89620282011-09-11 12:47:45 -07007988 Log.wtf(TAG, "Unhandled exception while laying out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007989 }
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07007990
7991 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007992 }
7993
Craig Mautner59c00972012-07-30 12:10:24 -07007994 private final void performLayoutLockedInner(final DisplayContent displayContent,
7995 boolean initial, boolean updateInputWindows) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007996 if (!mLayoutNeeded) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08007997 return;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007998 }
Craig Mautner59c00972012-07-30 12:10:24 -07007999 WindowList windows = displayContent.getWindowList();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008000 mLayoutNeeded = false;
Craig Mautner59c00972012-07-30 12:10:24 -07008001
8002 DisplayInfo displayInfo = displayContent.getDisplayInfo();
8003 final int dw = displayInfo.logicalWidth;
8004 final int dh = displayInfo.logicalHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008005
Dianne Hackborndf89e652011-10-06 22:35:11 -07008006 final int NFW = mFakeWindows.size();
8007 for (int i=0; i<NFW; i++) {
8008 mFakeWindows.get(i).layout(dw, dh);
8009 }
8010
Craig Mautner59c00972012-07-30 12:10:24 -07008011 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008012 int i;
8013
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008014 if (DEBUG_LAYOUT) {
8015 Slog.v(TAG, "-------------------------------------");
8016 Slog.v(TAG, "performLayout: needed="
8017 + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
8018 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008019
8020 WindowStateAnimator universeBackground = null;
8021
Dianne Hackborn1f903c32011-09-13 19:18:06 -07008022 mPolicy.beginLayoutLw(dw, dh, mRotation);
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07008023 mSystemDecorLayer = mPolicy.getSystemDecorRectLw(mSystemDecorRect);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008024 mScreenRect.set(0, 0, dw, dh);
Romain Guy06882f82009-06-10 13:36:04 -07008025
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008026 int seq = mLayoutSeq+1;
8027 if (seq < 0) seq = 0;
8028 mLayoutSeq = seq;
8029
8030 // First perform layout of any root windows (not attached
8031 // to another window).
8032 int topAttached = -1;
8033 for (i = N-1; i >= 0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07008034 final WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008035
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008036 // Don't do layout of a window if it is not visible, or
8037 // soon won't be visible, to avoid wasting time and funky
8038 // changes while a window is animating away.
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008039 final boolean gone = win.isGoneForLayoutLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008040
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008041 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008042 Slog.v(TAG, "1ST PASS " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008043 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
8044 + " mLayoutAttached=" + win.mLayoutAttached);
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008045 final AppWindowToken atoken = win.mAppToken;
8046 if (gone) Slog.v(TAG, " GONE: mViewVisibility="
8047 + win.mViewVisibility + " mRelayoutCalled="
8048 + win.mRelayoutCalled + " hidden="
8049 + win.mRootToken.hidden + " hiddenRequested="
8050 + (atoken != null && atoken.hiddenRequested)
8051 + " mAttachedHidden=" + win.mAttachedHidden);
8052 else Slog.v(TAG, " VIS: mViewVisibility="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008053 + win.mViewVisibility + " mRelayoutCalled="
8054 + win.mRelayoutCalled + " hidden="
8055 + win.mRootToken.hidden + " hiddenRequested="
8056 + (atoken != null && atoken.hiddenRequested)
8057 + " mAttachedHidden=" + win.mAttachedHidden);
8058 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008059
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008060 // If this view is GONE, then skip it -- keep the current
8061 // frame, and let the caller know so they can ignore it
8062 // if they want. (We do the normal layout for INVISIBLE
8063 // windows, since that means "perform layout as normal,
8064 // just don't display").
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008065 if (!gone || !win.mHaveFrame || win.mLayoutNeeded
8066 || win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008067 if (!win.mLayoutAttached) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008068 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08008069 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008070 win.mContentChanged = false;
8071 }
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008072 win.mLayoutNeeded = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008073 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008074 mPolicy.layoutWindowLw(win, win.mAttrs, null);
8075 win.mLayoutSeq = seq;
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008076 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008077 + win.mFrame + " mContainingFrame="
8078 + win.mContainingFrame + " mDisplayFrame="
8079 + win.mDisplayFrame);
8080 } else {
8081 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008082 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07008083 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008084 if (win.mViewVisibility == View.VISIBLE
8085 && win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND
8086 && universeBackground == null) {
8087 universeBackground = win.mWinAnimator;
8088 }
8089 }
8090
8091 if (mAnimator.mUniverseBackground != universeBackground) {
8092 mFocusMayChange = true;
8093 mAnimator.mUniverseBackground = universeBackground;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008094 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008095
8096 // Now perform layout of attached windows, which usually
8097 // depend on the position of the window they are attached to.
8098 // XXX does not deal with windows that are attached to windows
8099 // that are themselves attached.
8100 for (i = topAttached; i >= 0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07008101 final WindowState win = windows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008102
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008103 if (win.mLayoutAttached) {
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008104 if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008105 + " mHaveFrame=" + win.mHaveFrame
8106 + " mViewVisibility=" + win.mViewVisibility
8107 + " mRelayoutCalled=" + win.mRelayoutCalled);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008108 // If this view is GONE, then skip it -- keep the current
8109 // frame, and let the caller know so they can ignore it
8110 // if they want. (We do the normal layout for INVISIBLE
8111 // windows, since that means "perform layout as normal,
8112 // just don't display").
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008113 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008114 || !win.mHaveFrame || win.mLayoutNeeded) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008115 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08008116 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008117 win.mContentChanged = false;
8118 }
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008119 win.mLayoutNeeded = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008120 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008121 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
8122 win.mLayoutSeq = seq;
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008123 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008124 + win.mFrame + " mContainingFrame="
8125 + win.mContainingFrame + " mDisplayFrame="
8126 + win.mDisplayFrame);
8127 }
8128 }
8129 }
Jeff Brown349703e2010-06-22 01:27:15 -07008130
8131 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown3a22cd92011-01-21 13:59:04 -08008132 mInputMonitor.setUpdateInputWindowsNeededLw();
8133 if (updateInputWindows) {
Jeff Brown2e44b072011-01-24 15:21:56 -08008134 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08008135 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008136
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008137 mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008138 }
Romain Guy06882f82009-06-10 13:36:04 -07008139
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008140 void makeWindowFreezingScreenIfNeededLocked(WindowState w) {
8141 // If the screen is currently frozen or off, then keep
8142 // it frozen/off until this window draws at its new
8143 // orientation.
Craig Mautner2fb98b12012-03-20 17:24:00 -07008144 if (!okToDisplay()) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008145 if (DEBUG_ORIENTATION) Slog.v(TAG,
8146 "Changing surface while display frozen: " + w);
8147 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07008148 mInnerFields.mOrientationChangeComplete = false;
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008149 if (!mWindowsFreezingScreen) {
8150 mWindowsFreezingScreen = true;
8151 // XXX should probably keep timeout from
8152 // when we first froze the display.
8153 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
8154 mH.sendMessageDelayed(mH.obtainMessage(
8155 H.WINDOW_FREEZE_TIMEOUT), 2000);
8156 }
8157 }
8158 }
8159
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008160 /**
8161 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
Craig Mautner59c00972012-07-30 12:10:24 -07008162 * @param windows TODO(cmautner):
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008163 *
8164 * @return bitmap indicating if another pass through layout must be made.
8165 */
Craig Mautner59c00972012-07-30 12:10:24 -07008166 public int handleAppTransitionReadyLocked(WindowList windows) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008167 int changes = 0;
8168 int i;
8169 int NN = mOpeningApps.size();
8170 boolean goodToGo = true;
8171 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8172 "Checking " + NN + " opening apps (frozen="
8173 + mDisplayFrozen + " timeout="
8174 + mAppTransitionTimeout + ")...");
8175 if (!mDisplayFrozen && !mAppTransitionTimeout) {
8176 // If the display isn't frozen, wait to do anything until
8177 // all of the apps are ready. Otherwise just go because
8178 // we'll unfreeze the display when everyone is ready.
8179 for (i=0; i<NN && goodToGo; i++) {
8180 AppWindowToken wtoken = mOpeningApps.get(i);
8181 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Craig Mautner1d961d42012-05-27 12:02:11 -07008182 "Check opening app=" + wtoken + ": allDrawn="
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008183 + wtoken.allDrawn + " startingDisplayed="
Craig Mautner7358fbf2012-04-12 21:06:33 -07008184 + wtoken.startingDisplayed + " startingMoved="
8185 + wtoken.startingMoved);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008186 if (!wtoken.allDrawn && !wtoken.startingDisplayed
8187 && !wtoken.startingMoved) {
8188 goodToGo = false;
8189 }
8190 }
8191 }
8192 if (goodToGo) {
8193 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
8194 int transit = mNextAppTransition;
8195 if (mSkipAppTransitionAnimation) {
8196 transit = WindowManagerPolicy.TRANSIT_UNSET;
8197 }
8198 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
8199 mAppTransitionReady = false;
8200 mAppTransitionRunning = true;
8201 mAppTransitionTimeout = false;
8202 mStartingIconInTransition = false;
8203 mSkipAppTransitionAnimation = false;
8204
8205 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
8206
Craig Mautneref25d7a2012-05-15 23:01:47 -07008207 rebuildAppWindowListLocked();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008208
Craig Mautner0afddcb2012-05-08 15:38:00 -07008209 // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
Craig Mautner83339b42012-05-01 22:13:23 -07008210 WindowState oldWallpaper =
8211 mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
Craig Mautner0afddcb2012-05-08 15:38:00 -07008212 && !mWallpaperTarget.mWinAnimator.isDummyAnimation()
Craig Mautner83339b42012-05-01 22:13:23 -07008213 ? null : mWallpaperTarget;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008214
8215 adjustWallpaperWindowsLocked();
8216 mInnerFields.mWallpaperMayChange = false;
8217
8218 // The top-most window will supply the layout params,
8219 // and we will determine it below.
8220 LayoutParams animLp = null;
8221 int bestAnimLayer = -1;
8222 boolean fullscreenAnim = false;
8223
8224 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8225 "New wallpaper target=" + mWallpaperTarget
Daniel Sandlerab886f52012-06-04 14:36:25 -04008226 + ", oldWallpaper=" + oldWallpaper
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008227 + ", lower target=" + mLowerWallpaperTarget
8228 + ", upper target=" + mUpperWallpaperTarget);
8229 int foundWallpapers = 0;
8230 // Do a first pass through the tokens for two
8231 // things:
8232 // (1) Determine if both the closing and opening
8233 // app token sets are wallpaper targets, in which
8234 // case special animations are needed
8235 // (since the wallpaper needs to stay static
8236 // behind them).
8237 // (2) Find the layout params of the top-most
8238 // application window in the tokens, which is
8239 // what will control the animation theme.
8240 final int NC = mClosingApps.size();
8241 NN = NC + mOpeningApps.size();
8242 for (i=0; i<NN; i++) {
8243 AppWindowToken wtoken;
8244 int mode;
8245 if (i < NC) {
8246 wtoken = mClosingApps.get(i);
8247 mode = 1;
8248 } else {
8249 wtoken = mOpeningApps.get(i-NC);
8250 mode = 2;
8251 }
8252 if (mLowerWallpaperTarget != null) {
8253 if (mLowerWallpaperTarget.mAppToken == wtoken
8254 || mUpperWallpaperTarget.mAppToken == wtoken) {
8255 foundWallpapers |= mode;
8256 }
8257 }
8258 if (wtoken.appFullscreen) {
8259 WindowState ws = wtoken.findMainWindow();
8260 if (ws != null) {
8261 animLp = ws.mAttrs;
8262 bestAnimLayer = ws.mLayer;
8263 fullscreenAnim = true;
8264 }
8265 } else if (!fullscreenAnim) {
8266 WindowState ws = wtoken.findMainWindow();
8267 if (ws != null) {
8268 if (ws.mLayer > bestAnimLayer) {
8269 animLp = ws.mAttrs;
8270 bestAnimLayer = ws.mLayer;
8271 }
8272 }
8273 }
8274 }
8275
8276 if (foundWallpapers == 3) {
8277 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8278 "Wallpaper animation!");
8279 switch (transit) {
8280 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
8281 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
8282 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
8283 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
8284 break;
8285 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
8286 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
8287 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
8288 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
8289 break;
8290 }
8291 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8292 "New transit: " + transit);
Daniel Sandlerab886f52012-06-04 14:36:25 -04008293 } else if ((oldWallpaper != null) && !mOpeningApps.contains(oldWallpaper.mAppToken)) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008294 // We are transitioning from an activity with
8295 // a wallpaper to one without.
8296 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
8297 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8298 "New transit away from wallpaper: " + transit);
8299 } else if (mWallpaperTarget != null) {
8300 // We are transitioning from an activity without
8301 // a wallpaper to now showing the wallpaper
8302 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
8303 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8304 "New transit into wallpaper: " + transit);
8305 }
8306
8307 // If all closing windows are obscured, then there is
8308 // no need to do an animation. This is the case, for
8309 // example, when this transition is being done behind
8310 // the lock screen.
8311 if (!mPolicy.allowAppAnimationsLw()) {
8312 animLp = null;
8313 }
8314
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008315 AppWindowToken topOpeningApp = null;
8316 int topOpeningLayer = 0;
8317
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008318 NN = mOpeningApps.size();
8319 for (i=0; i<NN; i++) {
8320 AppWindowToken wtoken = mOpeningApps.get(i);
Craig Mautnerbec53f72012-04-05 11:49:05 -07008321 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
Craig Mautner59431632012-04-04 11:56:44 -07008322 wtoken.mAppAnimator.clearThumbnail();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008323 wtoken.reportedVisible = false;
8324 wtoken.inPendingTransaction = false;
Craig Mautner59431632012-04-04 11:56:44 -07008325 wtoken.mAppAnimator.animation = null;
Craig Mautnerbec53f72012-04-05 11:49:05 -07008326 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008327 wtoken.updateReportedVisibilityLocked();
8328 wtoken.waitingToShow = false;
Craig Mautnerbec53f72012-04-05 11:49:05 -07008329 mAnimator.mAnimating |= wtoken.mAppAnimator.showAllWindowsLocked();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008330 if (animLp != null) {
8331 int layer = -1;
8332 for (int j=0; j<wtoken.windows.size(); j++) {
8333 WindowState win = wtoken.windows.get(j);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07008334 if (win.mWinAnimator.mAnimLayer > layer) {
8335 layer = win.mWinAnimator.mAnimLayer;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008336 }
8337 }
8338 if (topOpeningApp == null || layer > topOpeningLayer) {
8339 topOpeningApp = wtoken;
8340 topOpeningLayer = layer;
8341 }
8342 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008343 }
8344 NN = mClosingApps.size();
8345 for (i=0; i<NN; i++) {
8346 AppWindowToken wtoken = mClosingApps.get(i);
8347 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8348 "Now closing app" + wtoken);
Craig Mautner59431632012-04-04 11:56:44 -07008349 wtoken.mAppAnimator.clearThumbnail();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008350 wtoken.inPendingTransaction = false;
Craig Mautner59431632012-04-04 11:56:44 -07008351 wtoken.mAppAnimator.animation = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008352 setTokenVisibilityLocked(wtoken, animLp, false,
8353 transit, false);
8354 wtoken.updateReportedVisibilityLocked();
8355 wtoken.waitingToHide = false;
8356 // Force the allDrawn flag, because we want to start
8357 // this guy's animations regardless of whether it's
8358 // gotten drawn.
8359 wtoken.allDrawn = true;
8360 }
8361
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008362 if (mNextAppTransitionThumbnail != null && topOpeningApp != null
Craig Mautner59431632012-04-04 11:56:44 -07008363 && topOpeningApp.mAppAnimator.animation != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008364 // This thumbnail animation is very special, we need to have
8365 // an extra surface with the thumbnail included with the animation.
8366 Rect dirty = new Rect(0, 0, mNextAppTransitionThumbnail.getWidth(),
8367 mNextAppTransitionThumbnail.getHeight());
8368 try {
8369 Surface surface = new Surface(mFxSession, Process.myPid(),
Craig Mautner6881a102012-07-27 13:04:51 -07008370 "thumbnail anim", Display.DEFAULT_DISPLAY,
8371 dirty.width(), dirty.height(),
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008372 PixelFormat.TRANSLUCENT, Surface.HIDDEN);
Craig Mautner59431632012-04-04 11:56:44 -07008373 topOpeningApp.mAppAnimator.thumbnail = surface;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008374 if (SHOW_TRANSACTIONS) Slog.i(TAG, " THUMBNAIL "
8375 + surface + ": CREATE");
8376 Surface drawSurface = new Surface();
8377 drawSurface.copyFrom(surface);
8378 Canvas c = drawSurface.lockCanvas(dirty);
8379 c.drawBitmap(mNextAppTransitionThumbnail, 0, 0, null);
8380 drawSurface.unlockCanvasAndPost(c);
8381 drawSurface.release();
Craig Mautner59431632012-04-04 11:56:44 -07008382 topOpeningApp.mAppAnimator.thumbnailLayer = topOpeningLayer;
Michael Jurka21385cd2012-05-03 10:57:31 -07008383 Animation anim = createThumbnailAnimationLocked(
8384 transit, true, true, mNextAppTransitionDelayed);
Craig Mautner59431632012-04-04 11:56:44 -07008385 topOpeningApp.mAppAnimator.thumbnailAnimation = anim;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008386 anim.restrictDuration(MAX_ANIMATION_DURATION);
8387 anim.scaleCurrentDuration(mTransitionAnimationScale);
Craig Mautner59431632012-04-04 11:56:44 -07008388 topOpeningApp.mAppAnimator.thumbnailX = mNextAppTransitionStartX;
8389 topOpeningApp.mAppAnimator.thumbnailY = mNextAppTransitionStartY;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008390 } catch (Surface.OutOfResourcesException e) {
8391 Slog.e(TAG, "Can't allocate thumbnail surface w=" + dirty.width()
8392 + " h=" + dirty.height(), e);
Craig Mautner59431632012-04-04 11:56:44 -07008393 topOpeningApp.mAppAnimator.clearThumbnail();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008394 }
8395 }
8396
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07008397 mNextAppTransitionType = ActivityOptions.ANIM_NONE;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008398 mNextAppTransitionPackage = null;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008399 mNextAppTransitionThumbnail = null;
Dianne Hackborn84375872012-06-01 19:03:50 -07008400 scheduleAnimationCallback(mNextAppTransitionCallback);
8401 mNextAppTransitionCallback = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008402
8403 mOpeningApps.clear();
8404 mClosingApps.clear();
8405
8406 // This has changed the visibility of windows, so perform
8407 // a new layout to get them all up-to-date.
8408 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT
8409 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
8410 mLayoutNeeded = true;
Craig Mautner59c00972012-07-30 12:10:24 -07008411
8412 // TODO(multidisplay): IMEs are only supported on the default display.
8413 if (windows == getDefaultWindowList() && !moveInputMethodWindowsIfNeededLocked(true)) {
8414 assignLayersLocked(windows);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008415 }
Craig Mautner59c00972012-07-30 12:10:24 -07008416 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, false /*updateInputWindows*/);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008417 mFocusMayChange = false;
8418 }
8419
8420 return changes;
8421 }
8422
8423 /**
8424 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008425 * @return bitmap indicating if another pass through layout must be made.
8426 */
Craig Mautner2f995a72012-02-21 09:53:21 -08008427 private int handleAnimatingStoppedAndTransitionLocked() {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008428 int changes = 0;
8429
8430 mAppTransitionRunning = false;
Craig Mautneref25d7a2012-05-15 23:01:47 -07008431 // Restore window app tokens to the ActivityManager views
Craig Mautner3f99fde2012-06-19 14:10:01 -07008432 for (int i = mAnimatingAppTokens.size() - 1; i >= 0; i--) {
8433 mAnimatingAppTokens.get(i).sendingToBottom = false;
8434 }
Craig Mautneref25d7a2012-05-15 23:01:47 -07008435 mAnimatingAppTokens.clear();
8436 mAnimatingAppTokens.addAll(mAppTokens);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008437 rebuildAppWindowListLocked();
Craig Mautneref25d7a2012-05-15 23:01:47 -07008438
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008439 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
8440 mInnerFields.mAdjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Craig Mautneref25d7a2012-05-15 23:01:47 -07008441 moveInputMethodWindowsIfNeededLocked(true);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008442 mInnerFields.mWallpaperMayChange = true;
8443 // Since the window list has been rebuilt, focus might
8444 // have to be recomputed since the actual order of windows
8445 // might have changed again.
8446 mFocusMayChange = true;
8447
8448 return changes;
8449 }
8450
8451 /**
8452 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
8453 *
8454 * @return bitmap indicating if another pass through layout must be made.
8455 */
8456 private int animateAwayWallpaperLocked() {
8457 int changes = 0;
8458 WindowState oldWallpaper = mWallpaperTarget;
8459 if (mLowerWallpaperTarget != null
8460 && mLowerWallpaperTarget.mAppToken != null) {
8461 if (DEBUG_WALLPAPER) Slog.v(TAG,
8462 "wallpaperForceHiding changed with lower="
8463 + mLowerWallpaperTarget);
8464 if (DEBUG_WALLPAPER) Slog.v(TAG,
8465 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
8466 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
8467 if (mLowerWallpaperTarget.mAppToken.hidden) {
8468 // The lower target has become hidden before we
8469 // actually started the animation... let's completely
8470 // re-evaluate everything.
8471 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
8472 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
8473 }
8474 }
8475 mInnerFields.mAdjResult |= adjustWallpaperWindowsLocked();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008476 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
8477 + " NEW: " + mWallpaperTarget
8478 + " LOWER: " + mLowerWallpaperTarget);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008479 return changes;
8480 }
8481
Craig Mautnere32c3072012-03-12 15:25:35 -07008482 private void updateResizingWindows(final WindowState w) {
Craig Mautnera608b882012-03-30 13:03:49 -07008483 final WindowStateAnimator winAnimator = w.mWinAnimator;
Craig Mautner1efacf72012-04-27 12:58:21 -07008484 if (w.mHasSurface && !w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
Craig Mautnere32c3072012-03-12 15:25:35 -07008485 w.mContentInsetsChanged |=
Dianne Hackborn5c58de32012-04-28 19:52:37 -07008486 !w.mLastContentInsets.equals(w.mContentInsets);
Craig Mautnere32c3072012-03-12 15:25:35 -07008487 w.mVisibleInsetsChanged |=
Dianne Hackborn5c58de32012-04-28 19:52:37 -07008488 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Craig Mautnere32c3072012-03-12 15:25:35 -07008489 boolean configChanged =
8490 w.mConfiguration != mCurConfiguration
8491 && (w.mConfiguration == null
8492 || mCurConfiguration.diff(w.mConfiguration) != 0);
8493 if (DEBUG_CONFIGURATION && configChanged) {
8494 Slog.v(TAG, "Win " + w + " config changed: "
8495 + mCurConfiguration);
8496 }
8497 if (localLOGV) Slog.v(TAG, "Resizing " + w
8498 + ": configChanged=" + configChanged
8499 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
8500 w.mLastFrame.set(w.mFrame);
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07008501 if (w.mContentInsetsChanged
Craig Mautnere32c3072012-03-12 15:25:35 -07008502 || w.mVisibleInsetsChanged
Craig Mautnera608b882012-03-30 13:03:49 -07008503 || winAnimator.mSurfaceResized
Craig Mautnere32c3072012-03-12 15:25:35 -07008504 || configChanged) {
8505 if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
8506 Slog.v(TAG, "Resize reasons: "
8507 + " contentInsetsChanged=" + w.mContentInsetsChanged
8508 + " visibleInsetsChanged=" + w.mVisibleInsetsChanged
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008509 + " surfaceResized=" + winAnimator.mSurfaceResized
Craig Mautnere32c3072012-03-12 15:25:35 -07008510 + " configChanged=" + configChanged);
8511 }
8512
8513 w.mLastContentInsets.set(w.mContentInsets);
8514 w.mLastVisibleInsets.set(w.mVisibleInsets);
8515 makeWindowFreezingScreenIfNeededLocked(w);
8516 // If the orientation is changing, then we need to
8517 // hold off on unfreezing the display until this
8518 // window has been redrawn; to do that, we need
8519 // to go through the process of getting informed
8520 // by the application when it has finished drawing.
8521 if (w.mOrientationChanging) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07008522 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautner83339b42012-05-01 22:13:23 -07008523 "Orientation start waiting for draw mDrawState=DRAW_PENDING in "
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008524 + w + ", surface " + winAnimator.mSurface);
Craig Mautner749a7bb2012-04-02 13:49:53 -07008525 winAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
Craig Mautnere32c3072012-03-12 15:25:35 -07008526 if (w.mAppToken != null) {
8527 w.mAppToken.allDrawn = false;
8528 }
8529 }
8530 if (!mResizingWindows.contains(w)) {
8531 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008532 "Resizing window " + w + " to " + winAnimator.mSurfaceW
8533 + "x" + winAnimator.mSurfaceH);
Craig Mautnere32c3072012-03-12 15:25:35 -07008534 mResizingWindows.add(w);
8535 }
8536 } else if (w.mOrientationChanging) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07008537 if (w.isDrawnLw()) {
Craig Mautnere32c3072012-03-12 15:25:35 -07008538 if (DEBUG_ORIENTATION) Slog.v(TAG,
8539 "Orientation not waiting for draw in "
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008540 + w + ", surface " + winAnimator.mSurface);
Craig Mautnere32c3072012-03-12 15:25:35 -07008541 w.mOrientationChanging = false;
8542 }
8543 }
8544 }
8545 }
8546
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008547 /**
8548 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
8549 *
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008550 * @param w WindowState this method is applied to.
8551 * @param currentTime The time which animations use for calculating transitions.
8552 * @param innerDw Width of app window.
8553 * @param innerDh Height of app window.
8554 */
8555 private void handleNotObscuredLocked(final WindowState w, final long currentTime,
8556 final int innerDw, final int innerDh) {
8557 final WindowManager.LayoutParams attrs = w.mAttrs;
8558 final int attrFlags = attrs.flags;
8559 final boolean canBeSeen = w.isDisplayedLw();
8560
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07008561 if (w.mHasSurface) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008562 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
8563 mInnerFields.mHoldScreen = w.mSession;
8564 }
8565 if (!mInnerFields.mSyswin && w.mAttrs.screenBrightness >= 0
8566 && mInnerFields.mScreenBrightness < 0) {
8567 mInnerFields.mScreenBrightness = w.mAttrs.screenBrightness;
8568 }
8569 if (!mInnerFields.mSyswin && w.mAttrs.buttonBrightness >= 0
8570 && mInnerFields.mButtonBrightness < 0) {
8571 mInnerFields.mButtonBrightness = w.mAttrs.buttonBrightness;
8572 }
8573 if (canBeSeen
8574 && (attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
8575 || attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD
8576 || attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_ERROR)) {
8577 mInnerFields.mSyswin = true;
8578 }
8579 }
8580
8581 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
8582 if (opaqueDrawn && w.isFullscreen(innerDw, innerDh)) {
8583 // This window completely covers everything behind it,
Craig Mautner2fb98b12012-03-20 17:24:00 -07008584 // so we want to leave all of them as undimmed (for
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008585 // performance reasons).
8586 mInnerFields.mObscured = true;
Craig Mautner35af2ff2012-04-24 14:30:15 -07008587 } else if (canBeSeen && (attrFlags & FLAG_DIM_BEHIND) != 0
Craig Mautner236a35b2012-06-08 09:54:59 -07008588 && !(w.mAppToken != null && w.mAppToken.hiddenRequested)
8589 && !w.mExiting) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07008590 if (localLOGV) Slog.v(TAG, "Win " + w + " obscured=" + mInnerFields.mObscured);
8591 if (!mInnerFields.mDimming) {
8592 //Slog.i(TAG, "DIM BEHIND: " + w);
8593 mInnerFields.mDimming = true;
Craig Mautneracafd192012-05-10 10:41:02 -07008594 final WindowStateAnimator winAnimator = w.mWinAnimator;
8595 if (!mAnimator.isDimming(winAnimator)) {
Craig Mautnerf8d4fbb2012-04-11 09:25:53 -07008596 final int width, height;
8597 if (attrs.type == WindowManager.LayoutParams.TYPE_BOOT_PROGRESS) {
Craig Mautner59c00972012-07-30 12:10:24 -07008598 final DisplayInfo displayInfo = w.mDisplayContent.getDisplayInfo();
8599 width = displayInfo.logicalWidth;
8600 height = displayInfo.logicalHeight;
Craig Mautnerf8d4fbb2012-04-11 09:25:53 -07008601 } else {
8602 width = innerDw;
8603 height = innerDh;
8604 }
Craig Mautnera76fdb72012-07-03 19:03:02 -07008605 startDimming(winAnimator, w.mExiting ? 0 : w.mAttrs.dimAmount, width, height);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008606 }
8607 }
8608 }
8609 }
8610
Craig Mautner6fbda632012-07-03 09:26:39 -07008611 private void updateAllDrawnLocked() {
8612 // See if any windows have been drawn, so they (and others
8613 // associated with them) can now be shown.
8614 final ArrayList<AppWindowToken> appTokens = mAnimatingAppTokens;
8615 final int NT = appTokens.size();
8616 for (int i=0; i<NT; i++) {
8617 AppWindowToken wtoken = appTokens.get(i);
8618 if (!wtoken.allDrawn) {
8619 int numInteresting = wtoken.numInterestingWindows;
8620 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
8621 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
8622 "allDrawn: " + wtoken
8623 + " interesting=" + numInteresting
8624 + " drawn=" + wtoken.numDrawnWindows);
8625 wtoken.allDrawn = true;
8626 }
8627 }
8628 }
8629 }
8630
Brad Fitzpatrick68044332010-11-22 18:19:48 -08008631 // "Something has changed! Let's make it correct now."
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008632 private final void performLayoutAndPlaceSurfacesLockedInner(
Craig Mautner59c00972012-07-30 12:10:24 -07008633 final DisplayContent displayContent, boolean recoveringMemory) {
Craig Mautner7d8df392012-04-06 15:26:23 -07008634 if (DEBUG_WINDOW_TRACE) {
Craig Mautner3255a282012-04-16 15:42:47 -07008635 Slog.v(TAG, "performLayoutAndPlaceSurfacesLockedInner: entry. Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -07008636 + Debug.getCallers(3));
Craig Mautner7d8df392012-04-06 15:26:23 -07008637 }
Joe Onorato34bcebc2010-07-07 18:05:01 -04008638 if (mDisplay == null) {
8639 Slog.i(TAG, "skipping performLayoutAndPlaceSurfacesLockedInner with no mDisplay");
8640 return;
8641 }
8642
Craig Mautner59c00972012-07-30 12:10:24 -07008643 final WindowList windows = displayContent.getWindowList();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008644 final long currentTime = SystemClock.uptimeMillis();
Craig Mautner59c00972012-07-30 12:10:24 -07008645 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
8646 final int dw = displayInfo.logicalWidth;
8647 final int dh = displayInfo.logicalHeight;
8648 final int innerDw = displayInfo.appWidth;
8649 final int innerDh = displayInfo.appHeight;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008650
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008651 int i;
8652
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008653 if (mFocusMayChange) {
8654 mFocusMayChange = false;
Jeff Brown3a22cd92011-01-21 13:59:04 -08008655 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
8656 false /*updateInputWindows*/);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008657 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008658
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008659 // Initialize state of exiting tokens.
8660 for (i=mExitingTokens.size()-1; i>=0; i--) {
8661 mExitingTokens.get(i).hasVisible = false;
8662 }
8663
8664 // Initialize state of exiting applications.
8665 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
8666 mExitingAppTokens.get(i).hasVisible = false;
8667 }
8668
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008669 mInnerFields.mHoldScreen = null;
8670 mInnerFields.mScreenBrightness = -1;
8671 mInnerFields.mButtonBrightness = -1;
Craig Mautner6fbda632012-07-03 09:26:39 -07008672 mTransactionSequence++;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07008673
Dianne Hackborn36991742011-10-11 21:35:26 -07008674 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
8675 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008676
8677 Surface.openTransaction();
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07008678
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07008679 if (mWatermark != null) {
8680 mWatermark.positionSurface(dw, dh);
8681 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08008682 if (mStrictModeFlash != null) {
8683 mStrictModeFlash.positionSurface(dw, dh);
8684 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07008685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008686 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008687 int repeats = 0;
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008688
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008689 do {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008690 repeats++;
8691 if (repeats > 6) {
8692 Slog.w(TAG, "Animation repeat aborted after too many iterations");
8693 mLayoutNeeded = false;
8694 break;
8695 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008696
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07008697 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("On entry to LockedInner",
8698 mPendingLayoutChanges);
Craig Mautnercf8cbbe2012-03-25 21:54:36 -07008699
Craig Mautnere32c3072012-03-12 15:25:35 -07008700 if ((mPendingLayoutChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07008701 if ((adjustWallpaperWindowsLocked() & ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
8702 assignLayersLocked(windows);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008703 mLayoutNeeded = true;
8704 }
8705 }
Craig Mautnerbb1449b2012-03-23 16:11:14 -07008706
Craig Mautnere32c3072012-03-12 15:25:35 -07008707 if ((mPendingLayoutChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008708 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
8709 if (updateOrientationFromAppTokensLocked(true)) {
8710 mLayoutNeeded = true;
8711 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
8712 }
8713 }
Craig Mautnerbb1449b2012-03-23 16:11:14 -07008714
Craig Mautnere32c3072012-03-12 15:25:35 -07008715 if ((mPendingLayoutChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008716 mLayoutNeeded = true;
8717 }
8718
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008719 // FIRST LOOP: Perform a layout, if needed.
8720 if (repeats < 4) {
Craig Mautner59c00972012-07-30 12:10:24 -07008721 performLayoutLockedInner(displayContent, repeats == 1, false /*updateInputWindows*/);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008722 } else {
8723 Slog.w(TAG, "Layout repeat skipped after too many iterations");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008724 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008725
Craig Mautnere32c3072012-03-12 15:25:35 -07008726 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
8727 // it is animating.
8728 mPendingLayoutChanges = 0;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07008729 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("loop number " + mLayoutRepeatCount,
8730 mPendingLayoutChanges);
Craig Mautnere32c3072012-03-12 15:25:35 -07008731 mPolicy.beginAnimationLw(dw, dh);
Craig Mautner59c00972012-07-30 12:10:24 -07008732 for (i = windows.size() - 1; i >= 0; i--) {
8733 WindowState w = windows.get(i);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07008734 if (w.mHasSurface) {
Craig Mautnere32c3072012-03-12 15:25:35 -07008735 mPolicy.animatingWindowLw(w, w.mAttrs);
8736 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008737 }
Craig Mautnere32c3072012-03-12 15:25:35 -07008738 mPendingLayoutChanges |= mPolicy.finishAnimationLw();
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07008739 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after finishAnimationLw",
8740 mPendingLayoutChanges);
Craig Mautnere32c3072012-03-12 15:25:35 -07008741 } while (mPendingLayoutChanges != 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008742
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07008743 final boolean someoneLosingFocus = !mLosingFocus.isEmpty();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008744
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008745 mInnerFields.mObscured = false;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008746 mInnerFields.mDimming = false;
8747 mInnerFields.mSyswin = false;
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008748
Craig Mautner7358fbf2012-04-12 21:06:33 -07008749 boolean focusDisplayed = false;
Craig Mautner6fbda632012-07-03 09:26:39 -07008750 boolean updateAllDrawn = false;
Craig Mautner59c00972012-07-30 12:10:24 -07008751 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008752 for (i=N-1; i>=0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07008753 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008754
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008755 final boolean obscuredChanged = w.mObscured != mInnerFields.mObscured;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008756
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008757 // Update effect.
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008758 w.mObscured = mInnerFields.mObscured;
8759 if (!mInnerFields.mObscured) {
8760 handleNotObscuredLocked(w, currentTime, innerDw, innerDh);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008761 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008762
Craig Mautnerad5725d2012-06-05 10:20:56 -07008763 if (obscuredChanged && (mWallpaperTarget == w) && w.isVisibleLw()) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07008764 // This is the wallpaper target and its obscured state
8765 // changed... make sure the current wallaper's visibility
8766 // has been updated accordingly.
8767 updateWallpaperVisibilityLocked();
8768 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008769
8770 final WindowStateAnimator winAnimator = w.mWinAnimator;
8771
8772 // If the window has moved due to its containing
8773 // content frame changing, then we'd like to animate
8774 // it.
8775 if (w.mHasSurface && w.shouldAnimateMove()) {
8776 // Frame has moved, containing content frame
8777 // has also moved, and we're not currently animating...
8778 // let's do something.
8779 Animation a = AnimationUtils.loadAnimation(mContext,
8780 com.android.internal.R.anim.window_move_from_decor);
8781 winAnimator.setAnimation(a);
8782 winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
8783 winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
Craig Mautner5702d4d2012-06-30 14:10:16 -07008784 try {
8785 w.mClient.moved(w.mFrame.left, w.mFrame.top);
8786 } catch (RemoteException e) {
8787 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008788 }
8789
8790 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
8791 w.mContentChanged = false;
8792
8793 // Moved from updateWindowsAndWallpaperLocked().
8794 if (w.mHasSurface) {
8795 // Take care of the window being ready to display.
8796 if (winAnimator.commitFinishDrawingLocked(currentTime)) {
8797 if ((w.mAttrs.flags
8798 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
8799 if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG,
8800 "First draw done in potential wallpaper target " + w);
8801 mInnerFields.mWallpaperMayChange = true;
8802 mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
8803 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
Craig Mautner6fbda632012-07-03 09:26:39 -07008804 debugLayoutRepeats("wallpaper and commitFinishDrawingLocked true",
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008805 mPendingLayoutChanges);
8806 }
8807 }
8808 }
8809
8810 winAnimator.setSurfaceBoundaries(recoveringMemory);
Craig Mautner6fbda632012-07-03 09:26:39 -07008811
8812 final AppWindowToken atoken = w.mAppToken;
8813 if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) {
8814 Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen="
8815 + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
8816 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
8817 }
8818 if (atoken != null
8819 && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
8820 if (atoken.lastTransactionSequence != mTransactionSequence) {
8821 atoken.lastTransactionSequence = mTransactionSequence;
8822 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
8823 atoken.startingDisplayed = false;
8824 }
8825 if ((w.isOnScreen() || winAnimator.mAttrType
8826 == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
8827 && !w.mExiting && !w.mDestroying) {
8828 if (WindowManagerService.DEBUG_VISIBILITY ||
8829 WindowManagerService.DEBUG_ORIENTATION) {
8830 Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
8831 + ", isAnimating=" + winAnimator.isAnimating());
8832 if (!w.isDrawnLw()) {
8833 Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurface
8834 + " pv=" + w.mPolicyVisibility
8835 + " mDrawState=" + winAnimator.mDrawState
8836 + " ah=" + w.mAttachedHidden
8837 + " th=" + atoken.hiddenRequested
8838 + " a=" + winAnimator.mAnimating);
8839 }
8840 }
8841 if (w != atoken.startingWindow) {
8842 if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
8843 atoken.numInterestingWindows++;
8844 if (w.isDrawnLw()) {
8845 atoken.numDrawnWindows++;
8846 if (WindowManagerService.DEBUG_VISIBILITY ||
8847 WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
8848 "tokenMayBeDrawn: " + atoken
8849 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen
8850 + " mAppFreezing=" + w.mAppFreezing);
8851 updateAllDrawn = true;
8852 }
8853 }
8854 } else if (w.isDrawnLw()) {
8855 atoken.startingDisplayed = true;
8856 }
8857 }
8858 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008859 }
8860
Craig Mautner51bb12b2012-04-27 14:39:53 -07008861 if (someoneLosingFocus && w == mCurrentFocus && w.isDisplayedLw()) {
8862 focusDisplayed = true;
8863 }
8864
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008865 updateResizingWindows(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008866 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008867
Craig Mautner6fbda632012-07-03 09:26:39 -07008868 if (updateAllDrawn) {
8869 updateAllDrawnLocked();
8870 }
8871
Craig Mautner7358fbf2012-04-12 21:06:33 -07008872 if (focusDisplayed) {
8873 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
8874 }
8875
Craig Mautnerf8d4fbb2012-04-11 09:25:53 -07008876 if (!mInnerFields.mDimming && mAnimator.isDimming()) {
Craig Mautnera76fdb72012-07-03 19:03:02 -07008877 stopDimming();
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07008878 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008879 } catch (RuntimeException e) {
Dianne Hackborn89620282011-09-11 12:47:45 -07008880 Log.wtf(TAG, "Unhandled exception in Window Manager", e);
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07008881 } finally {
8882 Surface.closeTransaction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008883 }
8884
Craig Mautner764983d2012-03-22 11:37:36 -07008885 // If we are ready to perform an app transition, check through
8886 // all of the app tokens to be shown and see if they are ready
8887 // to go.
8888 if (mAppTransitionReady) {
Craig Mautner59c00972012-07-30 12:10:24 -07008889 mPendingLayoutChanges |= handleAppTransitionReadyLocked(windows);
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07008890 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAppTransitionReadyLocked",
8891 mPendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07008892 }
8893
8894 mInnerFields.mAdjResult = 0;
8895
8896 if (!mAnimator.mAnimating && mAppTransitionRunning) {
8897 // We have finished the animation of an app transition. To do
8898 // this, we have delayed a lot of operations like showing and
8899 // hiding apps, moving apps in Z-order, etc. The app token list
8900 // reflects the correct Z-order, but the window list may now
8901 // be out of sync with it. So here we will just rebuild the
8902 // entire app window list. Fun!
8903 mPendingLayoutChanges |= handleAnimatingStoppedAndTransitionLocked();
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07008904 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAnimStopAndXitionLock",
8905 mPendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07008906 }
8907
8908 if (mInnerFields.mWallpaperForceHidingChanged && mPendingLayoutChanges == 0 &&
8909 !mAppTransitionReady) {
8910 // At this point, there was a window with a wallpaper that
8911 // was force hiding other windows behind it, but now it
8912 // is going away. This may be simple -- just animate
8913 // away the wallpaper and its window -- or it may be
8914 // hard -- the wallpaper now needs to be shown behind
8915 // something that was hidden.
8916 mPendingLayoutChanges |= animateAwayWallpaperLocked();
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07008917 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animateAwayWallpaperLocked",
8918 mPendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07008919 }
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07008920 mInnerFields.mWallpaperForceHidingChanged = false;
Craig Mautner764983d2012-03-22 11:37:36 -07008921
Craig Mautnere7ae2502012-03-26 17:11:19 -07008922 if (mInnerFields.mWallpaperMayChange) {
8923 if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG,
8924 "Wallpaper may change! Adjusting");
8925 mInnerFields.mAdjResult |= adjustWallpaperWindowsLocked();
8926 }
8927
8928 if ((mInnerFields.mAdjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
8929 if (DEBUG_WALLPAPER) Slog.v(TAG,
8930 "Wallpaper layer changed: assigning layers + relayout");
8931 mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Craig Mautner59c00972012-07-30 12:10:24 -07008932 assignLayersLocked(windows);
Craig Mautnere7ae2502012-03-26 17:11:19 -07008933 } else if ((mInnerFields.mAdjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
8934 if (DEBUG_WALLPAPER) Slog.v(TAG,
8935 "Wallpaper visibility changed: relayout");
8936 mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
8937 }
8938
8939 if (mFocusMayChange) {
8940 mFocusMayChange = false;
8941 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
8942 false /*updateInputWindows*/)) {
8943 mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
8944 mInnerFields.mAdjResult = 0;
8945 }
8946 }
Craig Mautner764983d2012-03-22 11:37:36 -07008947
8948 if (mLayoutNeeded) {
8949 mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07008950 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded", mPendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07008951 }
8952
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07008953 if (!mResizingWindows.isEmpty()) {
8954 for (i = mResizingWindows.size() - 1; i >= 0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008955 WindowState win = mResizingWindows.get(i);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008956 final WindowStateAnimator winAnimator = win.mWinAnimator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008957 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -08008958 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07008959 "Reporting new frame to " + win + ": " + win.mCompatFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -07008960 int diff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008961 boolean configChanged =
8962 win.mConfiguration != mCurConfiguration
8963 && (win.mConfiguration == null
Dianne Hackborn694f79b2010-03-17 19:44:59 -07008964 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0);
8965 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
8966 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008967 Slog.i(TAG, "Sending new config to window " + win + ": "
Craig Mautnera608b882012-03-30 13:03:49 -07008968 + winAnimator.mSurfaceW + "x" + winAnimator.mSurfaceH
Dianne Hackborn694f79b2010-03-17 19:44:59 -07008969 + " / " + mCurConfiguration + " / 0x"
8970 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008971 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07008972 win.mConfiguration = mCurConfiguration;
Craig Mautner749a7bb2012-04-02 13:49:53 -07008973 if (DEBUG_ORIENTATION &&
8974 winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) Slog.i(
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008975 TAG, "Resizing " + win + " WITH DRAW PENDING");
Svetoslav Ganov758143e2012-08-06 16:40:27 -07008976 win.mClient.resized(win.mFrame, win.mLastContentInsets, win.mLastVisibleInsets,
Craig Mautner749a7bb2012-04-02 13:49:53 -07008977 winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING,
8978 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008979 win.mContentInsetsChanged = false;
8980 win.mVisibleInsetsChanged = false;
Craig Mautnera608b882012-03-30 13:03:49 -07008981 winAnimator.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008982 } catch (RemoteException e) {
8983 win.mOrientationChanging = false;
8984 }
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07008985 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008986 mResizingWindows.clear();
8987 }
Romain Guy06882f82009-06-10 13:36:04 -07008988
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008989 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
8990 "With display frozen, orientationChangeComplete="
8991 + mInnerFields.mOrientationChangeComplete);
8992 if (mInnerFields.mOrientationChangeComplete) {
8993 if (mWindowsFreezingScreen) {
8994 mWindowsFreezingScreen = false;
8995 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
8996 }
8997 stopFreezingDisplayLocked();
8998 }
8999
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009000 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009001 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009002 i = mDestroySurface.size();
9003 if (i > 0) {
9004 do {
9005 i--;
9006 WindowState win = mDestroySurface.get(i);
9007 win.mDestroying = false;
9008 if (mInputMethodWindow == win) {
9009 mInputMethodWindow = null;
9010 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009011 if (win == mWallpaperTarget) {
9012 wallpaperDestroyed = true;
9013 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009014 win.mWinAnimator.destroySurfaceLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009015 } while (i > 0);
9016 mDestroySurface.clear();
9017 }
9018
9019 // Time to remove any exiting tokens?
9020 for (i=mExitingTokens.size()-1; i>=0; i--) {
9021 WindowToken token = mExitingTokens.get(i);
9022 if (!token.hasVisible) {
9023 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07009024 if (token.windowType == TYPE_WALLPAPER) {
9025 mWallpaperTokens.remove(token);
Craig Mautner918b53b2012-07-09 14:15:54 -07009026 updateLayoutToAnimWallpaperTokens();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07009027 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009028 }
9029 }
9030
9031 // Time to remove any exiting applications?
9032 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
9033 AppWindowToken token = mExitingAppTokens.get(i);
9034 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009035 // Make sure there is no animation running on this token,
9036 // so any windows associated with it will be removed as
9037 // soon as their animations are complete
Craig Mautner59431632012-04-04 11:56:44 -07009038 token.mAppAnimator.clearAnimation();
9039 token.mAppAnimator.animating = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009040 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
9041 "performLayout: App token exiting now removed" + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009042 mAppTokens.remove(token);
Craig Mautneref25d7a2012-05-15 23:01:47 -07009043 mAnimatingAppTokens.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009044 mExitingAppTokens.remove(i);
9045 }
9046 }
9047
Dianne Hackborn12d3a942012-04-27 14:16:30 -07009048 if (!mAnimator.mAnimating && mRelayoutWhileAnimating.size() > 0) {
9049 for (int j=mRelayoutWhileAnimating.size()-1; j>=0; j--) {
9050 try {
9051 mRelayoutWhileAnimating.get(j).mClient.doneAnimating();
9052 } catch (RemoteException e) {
9053 }
9054 }
9055 mRelayoutWhileAnimating.clear();
9056 }
9057
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009058 if (wallpaperDestroyed) {
Craig Mautnerbb1449b2012-03-23 16:11:14 -07009059 mLayoutNeeded |= adjustWallpaperWindowsLocked() != 0;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009060 }
Craig Mautnerbb1449b2012-03-23 16:11:14 -07009061 if (mPendingLayoutChanges != 0) {
9062 mLayoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009063 }
Jeff Browneb857f12010-07-16 10:06:33 -07009064
Jeff Brown3a22cd92011-01-21 13:59:04 -08009065 // Finally update all input windows now that the window changes have stabilized.
Jeff Brown2e44b072011-01-24 15:21:56 -08009066 mInputMonitor.updateInputWindowsLw(true /*force*/);
Jeff Browneb857f12010-07-16 10:06:33 -07009067
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009068 setHoldScreenLocked(mInnerFields.mHoldScreen != null);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009069 if (!mDisplayFrozen) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009070 if (mInnerFields.mScreenBrightness < 0 || mInnerFields.mScreenBrightness > 1.0f) {
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009071 mPowerManager.setScreenBrightnessOverride(-1);
9072 } else {
9073 mPowerManager.setScreenBrightnessOverride((int)
Jeff Brown7304c342012-05-11 18:42:42 -07009074 (mInnerFields.mScreenBrightness * PowerManager.BRIGHTNESS_ON));
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009075 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009076 if (mInnerFields.mButtonBrightness < 0 || mInnerFields.mButtonBrightness > 1.0f) {
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009077 mPowerManager.setButtonBrightnessOverride(-1);
9078 } else {
9079 mPowerManager.setButtonBrightnessOverride((int)
Jeff Brown7304c342012-05-11 18:42:42 -07009080 (mInnerFields.mButtonBrightness * PowerManager.BRIGHTNESS_ON));
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009081 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009082 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009083 if (mInnerFields.mHoldScreen != mHoldingScreenOn) {
9084 mHoldingScreenOn = mInnerFields.mHoldScreen;
9085 Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, mInnerFields.mHoldScreen);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009086 mH.sendMessage(m);
9087 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009088
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009089 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009090 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009091 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
Jeff Brownb696de52012-07-27 15:38:50 -07009092 PowerManager.USER_ACTIVITY_EVENT_BUTTON, true);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009093 mTurnOnScreen = false;
9094 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009095
Craig Mautnera608b882012-03-30 13:03:49 -07009096 if (mInnerFields.mUpdateRotation) {
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009097 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009098 if (updateRotationUncheckedLocked(false)) {
Dianne Hackborn3e4f9d02011-02-04 14:05:55 -08009099 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07009100 } else {
Craig Mautnera608b882012-03-30 13:03:49 -07009101 mInnerFields.mUpdateRotation = false;
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009102 }
9103 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009104
Craig Mautnerbb1449b2012-03-23 16:11:14 -07009105 if (mInnerFields.mOrientationChangeComplete && !mLayoutNeeded &&
Craig Mautnera608b882012-03-30 13:03:49 -07009106 !mInnerFields.mUpdateRotation) {
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07009107 checkDrawnWindowsLocked();
9108 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009109
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08009110 // Check to see if we are now in a state where the screen should
9111 // be enabled, because the window obscured flags have changed.
9112 enableScreenIfNeededLocked();
Craig Mautner7d8df392012-04-06 15:26:23 -07009113
Craig Mautner711f90a2012-07-03 18:43:52 -07009114 updateLayoutToAnimationLocked();
Craig Mautner7d8df392012-04-06 15:26:23 -07009115
9116 if (DEBUG_WINDOW_TRACE) {
9117 Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: mPendingLayoutChanges="
9118 + Integer.toHexString(mPendingLayoutChanges) + " mLayoutNeeded=" + mLayoutNeeded
9119 + " animating=" + mAnimator.mAnimating);
9120 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009121 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009122
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009123 void checkDrawnWindowsLocked() {
9124 if (mWaitingForDrawn.size() > 0) {
9125 for (int j=mWaitingForDrawn.size()-1; j>=0; j--) {
9126 Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(j);
9127 WindowState win = pair.first;
9128 //Slog.i(TAG, "Waiting for drawn " + win + ": removed="
9129 // + win.mRemoved + " visible=" + win.isVisibleLw()
9130 // + " shown=" + win.mSurfaceShown);
9131 if (win.mRemoved || !win.isVisibleLw()) {
9132 // Window has been removed or made invisible; no draw
9133 // will now happen, so stop waiting.
9134 Slog.w(TAG, "Aborted waiting for drawn: " + pair.first);
9135 try {
9136 pair.second.sendResult(null);
9137 } catch (RemoteException e) {
9138 }
9139 mWaitingForDrawn.remove(pair);
9140 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009141 } else if (win.mWinAnimator.mSurfaceShown) {
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009142 // Window is now drawn (and shown).
9143 try {
9144 pair.second.sendResult(null);
9145 } catch (RemoteException e) {
9146 }
9147 mWaitingForDrawn.remove(pair);
9148 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9149 }
9150 }
9151 }
9152 }
9153
9154 public void waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009155 synchronized (mWindowMap) {
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009156 WindowState win = windowForClientLocked(null, token, true);
9157 if (win != null) {
9158 Pair<WindowState, IRemoteCallback> pair =
9159 new Pair<WindowState, IRemoteCallback>(win, callback);
9160 Message m = mH.obtainMessage(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9161 mH.sendMessageDelayed(m, 2000);
9162 mWaitingForDrawn.add(pair);
9163 checkDrawnWindowsLocked();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009164 }
9165 }
9166 }
9167
Jeff Brown46b9ac02010-04-22 18:58:52 -07009168 /**
9169 * Must be called with the main window manager lock held.
9170 */
9171 void setHoldScreenLocked(boolean holding) {
9172 boolean state = mHoldingScreenWakeLock.isHeld();
9173 if (holding != state) {
9174 if (holding) {
Daniel Sandler0601eb72011-04-13 01:01:32 -04009175 mPolicy.screenOnStartedLw();
Jeff Brown46b9ac02010-04-22 18:58:52 -07009176 mHoldingScreenWakeLock.acquire();
9177 } else {
9178 mPolicy.screenOnStoppedLw();
9179 mHoldingScreenWakeLock.release();
9180 }
9181 }
9182 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009183
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08009184 void requestTraversalLocked() {
9185 if (!mTraversalScheduled) {
9186 mTraversalScheduled = true;
9187 mH.sendEmptyMessage(H.DO_TRAVERSAL);
9188 }
9189 }
9190
Craig Mautner711f90a2012-07-03 18:43:52 -07009191 /** Note that Locked in this case is on mLayoutToAnim */
Jeff Brown4a06c802012-02-15 15:06:01 -08009192 void scheduleAnimationLocked() {
Craig Mautner711f90a2012-07-03 18:43:52 -07009193 final LayoutToAnimatorParams layoutToAnim = mLayoutToAnim;
9194 if (!layoutToAnim.mAnimationScheduled) {
9195 layoutToAnim.mAnimationScheduled = true;
9196 mChoreographer.postCallback(
9197 Choreographer.CALLBACK_ANIMATION, mAnimator.mAnimationRunnable, null);
9198 }
9199 }
9200
9201 void updateLayoutToAnimationLocked() {
9202 final LayoutToAnimatorParams layoutToAnim = mLayoutToAnim;
Craig Mautner1caa3992012-06-22 09:46:48 -07009203 synchronized (layoutToAnim) {
9204 // Copy local params to transfer params.
Craig Mautner59c00972012-07-30 12:10:24 -07009205 ArrayList<WinAnimatorList> allWinAnimatorLists = layoutToAnim.mWinAnimatorLists;
9206 allWinAnimatorLists.clear();
9207 DisplayContentsIterator iterator = new DisplayContentsIterator();
9208 while (iterator.hasNext()) {
9209 final DisplayContent displayContent = iterator.next();
9210 WinAnimatorList winAnimatorList = new WinAnimatorList();
9211 final WindowList windows = displayContent.getWindowList();
9212 int N = windows.size();
9213 for (int i = 0; i < N; i++) {
9214 final WindowStateAnimator winAnimator = windows.get(i).mWinAnimator;
9215 if (winAnimator.mSurface != null) {
9216 winAnimatorList.add(winAnimator);
9217 }
Craig Mautner1caa3992012-06-22 09:46:48 -07009218 }
Craig Mautner59c00972012-07-30 12:10:24 -07009219 allWinAnimatorLists.add(winAnimatorList);
Craig Mautner1caa3992012-06-22 09:46:48 -07009220 }
Craig Mautner322e4032012-07-13 13:35:20 -07009221
Craig Mautner1caa3992012-06-22 09:46:48 -07009222 layoutToAnim.mWallpaperTarget = mWallpaperTarget;
Craig Mautner918b53b2012-07-09 14:15:54 -07009223 layoutToAnim.mLowerWallpaperTarget = mLowerWallpaperTarget;
9224 layoutToAnim.mUpperWallpaperTarget = mUpperWallpaperTarget;
Craig Mautner322e4032012-07-13 13:35:20 -07009225
9226 final ArrayList<AppWindowAnimParams> paramList = layoutToAnim.mAppWindowAnimParams;
9227 paramList.clear();
Craig Mautner59c00972012-07-30 12:10:24 -07009228 int N = mAnimatingAppTokens.size();
Craig Mautner322e4032012-07-13 13:35:20 -07009229 for (int i = 0; i < N; i++) {
9230 paramList.add(new AppWindowAnimParams(mAnimatingAppTokens.get(i).mAppAnimator));
9231 }
9232
9233 layoutToAnim.mParamsModified = true;
Craig Mautner711f90a2012-07-03 18:43:52 -07009234 scheduleAnimationLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009235 }
9236 }
Romain Guy06882f82009-06-10 13:36:04 -07009237
Craig Mautner918b53b2012-07-09 14:15:54 -07009238 void updateLayoutToAnimWallpaperTokens() {
9239 synchronized(mLayoutToAnim) {
9240 mLayoutToAnim.mWallpaperTokens = new ArrayList<WindowToken>(mWallpaperTokens);
9241 mLayoutToAnim.mChanges |= LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED;
9242 }
9243 }
9244
Craig Mautnera76fdb72012-07-03 19:03:02 -07009245 void setAnimDimParams(DimAnimator.Parameters params) {
9246 synchronized (mLayoutToAnim) {
9247 mLayoutToAnim.mDimParams = params;
9248 scheduleAnimationLocked();
9249 }
9250 }
9251
9252 void startDimming(final WindowStateAnimator winAnimator, final float target,
9253 final int width, final int height) {
9254 setAnimDimParams(new DimAnimator.Parameters(winAnimator, width, height, target));
9255 }
9256
9257 void stopDimming() {
9258 setAnimDimParams(null);
9259 }
9260
Craig Mautner322e4032012-07-13 13:35:20 -07009261 private boolean copyAnimToLayoutParamsLocked() {
9262 boolean doRequest = false;
9263 final WindowAnimator.AnimatorToLayoutParams animToLayout = mAnimator.mAnimToLayout;
9264 synchronized (animToLayout) {
9265 animToLayout.mUpdateQueued = false;
9266 final int bulkUpdateParams = animToLayout.mBulkUpdateParams;
9267 // TODO(cmautner): As the number of bits grows, use masks of bit groups to
9268 // eliminate unnecessary tests.
9269 if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) {
9270 mInnerFields.mUpdateRotation = true;
9271 doRequest = true;
9272 }
9273 if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
9274 mInnerFields.mWallpaperMayChange = true;
9275 doRequest = true;
9276 }
9277 if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
9278 mInnerFields.mWallpaperForceHidingChanged = true;
9279 doRequest = true;
9280 }
9281 if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
9282 mInnerFields.mOrientationChangeComplete = false;
9283 } else {
9284 mInnerFields.mOrientationChangeComplete = true;
9285 if (mWindowsFreezingScreen) {
9286 doRequest = true;
9287 }
9288 }
9289 if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
9290 mTurnOnScreen = true;
9291 }
9292
9293 mPendingLayoutChanges |= animToLayout.mPendingLayoutChanges;
9294 if (mPendingLayoutChanges != 0) {
9295 doRequest = true;
9296 }
9297
9298 mWindowDetachedWallpaper = animToLayout.mWindowDetachedWallpaper;
9299 }
9300 return doRequest;
9301 }
9302
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009303 boolean reclaimSomeSurfaceMemoryLocked(WindowStateAnimator winAnimator, String operation,
9304 boolean secure) {
9305 final Surface surface = winAnimator.mSurface;
Dianne Hackborn64825172011-03-02 21:32:58 -08009306 boolean leakedSurface = false;
9307 boolean killedApps = false;
Romain Guy06882f82009-06-10 13:36:04 -07009308
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009309 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
9310 winAnimator.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -07009311
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009312 if (mForceRemoves == null) {
9313 mForceRemoves = new ArrayList<WindowState>();
9314 }
Romain Guy06882f82009-06-10 13:36:04 -07009315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009316 long callingIdentity = Binder.clearCallingIdentity();
9317 try {
9318 // There was some problem... first, do a sanity check of the
9319 // window list to make sure we haven't left any dangling surfaces
9320 // around.
Craig Mautner59c00972012-07-30 12:10:24 -07009321
9322 AllWindowsIterator iterator = new AllWindowsIterator();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009323 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
Craig Mautner59c00972012-07-30 12:10:24 -07009324 while (iterator.hasNext()) {
9325 WindowState ws = iterator.next();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009326 WindowStateAnimator wsa = ws.mWinAnimator;
9327 if (wsa.mSurface != null) {
9328 if (!mSessions.contains(wsa.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009329 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009330 + ws + " surface=" + wsa.mSurface
9331 + " token=" + ws.mToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009332 + " pid=" + ws.mSession.mPid
9333 + " uid=" + ws.mSession.mUid);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08009334 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009335 wsa.mSurface.destroy();
9336 wsa.mSurfaceShown = false;
9337 wsa.mSurface = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009338 ws.mHasSurface = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009339 mForceRemoves.add(ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009340 leakedSurface = true;
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08009341 } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009342 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009343 + ws + " surface=" + wsa.mSurface
9344 + " token=" + ws.mAppToken);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08009345 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009346 wsa.mSurface.destroy();
9347 wsa.mSurfaceShown = false;
9348 wsa.mSurface = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009349 ws.mHasSurface = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009350 leakedSurface = true;
9351 }
9352 }
9353 }
Romain Guy06882f82009-06-10 13:36:04 -07009354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009355 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009356 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009357 SparseIntArray pidCandidates = new SparseIntArray();
Craig Mautner59c00972012-07-30 12:10:24 -07009358 iterator = new AllWindowsIterator();
9359 while (iterator.hasNext()) {
9360 WindowState ws = iterator.next();
9361 if (mForceRemoves.contains(ws)) {
9362 continue;
9363 }
9364 WindowStateAnimator wsa = ws.mWinAnimator;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009365 if (wsa.mSurface != null) {
9366 pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009367 }
9368 }
9369 if (pidCandidates.size() > 0) {
9370 int[] pids = new int[pidCandidates.size()];
9371 for (int i=0; i<pids.length; i++) {
9372 pids[i] = pidCandidates.keyAt(i);
9373 }
9374 try {
Dianne Hackborn64825172011-03-02 21:32:58 -08009375 if (mActivityManager.killPids(pids, "Free memory", secure)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009376 killedApps = true;
9377 }
9378 } catch (RemoteException e) {
9379 }
9380 }
9381 }
Romain Guy06882f82009-06-10 13:36:04 -07009382
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009383 if (leakedSurface || killedApps) {
9384 // We managed to reclaim some memory, so get rid of the trouble
9385 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -08009386 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009387 if (surface != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009388 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
Dianne Hackborn5fd21692011-06-07 14:09:47 -07009389 "RECOVER DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009390 surface.destroy();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009391 winAnimator.mSurfaceShown = false;
9392 winAnimator.mSurface = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009393 winAnimator.mWin.mHasSurface = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009394 }
Romain Guy06882f82009-06-10 13:36:04 -07009395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009396 try {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009397 winAnimator.mWin.mClient.dispatchGetNewSurface();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009398 } catch (RemoteException e) {
9399 }
9400 }
9401 } finally {
9402 Binder.restoreCallingIdentity(callingIdentity);
9403 }
Dianne Hackborn64825172011-03-02 21:32:58 -08009404
9405 return leakedSurface || killedApps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009406 }
Romain Guy06882f82009-06-10 13:36:04 -07009407
Jeff Brown3a22cd92011-01-21 13:59:04 -08009408 private boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009409 WindowState newFocus = computeFocusedWindowLocked();
9410 if (mCurrentFocus != newFocus) {
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07009411 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009412 // This check makes sure that we don't already have the focus
9413 // change message pending.
9414 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
9415 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009416 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009417 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
9418 final WindowState oldFocus = mCurrentFocus;
9419 mCurrentFocus = newFocus;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009420 mAnimator.setCurrentFocus(newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009421 mLosingFocus.remove(newFocus);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009422 int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus);
Romain Guy06882f82009-06-10 13:36:04 -07009423
Craig Mautner59c00972012-07-30 12:10:24 -07009424 // TODO(multidisplay): Focused windows on default display only.
9425 final DisplayContent displayContent = getDefaultDisplayContent();
9426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009427 final WindowState imWindow = mInputMethodWindow;
9428 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009429 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009430 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009431 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
9432 mLayoutNeeded = true;
9433 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009434 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Craig Mautner59c00972012-07-30 12:10:24 -07009435 performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009436 focusChanged &= ~WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009437 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
9438 // Client will do the layout, but we need to assign layers
9439 // for handleNewWindowLocked() below.
Craig Mautner59c00972012-07-30 12:10:24 -07009440 assignLayersLocked(displayContent.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009441 }
9442 }
Dianne Hackborndf89e652011-10-06 22:35:11 -07009443
9444 if ((focusChanged&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
9445 // The change in focus caused us to need to do a layout. Okay.
9446 mLayoutNeeded = true;
9447 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Craig Mautner59c00972012-07-30 12:10:24 -07009448 performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009449 }
9450 }
9451
Jeff Brown349703e2010-06-22 01:27:15 -07009452 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
9453 // If we defer assigning layers, then the caller is responsible for
9454 // doing this part.
Jeff Brown3a22cd92011-01-21 13:59:04 -08009455 finishUpdateFocusedWindowAfterAssignLayersLocked(updateInputWindows);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009456 }
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07009457
9458 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009459 return true;
9460 }
9461 return false;
9462 }
Jeff Brown349703e2010-06-22 01:27:15 -07009463
Jeff Brown3a22cd92011-01-21 13:59:04 -08009464 private void finishUpdateFocusedWindowAfterAssignLayersLocked(boolean updateInputWindows) {
9465 mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows);
Jeff Brown349703e2010-06-22 01:27:15 -07009466 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009467
9468 private WindowState computeFocusedWindowLocked() {
9469 WindowState result = null;
9470 WindowState win;
9471
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07009472 if (mAnimator.mUniverseBackground != null
9473 && mAnimator.mUniverseBackground.mWin.canReceiveKeys()) {
9474 return mAnimator.mUniverseBackground.mWin;
9475 }
9476
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009477 int nextAppIndex = mAppTokens.size()-1;
9478 WindowToken nextApp = nextAppIndex >= 0
9479 ? mAppTokens.get(nextAppIndex) : null;
9480
Craig Mautner59c00972012-07-30 12:10:24 -07009481 // TODO(multidisplay): IMEs are only supported on the default display.
9482 WindowList windows = getDefaultWindowList();
9483 for (int i = windows.size() - 1; i >= 0; i--) {
9484 win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009485
Joe Onorato8a9b2202010-02-26 18:56:32 -08009486 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009487 TAG, "Looking for focus: " + i
9488 + " = " + win
9489 + ", flags=" + win.mAttrs.flags
9490 + ", canReceive=" + win.canReceiveKeys());
9491
9492 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -07009493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009494 // If this window's application has been removed, just skip it.
Craig Mautneref25d7a2012-05-15 23:01:47 -07009495 if (thisApp != null && (thisApp.removed || thisApp.sendingToBottom)) {
Craig Mautner3f99fde2012-06-19 14:10:01 -07009496 if (DEBUG_FOCUS) Slog.v(TAG, "Skipping app because " + (thisApp.removed
9497 ? "removed" : "sendingToBottom"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009498 continue;
9499 }
Romain Guy06882f82009-06-10 13:36:04 -07009500
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009501 // If there is a focused app, don't allow focus to go to any
9502 // windows below it. If this is an application window, step
9503 // through the app tokens until we find its app.
9504 if (thisApp != null && nextApp != null && thisApp != nextApp
9505 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
9506 int origAppIndex = nextAppIndex;
9507 while (nextAppIndex > 0) {
9508 if (nextApp == mFocusedApp) {
9509 // Whoops, we are below the focused app... no focus
9510 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -08009511 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009512 TAG, "Reached focused app: " + mFocusedApp);
9513 return null;
9514 }
9515 nextAppIndex--;
9516 nextApp = mAppTokens.get(nextAppIndex);
9517 if (nextApp == thisApp) {
9518 break;
9519 }
9520 }
9521 if (thisApp != nextApp) {
9522 // Uh oh, the app token doesn't exist! This shouldn't
9523 // happen, but if it does we can get totally hosed...
9524 // so restart at the original app.
9525 nextAppIndex = origAppIndex;
9526 nextApp = mAppTokens.get(nextAppIndex);
9527 }
9528 }
9529
9530 // Dispatch to this window if it is wants key events.
9531 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009532 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009533 TAG, "Found focus @ " + i + " = " + win);
9534 result = win;
9535 break;
9536 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009537 }
9538
9539 return result;
9540 }
9541
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08009542 private void startFreezingDisplayLocked(boolean inTransaction) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009543 if (mDisplayFrozen) {
9544 return;
9545 }
Romain Guy06882f82009-06-10 13:36:04 -07009546
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07009547 if (mDisplay == null || !mPolicy.isScreenOnFully()) {
Dianne Hackborn8e8d65f2011-08-11 19:36:18 -07009548 // No need to freeze the screen before the system is ready or if
9549 // the screen is off.
9550 return;
9551 }
9552
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009553 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -07009554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009555 mDisplayFrozen = true;
Craig Mautner7d8df392012-04-06 15:26:23 -07009556
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009557 mInputMonitor.freezeInputDispatchingLw();
Craig Mautner7d8df392012-04-06 15:26:23 -07009558
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009559 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
9560 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07009561 mNextAppTransitionType = ActivityOptions.ANIM_NONE;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009562 mNextAppTransitionPackage = null;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07009563 mNextAppTransitionThumbnail = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009564 mAppTransitionReady = true;
9565 }
Romain Guy06882f82009-06-10 13:36:04 -07009566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009567 if (PROFILE_ORIENTATION) {
9568 File file = new File("/data/system/frozen");
9569 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
9570 }
Dianne Hackborna1111872010-11-23 20:55:11 -08009571
9572 if (CUSTOM_SCREEN_ROTATION) {
Craig Mautner764983d2012-03-22 11:37:36 -07009573 if (mAnimator.mScreenRotationAnimation != null) {
9574 mAnimator.mScreenRotationAnimation.kill();
9575 mAnimator.mScreenRotationAnimation = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08009576 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07009577
Craig Mautner59c00972012-07-30 12:10:24 -07009578 // TODO(multidisplay): rotation on main screen only.
9579 DisplayInfo displayInfo = getDefaultDisplayContent().getDisplayInfo();
Craig Mautnerd87946b2012-03-29 18:00:19 -07009580 mAnimator.mScreenRotationAnimation = new ScreenRotationAnimation(mContext,
Craig Mautner59c00972012-07-30 12:10:24 -07009581 mFxSession, inTransaction, displayInfo.logicalWidth, displayInfo.logicalHeight,
Craig Mautnerd87946b2012-03-29 18:00:19 -07009582 mDisplay.getRotation());
Dianne Hackborna1111872010-11-23 20:55:11 -08009583 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009584 }
Romain Guy06882f82009-06-10 13:36:04 -07009585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009586 private void stopFreezingDisplayLocked() {
9587 if (!mDisplayFrozen) {
9588 return;
9589 }
Romain Guy06882f82009-06-10 13:36:04 -07009590
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009591 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
Craig Mautnerd87946b2012-03-29 18:00:19 -07009592 if (DEBUG_ORIENTATION) Slog.d(TAG,
9593 "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + mWaitingForConfig
9594 + ", mAppsFreezingScreen=" + mAppsFreezingScreen
9595 + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009596 return;
9597 }
9598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009599 mDisplayFrozen = false;
9600 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
9601 if (PROFILE_ORIENTATION) {
9602 Debug.stopMethodTracing();
9603 }
Dianne Hackborna1111872010-11-23 20:55:11 -08009604
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009605 boolean updateRotation = false;
Craig Mautner59c00972012-07-30 12:10:24 -07009606
Craig Mautner764983d2012-03-22 11:37:36 -07009607 if (CUSTOM_SCREEN_ROTATION && mAnimator.mScreenRotationAnimation != null
9608 && mAnimator.mScreenRotationAnimation.hasScreenshot()) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07009609 if (DEBUG_ORIENTATION) Slog.i(TAG, "**** Dismissing screen rotation animation");
Craig Mautner59c00972012-07-30 12:10:24 -07009610 // TODO(multidisplay): rotation on main screen only.
9611 DisplayInfo displayInfo = getDefaultDisplayContent().getDisplayInfo();
Craig Mautner764983d2012-03-22 11:37:36 -07009612 if (mAnimator.mScreenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
Craig Mautner59c00972012-07-30 12:10:24 -07009613 mTransitionAnimationScale, displayInfo.logicalWidth,
9614 displayInfo.logicalHeight)) {
Craig Mautner711f90a2012-07-03 18:43:52 -07009615 updateLayoutToAnimationLocked();
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009616 } else {
Craig Mautner7d8df392012-04-06 15:26:23 -07009617 mAnimator.mScreenRotationAnimation.kill();
Craig Mautner764983d2012-03-22 11:37:36 -07009618 mAnimator.mScreenRotationAnimation = null;
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009619 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -08009620 }
9621 } else {
Craig Mautner764983d2012-03-22 11:37:36 -07009622 if (mAnimator.mScreenRotationAnimation != null) {
9623 mAnimator.mScreenRotationAnimation.kill();
9624 mAnimator.mScreenRotationAnimation = null;
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009625 }
9626 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -08009627 }
Romain Guy06882f82009-06-10 13:36:04 -07009628
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009629 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009630
Dianne Hackborn420829e2011-01-28 11:30:35 -08009631 boolean configChanged;
9632
Christopher Tateb696aee2010-04-02 19:08:30 -07009633 // While the display is frozen we don't re-compute the orientation
9634 // to avoid inconsistent states. However, something interesting
9635 // could have actually changed during that time so re-evaluate it
9636 // now to catch that.
Dianne Hackborn420829e2011-01-28 11:30:35 -08009637 configChanged = updateOrientationFromAppTokensLocked(false);
Christopher Tateb696aee2010-04-02 19:08:30 -07009638
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009639 // A little kludge: a lot could have happened while the
9640 // display was frozen, so now that we are coming back we
9641 // do a gc so that any remote references the system
9642 // processes holds on others can be released if they are
9643 // no longer needed.
9644 mH.removeMessages(H.FORCE_GC);
9645 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
9646 2000);
Romain Guy06882f82009-06-10 13:36:04 -07009647
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009648 mScreenFrozenLock.release();
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009649
9650 if (updateRotation) {
9651 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Jeff Brown01a98dd2011-09-20 15:08:29 -07009652 configChanged |= updateRotationUncheckedLocked(false);
Dianne Hackborn420829e2011-01-28 11:30:35 -08009653 }
9654
9655 if (configChanged) {
9656 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009657 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009658 }
Romain Guy06882f82009-06-10 13:36:04 -07009659
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07009660 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
9661 DisplayMetrics dm) {
9662 if (index < tokens.length) {
9663 String str = tokens[index];
9664 if (str != null && str.length() > 0) {
9665 try {
9666 int val = Integer.parseInt(str);
9667 return val;
9668 } catch (Exception e) {
9669 }
9670 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009671 }
9672 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
9673 return defDps;
9674 }
9675 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
9676 return val;
9677 }
9678
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009679 void createWatermark() {
9680 if (mWatermark != null) {
9681 return;
9682 }
9683
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07009684 File file = new File("/system/etc/setup.conf");
9685 FileInputStream in = null;
9686 try {
9687 in = new FileInputStream(file);
9688 DataInputStream ind = new DataInputStream(in);
9689 String line = ind.readLine();
9690 if (line != null) {
9691 String[] toks = line.split("%");
9692 if (toks != null && toks.length > 0) {
Jeff Brownbc68a592011-07-25 12:58:12 -07009693 mWatermark = new Watermark(mRealDisplayMetrics, mFxSession, toks);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07009694 }
9695 }
9696 } catch (FileNotFoundException e) {
9697 } catch (IOException e) {
9698 } finally {
9699 if (in != null) {
9700 try {
9701 in.close();
9702 } catch (IOException e) {
9703 }
9704 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009705 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009706 }
9707
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009708 @Override
Joe Onorato664644d2011-01-23 17:53:23 -08009709 public void statusBarVisibilityChanged(int visibility) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07009710 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
9711 != PackageManager.PERMISSION_GRANTED) {
9712 throw new SecurityException("Caller does not hold permission "
9713 + android.Manifest.permission.STATUS_BAR);
9714 }
Dianne Hackborn9a230e02011-10-06 11:51:27 -07009715
Joe Onorato664644d2011-01-23 17:53:23 -08009716 synchronized (mWindowMap) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07009717 mLastStatusBarVisibility = visibility;
9718 visibility = mPolicy.adjustSystemUiVisibilityLw(visibility);
9719 updateStatusBarVisibilityLocked(visibility);
9720 }
9721 }
9722
Craig Mautner59c00972012-07-30 12:10:24 -07009723 // TOOD(multidisplay): StatusBar on multiple screens?
Dianne Hackborndf89e652011-10-06 22:35:11 -07009724 void updateStatusBarVisibilityLocked(int visibility) {
9725 mInputManager.setSystemUiVisibility(visibility);
Craig Mautner59c00972012-07-30 12:10:24 -07009726 final WindowList windows = getDefaultWindowList();
9727 final int N = windows.size();
Dianne Hackborndf89e652011-10-06 22:35:11 -07009728 for (int i = 0; i < N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07009729 WindowState ws = windows.get(i);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009730 try {
9731 int curValue = ws.mSystemUiVisibility;
9732 int diff = curValue ^ visibility;
9733 // We are only interested in differences of one of the
9734 // clearable flags...
9735 diff &= View.SYSTEM_UI_CLEARABLE_FLAGS;
9736 // ...if it has actually been cleared.
9737 diff &= ~visibility;
9738 int newValue = (curValue&~diff) | (visibility&diff);
9739 if (newValue != curValue) {
9740 ws.mSeq++;
9741 ws.mSystemUiVisibility = newValue;
9742 }
9743 if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) {
9744 ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq,
9745 visibility, newValue, diff);
9746 }
9747 } catch (RemoteException e) {
9748 // so sorry
9749 }
9750 }
9751 }
9752
9753 @Override
9754 public void reevaluateStatusBarVisibility() {
9755 synchronized (mWindowMap) {
9756 int visibility = mPolicy.adjustSystemUiVisibilityLw(mLastStatusBarVisibility);
9757 updateStatusBarVisibilityLocked(visibility);
9758 performLayoutAndPlaceSurfacesLocked();
9759 }
9760 }
9761
9762 @Override
Jeff Brown32cbc38552011-12-01 14:01:49 -08009763 public FakeWindow addFakeWindow(Looper looper,
9764 InputEventReceiver.Factory inputEventReceiverFactory,
Dianne Hackborndf89e652011-10-06 22:35:11 -07009765 String name, int windowType, int layoutParamsFlags, boolean canReceiveKeys,
9766 boolean hasFocus, boolean touchFullscreen) {
9767 synchronized (mWindowMap) {
Jeff Brown32cbc38552011-12-01 14:01:49 -08009768 FakeWindowImpl fw = new FakeWindowImpl(this, looper, inputEventReceiverFactory,
9769 name, windowType,
Dianne Hackborndf89e652011-10-06 22:35:11 -07009770 layoutParamsFlags, canReceiveKeys, hasFocus, touchFullscreen);
9771 int i=0;
9772 while (i<mFakeWindows.size()) {
9773 if (mFakeWindows.get(i).mWindowLayer <= fw.mWindowLayer) {
9774 break;
Joe Onorato664644d2011-01-23 17:53:23 -08009775 }
9776 }
Dianne Hackborndf89e652011-10-06 22:35:11 -07009777 mFakeWindows.add(i, fw);
9778 mInputMonitor.updateInputWindowsLw(true);
9779 return fw;
9780 }
9781 }
9782
9783 boolean removeFakeWindowLocked(FakeWindow window) {
9784 synchronized (mWindowMap) {
9785 if (mFakeWindows.remove(window)) {
9786 mInputMonitor.updateInputWindowsLw(true);
9787 return true;
9788 }
9789 return false;
Joe Onorato664644d2011-01-23 17:53:23 -08009790 }
9791 }
9792
satoke0a99412012-05-10 02:22:58 +09009793 // It is assumed that this method is called only by InputMethodManagerService.
9794 public void saveLastInputMethodWindowForTransition() {
9795 synchronized (mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -07009796 // TODO(multidisplay): Pass in the displayID.
9797 DisplayContent displayContent = getDefaultDisplayContent();
satoke0a99412012-05-10 02:22:58 +09009798 if (mInputMethodWindow != null) {
9799 mPolicy.setLastInputMethodWindowLw(mInputMethodWindow, mInputMethodTarget);
9800 }
9801 }
9802 }
9803
Daniel Sandler0c4ccff2011-10-19 16:39:14 -04009804 @Override
9805 public boolean hasNavigationBar() {
9806 return mPolicy.hasNavigationBar();
9807 }
9808
Jim Miller93c518e2012-01-17 15:55:31 -08009809 public void lockNow() {
9810 mPolicy.lockNow();
9811 }
9812
Jeff Brownd7a04de2012-06-17 14:17:52 -07009813 void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009814 pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
Jeff Brownd7a04de2012-06-17 14:17:52 -07009815 mPolicy.dump(" ", pw, args);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009816 }
9817
Jeff Brownd7a04de2012-06-17 14:17:52 -07009818 void dumpTokensLocked(PrintWriter pw, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009819 pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
9820 if (mTokenMap.size() > 0) {
9821 pw.println(" All tokens:");
9822 Iterator<WindowToken> it = mTokenMap.values().iterator();
9823 while (it.hasNext()) {
9824 WindowToken token = it.next();
9825 pw.print(" Token "); pw.print(token.token);
9826 if (dumpAll) {
9827 pw.println(':');
9828 token.dump(pw, " ");
9829 } else {
9830 pw.println();
9831 }
9832 }
9833 }
9834 if (mWallpaperTokens.size() > 0) {
9835 pw.println();
9836 pw.println(" Wallpaper tokens:");
9837 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
9838 WindowToken token = mWallpaperTokens.get(i);
9839 pw.print(" Wallpaper #"); pw.print(i);
9840 pw.print(' '); pw.print(token);
9841 if (dumpAll) {
9842 pw.println(':');
9843 token.dump(pw, " ");
9844 } else {
9845 pw.println();
9846 }
9847 }
9848 }
9849 if (mAppTokens.size() > 0) {
9850 pw.println();
9851 pw.println(" Application tokens in Z order:");
9852 for (int i=mAppTokens.size()-1; i>=0; i--) {
Craig Mautnerdbb79912012-03-01 18:59:14 -08009853 pw.print(" App #"); pw.print(i); pw.println(": ");
9854 mAppTokens.get(i).dump(pw, " ");
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009855 }
9856 }
9857 if (mFinishedStarting.size() > 0) {
9858 pw.println();
9859 pw.println(" Finishing start of application tokens:");
9860 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
9861 WindowToken token = mFinishedStarting.get(i);
9862 pw.print(" Finished Starting #"); pw.print(i);
9863 pw.print(' '); pw.print(token);
9864 if (dumpAll) {
9865 pw.println(':');
9866 token.dump(pw, " ");
9867 } else {
9868 pw.println();
9869 }
9870 }
9871 }
9872 if (mExitingTokens.size() > 0) {
9873 pw.println();
9874 pw.println(" Exiting tokens:");
9875 for (int i=mExitingTokens.size()-1; i>=0; i--) {
9876 WindowToken token = mExitingTokens.get(i);
9877 pw.print(" Exiting #"); pw.print(i);
9878 pw.print(' '); pw.print(token);
9879 if (dumpAll) {
9880 pw.println(':');
9881 token.dump(pw, " ");
9882 } else {
9883 pw.println();
9884 }
9885 }
9886 }
9887 if (mExitingAppTokens.size() > 0) {
9888 pw.println();
9889 pw.println(" Exiting application tokens:");
9890 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
9891 WindowToken token = mExitingAppTokens.get(i);
9892 pw.print(" Exiting App #"); pw.print(i);
9893 pw.print(' '); pw.print(token);
9894 if (dumpAll) {
9895 pw.println(':');
9896 token.dump(pw, " ");
9897 } else {
9898 pw.println();
9899 }
9900 }
9901 }
Craig Mautneref25d7a2012-05-15 23:01:47 -07009902 if (mAppTransitionRunning && mAnimatingAppTokens.size() > 0) {
9903 pw.println();
9904 pw.println(" Application tokens during animation:");
9905 for (int i=mAnimatingAppTokens.size()-1; i>=0; i--) {
9906 WindowToken token = mAnimatingAppTokens.get(i);
9907 pw.print(" App moving to bottom #"); pw.print(i);
9908 pw.print(' '); pw.print(token);
9909 if (dumpAll) {
9910 pw.println(':');
9911 token.dump(pw, " ");
9912 } else {
9913 pw.println();
9914 }
9915 }
9916 }
Dianne Hackborn6e2281d2012-06-19 17:48:32 -07009917 if (mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
9918 pw.println();
9919 if (mOpeningApps.size() > 0) {
9920 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
9921 }
9922 if (mClosingApps.size() > 0) {
9923 pw.print(" mClosingApps="); pw.println(mClosingApps);
9924 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009925 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009926 }
9927
Jeff Brownd7a04de2012-06-17 14:17:52 -07009928 void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009929 pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
9930 if (mSessions.size() > 0) {
9931 Iterator<Session> it = mSessions.iterator();
9932 while (it.hasNext()) {
9933 Session s = it.next();
9934 pw.print(" Session "); pw.print(s); pw.println(':');
9935 s.dump(pw, " ");
9936 }
9937 }
9938 }
9939
Jeff Brownd7a04de2012-06-17 14:17:52 -07009940 void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009941 ArrayList<WindowState> windows) {
9942 pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)");
Jeff Brownd7a04de2012-06-17 14:17:52 -07009943 dumpWindowsNoHeaderLocked(pw, dumpAll, windows);
9944 }
9945
9946 void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll,
9947 ArrayList<WindowState> windows) {
Craig Mautner59c00972012-07-30 12:10:24 -07009948 int j = 0;
9949 final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
9950 while (iterator.hasNext()) {
9951 final WindowState w = iterator.next();
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009952 if (windows == null || windows.contains(w)) {
Craig Mautner59c00972012-07-30 12:10:24 -07009953 pw.print(" Window #"); pw.print(j++); pw.print(' ');
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009954 pw.print(w); pw.println(":");
Dianne Hackborn89620282011-09-11 12:47:45 -07009955 w.dump(pw, " ", dumpAll || windows != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009956 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009957 }
9958 if (mInputMethodDialogs.size() > 0) {
9959 pw.println();
9960 pw.println(" Input method dialogs:");
9961 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
9962 WindowState w = mInputMethodDialogs.get(i);
9963 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009964 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009965 }
9966 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009967 }
9968 if (mPendingRemove.size() > 0) {
9969 pw.println();
9970 pw.println(" Remove pending for:");
9971 for (int i=mPendingRemove.size()-1; i>=0; i--) {
9972 WindowState w = mPendingRemove.get(i);
9973 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009974 pw.print(" Remove #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009975 pw.print(w);
9976 if (dumpAll) {
9977 pw.println(":");
9978 w.dump(pw, " ", true);
9979 } else {
9980 pw.println();
9981 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009982 }
9983 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009984 }
9985 if (mForceRemoves != null && mForceRemoves.size() > 0) {
9986 pw.println();
9987 pw.println(" Windows force removing:");
9988 for (int i=mForceRemoves.size()-1; i>=0; i--) {
9989 WindowState w = mForceRemoves.get(i);
9990 pw.print(" Removing #"); pw.print(i); pw.print(' ');
9991 pw.print(w);
9992 if (dumpAll) {
9993 pw.println(":");
9994 w.dump(pw, " ", true);
9995 } else {
9996 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009997 }
9998 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009999 }
10000 if (mDestroySurface.size() > 0) {
10001 pw.println();
10002 pw.println(" Windows waiting to destroy their surface:");
10003 for (int i=mDestroySurface.size()-1; i>=0; i--) {
10004 WindowState w = mDestroySurface.get(i);
10005 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010006 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010007 pw.print(w);
10008 if (dumpAll) {
10009 pw.println(":");
10010 w.dump(pw, " ", true);
10011 } else {
10012 pw.println();
10013 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010014 }
10015 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010016 }
10017 if (mLosingFocus.size() > 0) {
10018 pw.println();
10019 pw.println(" Windows losing focus:");
10020 for (int i=mLosingFocus.size()-1; i>=0; i--) {
10021 WindowState w = mLosingFocus.get(i);
10022 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010023 pw.print(" Losing #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010024 pw.print(w);
10025 if (dumpAll) {
10026 pw.println(":");
10027 w.dump(pw, " ", true);
10028 } else {
10029 pw.println();
10030 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010031 }
10032 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010033 }
10034 if (mResizingWindows.size() > 0) {
10035 pw.println();
10036 pw.println(" Windows waiting to resize:");
10037 for (int i=mResizingWindows.size()-1; i>=0; i--) {
10038 WindowState w = mResizingWindows.get(i);
10039 if (windows == null || windows.contains(w)) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010040 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010041 pw.print(w);
10042 if (dumpAll) {
10043 pw.println(":");
10044 w.dump(pw, " ", true);
10045 } else {
10046 pw.println();
10047 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010048 }
10049 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010050 }
Dianne Hackborn38e29a62011-09-18 14:43:08 -070010051 if (mWaitingForDrawn.size() > 0) {
10052 pw.println();
10053 pw.println(" Clients waiting for these windows to be drawn:");
10054 for (int i=mWaitingForDrawn.size()-1; i>=0; i--) {
10055 Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(i);
10056 pw.print(" Waiting #"); pw.print(i); pw.print(' '); pw.print(pair.first);
10057 pw.print(": "); pw.println(pair.second);
10058 }
10059 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010060 pw.println();
10061 if (mDisplay != null) {
Craig Mautner59c00972012-07-30 12:10:24 -070010062 DisplayContentsIterator dCIterator = new DisplayContentsIterator();
10063 while (dCIterator.hasNext()) {
10064 dCIterator.next().dump(pw);
10065 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010066 } else {
10067 pw.println(" NO DISPLAY");
10068 }
10069 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
10070 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
10071 if (mLastFocus != mCurrentFocus) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010072 pw.print(" mLastFocus="); pw.println(mLastFocus);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010073 }
10074 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
10075 if (mInputMethodTarget != null) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010076 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010077 }
10078 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
10079 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
10080 if (dumpAll) {
Dianne Hackborn85afd1b2012-05-13 13:31:06 -070010081 pw.print(" mSystemDecorRect="); pw.print(mSystemDecorRect.toShortString());
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070010082 pw.print(" mSystemDecorLayer="); pw.print(mSystemDecorLayer);
10083 pw.print(" mScreenRecr="); pw.println(mScreenRect.toShortString());
Dianne Hackborndf89e652011-10-06 22:35:11 -070010084 if (mLastStatusBarVisibility != 0) {
10085 pw.print(" mLastStatusBarVisibility=0x");
10086 pw.println(Integer.toHexString(mLastStatusBarVisibility));
10087 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010088 if (mInputMethodWindow != null) {
10089 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
10090 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -070010091 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -070010092 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
10093 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
10094 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
10095 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010096 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
10097 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
10098 if (mInputMethodAnimLayerAdjustment != 0 ||
10099 mWallpaperAnimLayerAdjustment != 0) {
10100 pw.print(" mInputMethodAnimLayerAdjustment=");
10101 pw.print(mInputMethodAnimLayerAdjustment);
10102 pw.print(" mWallpaperAnimLayerAdjustment=");
10103 pw.println(mWallpaperAnimLayerAdjustment);
10104 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010105 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
10106 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
Craig Mautner6fbda632012-07-03 09:26:39 -070010107 pw.print(" mLayoutNeeded="); pw.print(mLayoutNeeded);
10108 pw.print("mTransactionSequence="); pw.println(mTransactionSequence);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010109 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
10110 pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010111 pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
10112 pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010113 pw.print(" mRotation="); pw.print(mRotation);
Dianne Hackborndacea8c2011-04-21 17:26:39 -070010114 pw.print(" mAltOrientation="); pw.println(mAltOrientation);
Craig Mautnerf20588f2012-04-11 17:06:21 -070010115 pw.print(" mLastWindowForcedOrientation="); pw.print(mLastWindowForcedOrientation);
Dianne Hackbornbc7386c2011-06-06 17:27:54 -070010116 pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation);
Jeff Brown01a98dd2011-09-20 15:08:29 -070010117 pw.print(" mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
Craig Mautner764983d2012-03-22 11:37:36 -070010118 if (mAnimator.mScreenRotationAnimation != null) {
Dianne Hackborn4dcece82012-02-10 14:50:32 -080010119 pw.println(" mScreenRotationAnimation:");
Craig Mautner764983d2012-03-22 11:37:36 -070010120 mAnimator.mScreenRotationAnimation.printTo(" ", pw);
Dianne Hackborn4dcece82012-02-10 14:50:32 -080010121 }
10122 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
10123 pw.print(" mTransitionWindowAnimationScale="); pw.print(mTransitionAnimationScale);
Chet Haasec38fa1f2012-02-01 16:37:46 -080010124 pw.print(" mAnimatorDurationScale="); pw.println(mAnimatorDurationScale);
Dianne Hackborn4dcece82012-02-10 14:50:32 -080010125 pw.print(" mTraversalScheduled="); pw.print(mTraversalScheduled);
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010126 pw.print(" mNextAppTransition=0x");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010127 pw.print(Integer.toHexString(mNextAppTransition));
Dianne Hackborn9d132642011-04-21 17:26:39 -070010128 pw.print(" mAppTransitionReady="); pw.println(mAppTransitionReady);
10129 pw.print(" mAppTransitionRunning="); pw.print(mAppTransitionRunning);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010130 pw.print(" mAppTransitionTimeout="); pw.println(mAppTransitionTimeout);
10131 if (mNextAppTransitionType != ActivityOptions.ANIM_NONE) {
10132 pw.print(" mNextAppTransitionType="); pw.println(mNextAppTransitionType);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010133 }
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010134 switch (mNextAppTransitionType) {
10135 case ActivityOptions.ANIM_CUSTOM:
10136 pw.print(" mNextAppTransitionPackage=");
Dianne Hackborn84375872012-06-01 19:03:50 -070010137 pw.println(mNextAppTransitionPackage);
10138 pw.print(" mNextAppTransitionEnter=0x");
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010139 pw.print(Integer.toHexString(mNextAppTransitionEnter));
10140 pw.print(" mNextAppTransitionExit=0x");
Dianne Hackborn84375872012-06-01 19:03:50 -070010141 pw.println(Integer.toHexString(mNextAppTransitionExit));
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010142 break;
10143 case ActivityOptions.ANIM_SCALE_UP:
10144 pw.print(" mNextAppTransitionStartX="); pw.print(mNextAppTransitionStartX);
10145 pw.print(" mNextAppTransitionStartY=");
10146 pw.println(mNextAppTransitionStartY);
10147 pw.print(" mNextAppTransitionStartWidth=");
10148 pw.print(mNextAppTransitionStartWidth);
10149 pw.print(" mNextAppTransitionStartHeight=");
10150 pw.println(mNextAppTransitionStartHeight);
10151 break;
10152 case ActivityOptions.ANIM_THUMBNAIL:
Michael Jurka21385cd2012-05-03 10:57:31 -070010153 case ActivityOptions.ANIM_THUMBNAIL_DELAYED:
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010154 pw.print(" mNextAppTransitionThumbnail=");
10155 pw.print(mNextAppTransitionThumbnail);
Dianne Hackborn84375872012-06-01 19:03:50 -070010156 pw.print(" mNextAppTransitionStartX=");
10157 pw.print(mNextAppTransitionStartX);
10158 pw.print(" mNextAppTransitionStartY=");
10159 pw.println(mNextAppTransitionStartY);
10160 pw.print(" mNextAppTransitionDelayed="); pw.println(mNextAppTransitionDelayed);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010161 break;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070010162 }
Dianne Hackborn84375872012-06-01 19:03:50 -070010163 if (mNextAppTransitionCallback != null) {
10164 pw.print(" mNextAppTransitionCallback=");
10165 pw.println(mNextAppTransitionCallback);
10166 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010167 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010168 pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Craig Mautner6fbda632012-07-03 09:26:39 -070010169 pw.println(" Window Animator:");
10170 mAnimator.dump(pw, " ", dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010171 }
10172 }
10173
Jeff Brownd7a04de2012-06-17 14:17:52 -070010174 boolean dumpWindows(PrintWriter pw, String name, String[] args,
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010175 int opti, boolean dumpAll) {
10176 ArrayList<WindowState> windows = new ArrayList<WindowState>();
10177 if ("visible".equals(name)) {
10178 synchronized(mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -070010179 final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
10180 while (iterator.hasNext()) {
10181 final WindowState w = iterator.next();
Craig Mautnerc2f9be02012-03-27 17:32:29 -070010182 if (w.mWinAnimator.mSurfaceShown) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010183 windows.add(w);
10184 }
10185 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010186 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010187 } else {
10188 int objectId = 0;
10189 // See if this is an object ID.
10190 try {
10191 objectId = Integer.parseInt(name, 16);
10192 name = null;
10193 } catch (RuntimeException e) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010194 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010195 synchronized(mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -070010196 final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
10197 while (iterator.hasNext()) {
10198 final WindowState w = iterator.next();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010199 if (name != null) {
10200 if (w.mAttrs.getTitle().toString().contains(name)) {
10201 windows.add(w);
10202 }
10203 } else if (System.identityHashCode(w) == objectId) {
10204 windows.add(w);
10205 }
10206 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010207 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010208 }
10209
10210 if (windows.size() <= 0) {
10211 return false;
10212 }
10213
10214 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010215 dumpWindowsLocked(pw, dumpAll, windows);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010216 }
10217 return true;
10218 }
10219
Jeff Brownd7a04de2012-06-17 14:17:52 -070010220 void dumpLastANRLocked(PrintWriter pw) {
10221 pw.println("WINDOW MANAGER LAST ANR (dumpsys window lastanr)");
10222 if (mLastANRState == null) {
10223 pw.println(" <no ANR has occurred since boot>");
10224 } else {
10225 pw.println(mLastANRState);
10226 }
10227 }
10228
10229 /**
10230 * Saves information about the state of the window manager at
10231 * the time an ANR occurred before anything else in the system changes
10232 * in response.
10233 *
Jeff Brownee172412012-06-18 12:58:03 -070010234 * @param appWindowToken The application that ANR'd, may be null.
Jeff Brownd7a04de2012-06-17 14:17:52 -070010235 * @param windowState The window that ANR'd, may be null.
10236 */
10237 public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState) {
10238 StringWriter sw = new StringWriter();
10239 PrintWriter pw = new PrintWriter(sw);
10240 pw.println(" ANR time: " + DateFormat.getInstance().format(new Date()));
Jeff Brownee172412012-06-18 12:58:03 -070010241 if (appWindowToken != null) {
10242 pw.println(" Application at fault: " + appWindowToken.stringName);
10243 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010244 if (windowState != null) {
10245 pw.println(" Window at fault: " + windowState.mAttrs.getTitle());
10246 }
10247 pw.println();
10248 dumpWindowsNoHeaderLocked(pw, true, null);
10249 pw.close();
10250 mLastANRState = sw.toString();
10251 }
10252
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010253 @Override
10254 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10255 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
10256 != PackageManager.PERMISSION_GRANTED) {
10257 pw.println("Permission Denial: can't dump WindowManager from from pid="
10258 + Binder.getCallingPid()
10259 + ", uid=" + Binder.getCallingUid());
10260 return;
10261 }
10262
10263 boolean dumpAll = false;
10264
10265 int opti = 0;
10266 while (opti < args.length) {
10267 String opt = args[opti];
10268 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10269 break;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010270 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010271 opti++;
10272 if ("-a".equals(opt)) {
10273 dumpAll = true;
10274 } else if ("-h".equals(opt)) {
10275 pw.println("Window manager dump options:");
10276 pw.println(" [-a] [-h] [cmd] ...");
10277 pw.println(" cmd may be one of:");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010278 pw.println(" l[astanr]: last ANR information");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010279 pw.println(" p[policy]: policy state");
10280 pw.println(" s[essions]: active sessions");
10281 pw.println(" t[okens]: token list");
10282 pw.println(" w[indows]: window list");
10283 pw.println(" cmd may also be a NAME to dump windows. NAME may");
10284 pw.println(" be a partial substring in a window name, a");
10285 pw.println(" Window hex object identifier, or");
10286 pw.println(" \"all\" for all windows, or");
10287 pw.println(" \"visible\" for the visible windows.");
10288 pw.println(" -a: include all available server state.");
10289 return;
Dianne Hackborn87fc3082010-12-03 13:09:12 -080010290 } else {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010291 pw.println("Unknown argument: " + opt + "; use -h for help");
Dianne Hackborn87fc3082010-12-03 13:09:12 -080010292 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010293 }
10294
10295 // Is the caller requesting to dump a particular piece of data?
10296 if (opti < args.length) {
10297 String cmd = args[opti];
10298 opti++;
Jeff Brownd7a04de2012-06-17 14:17:52 -070010299 if ("lastanr".equals(cmd) || "l".equals(cmd)) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010300 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010301 dumpLastANRLocked(pw);
10302 }
10303 return;
10304 } else if ("policy".equals(cmd) || "p".equals(cmd)) {
10305 synchronized(mWindowMap) {
10306 dumpPolicyLocked(pw, args, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010307 }
10308 return;
10309 } else if ("sessions".equals(cmd) || "s".equals(cmd)) {
10310 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010311 dumpSessionsLocked(pw, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010312 }
10313 return;
10314 } else if ("tokens".equals(cmd) || "t".equals(cmd)) {
10315 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010316 dumpTokensLocked(pw, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010317 }
10318 return;
10319 } else if ("windows".equals(cmd) || "w".equals(cmd)) {
10320 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010321 dumpWindowsLocked(pw, true, null);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010322 }
10323 return;
10324 } else if ("all".equals(cmd) || "a".equals(cmd)) {
10325 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010326 dumpWindowsLocked(pw, true, null);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010327 }
10328 return;
10329 } else {
10330 // Dumping a single name?
Jeff Brownd7a04de2012-06-17 14:17:52 -070010331 if (!dumpWindows(pw, cmd, args, opti, dumpAll)) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010332 pw.println("Bad window command, or no windows match: " + cmd);
10333 pw.println("Use -h for help.");
10334 }
10335 return;
10336 }
10337 }
10338
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010339 synchronized(mWindowMap) {
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010340 pw.println();
10341 if (dumpAll) {
10342 pw.println("-------------------------------------------------------------------------------");
10343 }
10344 dumpLastANRLocked(pw);
10345 pw.println();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010346 if (dumpAll) {
10347 pw.println("-------------------------------------------------------------------------------");
10348 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010349 dumpPolicyLocked(pw, args, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010350 pw.println();
10351 if (dumpAll) {
10352 pw.println("-------------------------------------------------------------------------------");
10353 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010354 dumpSessionsLocked(pw, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010355 pw.println();
10356 if (dumpAll) {
10357 pw.println("-------------------------------------------------------------------------------");
10358 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010359 dumpTokensLocked(pw, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010360 pw.println();
10361 if (dumpAll) {
10362 pw.println("-------------------------------------------------------------------------------");
10363 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010364 dumpWindowsLocked(pw, dumpAll, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010365 }
10366 }
10367
Jeff Brown349703e2010-06-22 01:27:15 -070010368 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010369 public void monitor() {
10370 synchronized (mWindowMap) { }
Mike Lockwood983ee092009-11-22 01:42:24 -050010371 synchronized (mKeyguardTokenWatcher) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070010372 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010373
Jeff Brown2992ea72011-01-28 22:04:14 -080010374 public interface OnHardKeyboardStatusChangeListener {
10375 public void onHardKeyboardStatusChange(boolean available, boolean enabled);
10376 }
Craig Mautnera2c77052012-03-26 12:14:43 -070010377
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070010378 void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
Craig Mautnercf8cbbe2012-03-25 21:54:36 -070010379 if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070010380 Slog.v(TAG, "Layouts looping: " + msg + ", mPendingLayoutChanges = 0x" +
10381 Integer.toHexString(pendingLayoutChanges));
Craig Mautnercf8cbbe2012-03-25 21:54:36 -070010382 }
10383 }
Craig Mautner59c00972012-07-30 12:10:24 -070010384
10385 public DisplayContent getDisplayContent(final int displayId) {
10386 DisplayContent displayContent = mDisplayContents.get(displayId);
10387 if (displayContent == null) {
Craig Mautner4f67ba62012-08-02 11:23:00 -070010388 displayContent = new DisplayContent(mDisplayManager, displayId);
Craig Mautner59c00972012-07-30 12:10:24 -070010389 mDisplayContents.put(displayId, displayContent);
10390 }
10391 return displayContent;
10392 }
10393
10394 class DisplayContentsIterator implements Iterator<DisplayContent> {
10395 private int cur;
10396
10397 @Override
10398 public boolean hasNext() {
10399 return cur < mDisplayContents.size();
10400 }
10401
10402 @Override
10403 public DisplayContent next() {
10404 if (hasNext()) {
10405 return mDisplayContents.valueAt(cur++);
10406 }
10407 throw new NoSuchElementException();
10408 }
10409
10410 @Override
10411 public void remove() {
10412 throw new IllegalArgumentException("AllDisplayContentIterator.remove not implemented");
10413 }
10414 }
10415
10416 boolean REVERSE_ITERATOR = true;
10417 class AllWindowsIterator implements Iterator<WindowState> {
10418 private DisplayContent mDisplayContent;
10419 private DisplayContentsIterator mDisplayContentsIterator;
10420 private WindowList mWindowList;
10421 private int mWindowListIndex;
10422 private boolean mReverse;
10423
10424 AllWindowsIterator() {
10425 mDisplayContentsIterator = new DisplayContentsIterator();
10426 mDisplayContent = mDisplayContentsIterator.next();
10427 mWindowList = mDisplayContent.getWindowList();
10428 }
10429
10430 AllWindowsIterator(boolean reverse) {
10431 this();
10432 mReverse = reverse;
10433 mWindowListIndex = reverse ? mWindowList.size() - 1 : 0;
10434 }
10435
10436 @Override
10437 public boolean hasNext() {
10438 if (mReverse) {
10439 return mWindowListIndex >= 0;
10440 }
10441 return mWindowListIndex < mWindowList.size();
10442 }
10443
10444 @Override
10445 public WindowState next() {
10446 if (hasNext()) {
10447 WindowState win = mWindowList.get(mWindowListIndex);
10448 if (mReverse) {
10449 mWindowListIndex--;
10450 if (mWindowListIndex < 0 && mDisplayContentsIterator.hasNext()) {
10451 mDisplayContent = mDisplayContentsIterator.next();
10452 mWindowList = mDisplayContent.getWindowList();
10453 mWindowListIndex = mWindowList.size() - 1;
10454 }
10455 } else {
10456 mWindowListIndex++;
10457 if (mWindowListIndex >= mWindowList.size() && mDisplayContentsIterator.hasNext()) {
10458 mDisplayContent = mDisplayContentsIterator.next();
10459 mWindowList = mDisplayContent.getWindowList();
10460 mWindowListIndex = 0;
10461 }
10462 }
10463 return win;
10464 }
10465 throw new NoSuchElementException();
10466 }
10467
10468 @Override
10469 public void remove() {
10470 throw new IllegalArgumentException("AllWindowsIterator.remove not implemented");
10471 }
10472 }
10473
10474 public DisplayContent getDefaultDisplayContent() {
10475 return getDisplayContent(Display.DEFAULT_DISPLAY);
10476 }
10477
10478 public WindowList getDefaultWindowList() {
10479 return getDefaultDisplayContent().getWindowList();
10480 }
10481
10482 public DisplayInfo getDefaultDisplayInfo() {
10483 return getDefaultDisplayContent().getDisplayInfo();
10484 }
10485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010486}