blob: d741d77822b611690f597ae22c653726cdbfbba7 [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
Craig Mautner9e4f28c2013-04-03 10:53:23 -070019import static android.view.WindowManager.LayoutParams.*;
20
21import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022
Craig Mautnerae446592012-12-06 19:05:05 -080023import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
24
Dianne Hackbornc2293022013-02-06 23:14:49 -080025import android.app.AppOpsManager;
Dianne Hackborna57c6952013-03-29 14:46:40 -070026import android.util.TimeUtils;
Dianne Hackborne3f23a32013-03-01 13:25:35 -080027import android.view.IWindowId;
Craig Mautner5eda9b32013-07-02 11:58:16 -070028
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import com.android.internal.app.IBatteryStats;
30import com.android.internal.policy.PolicyManager;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080031import com.android.internal.policy.impl.PhoneWindowManager;
Dianne Hackborn8c841092013-06-24 13:46:13 -070032import com.android.internal.util.FastPrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import com.android.internal.view.IInputContext;
34import com.android.internal.view.IInputMethodClient;
35import com.android.internal.view.IInputMethodManager;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080036import com.android.internal.view.WindowManagerPolicyThread;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080037import com.android.server.AttributeCache;
38import com.android.server.EventLogTags;
Dianne Hackborn8d044e82013-04-30 17:24:15 -070039import com.android.server.UiThread;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080040import com.android.server.Watchdog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import com.android.server.am.BatteryStatsService;
Jeff Brownfa25bf52012-07-23 19:26:30 -070042import com.android.server.display.DisplayManagerService;
Jeff Brown4532e612012-04-05 14:27:12 -070043import com.android.server.input.InputManagerService;
Jeff Brown4f8ecd82012-06-18 18:29:13 -070044import com.android.server.power.PowerManagerService;
45import com.android.server.power.ShutdownThread;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046
47import android.Manifest;
Craig Mautner5ff12102013-05-24 12:50:15 -070048import android.app.ActivityManager.StackBoxInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049import android.app.ActivityManagerNative;
50import android.app.IActivityManager;
Joe Onoratoac0ee892011-01-30 15:38:30 -080051import android.app.StatusBarManager;
Jim Millerd6b57052010-06-07 17:52:42 -070052import android.app.admin.DevicePolicyManager;
Jeff Brownff7e6ef2012-08-15 02:05:18 -070053import android.animation.ValueAnimator;
Jim Miller284b62e2010-06-08 14:27:42 -070054import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055import android.content.Context;
Jim Miller284b62e2010-06-08 14:27:42 -070056import android.content.Intent;
57import android.content.IntentFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import android.content.pm.ActivityInfo;
59import android.content.pm.PackageManager;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070060import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.content.res.Configuration;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080062import android.graphics.Bitmap;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070063import android.graphics.Canvas;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import android.graphics.Matrix;
65import android.graphics.PixelFormat;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -070066import android.graphics.Point;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import android.graphics.Rect;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070068import android.graphics.RectF;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069import android.graphics.Region;
Craig Mautnerb47bbc32012-08-22 17:41:48 -070070import android.hardware.display.DisplayManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071import android.os.Binder;
Dianne Hackborn75804932009-10-20 20:15:20 -070072import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.os.Debug;
74import android.os.Handler;
75import android.os.IBinder;
Dianne Hackborn38e29a62011-09-18 14:43:08 -070076import android.os.IRemoteCallback;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077import android.os.Looper;
78import android.os.Message;
79import android.os.Parcel;
80import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.os.PowerManager;
82import android.os.Process;
83import android.os.RemoteException;
84import android.os.ServiceManager;
Brad Fitzpatrickec062f62010-11-03 09:56:54 -070085import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086import android.os.SystemClock;
87import android.os.SystemProperties;
Dianne Hackborn1ded0b12012-04-26 14:14:50 -070088import android.os.Trace;
Craig Mautner259328c2012-08-21 19:30:58 -070089import android.os.WorkSource;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.provider.Settings;
Dianne Hackborn723738c2009-06-25 19:48:04 -070091import android.util.DisplayMetrics;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import android.util.EventLog;
Michael Jurka4accb6a2012-03-26 09:18:46 -070093import android.util.FloatMath;
Jim Millerd6b57052010-06-07 17:52:42 -070094import android.util.Log;
Craig Mautner59c00972012-07-30 12:10:24 -070095import android.util.SparseArray;
Dianne Hackborn38e29a62011-09-18 14:43:08 -070096import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -080097import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098import android.util.SparseIntArray;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070099import android.util.TypedValue;
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800100import android.view.Choreographer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101import android.view.Display;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700102import android.view.DisplayInfo;
Adam Powelldfee59a2011-08-05 20:48:30 -0700103import android.view.Gravity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104import android.view.IApplicationToken;
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -0700105import android.view.IInputFilter;
Svetoslav Ganov545252f2012-12-10 18:29:24 -0800106import android.view.IMagnificationCallbacks;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import android.view.IOnKeyguardExitResult;
108import android.view.IRotationWatcher;
109import android.view.IWindow;
110import android.view.IWindowManager;
111import android.view.IWindowSession;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700112import android.view.InputChannel;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700113import android.view.InputDevice;
Jeff Brownbbda99d2010-07-28 15:48:59 -0700114import android.view.InputEvent;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800115import android.view.InputEventReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116import android.view.KeyEvent;
Svetoslav Ganov545252f2012-12-10 18:29:24 -0800117import android.view.MagnificationSpec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118import android.view.MotionEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119import android.view.Surface;
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800120import android.view.SurfaceControl;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121import android.view.SurfaceSession;
122import android.view.View;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700123import android.view.ViewTreeObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124import android.view.WindowManager;
Jeff Brown98365d72012-08-19 20:30:52 -0700125import android.view.WindowManagerGlobal;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126import android.view.WindowManagerPolicy;
127import android.view.WindowManager.LayoutParams;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700128import android.view.WindowManagerPolicy.FakeWindow;
Craig Mautner037aa8d2013-06-07 10:35:44 -0700129import android.view.WindowManagerPolicy.PointerEventListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130import android.view.animation.Animation;
131import android.view.animation.AnimationUtils;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700132import android.view.animation.Transformation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133
134import java.io.BufferedWriter;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700135import java.io.DataInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136import java.io.File;
137import java.io.FileDescriptor;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700138import java.io.FileInputStream;
139import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140import java.io.IOException;
141import java.io.OutputStream;
142import java.io.OutputStreamWriter;
143import java.io.PrintWriter;
144import java.io.StringWriter;
145import java.net.Socket;
Jeff Brownd7a04de2012-06-17 14:17:52 -0700146import java.text.DateFormat;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147import java.util.ArrayList;
Jeff Brownd7a04de2012-06-17 14:17:52 -0700148import java.util.Date;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149import java.util.HashMap;
150import java.util.HashSet;
151import java.util.Iterator;
152import java.util.List;
153
154/** {@hide} */
Dianne Hackbornddca3ee2009-07-23 19:01:31 -0700155public class WindowManagerService extends IWindowManager.Stub
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700156 implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs,
Craig Mautner722285e2012-09-07 13:55:58 -0700157 DisplayManagerService.WindowManagerFuncs, DisplayManager.DisplayListener {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 static final String TAG = "WindowManager";
159 static final boolean DEBUG = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700160 static final boolean DEBUG_ADD_REMOVE = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800161 static final boolean DEBUG_FOCUS = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 static final boolean DEBUG_ANIM = false;
Dianne Hackborn9b52a212009-12-11 14:51:35 -0800163 static final boolean DEBUG_LAYOUT = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800164 static final boolean DEBUG_RESIZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 static final boolean DEBUG_LAYERS = false;
166 static final boolean DEBUG_INPUT = false;
167 static final boolean DEBUG_INPUT_METHOD = false;
168 static final boolean DEBUG_VISIBILITY = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700169 static final boolean DEBUG_WINDOW_MOVEMENT = false;
Craig Mautnerd9a22882013-03-16 15:00:36 -0700170 static final boolean DEBUG_TOKEN_MOVEMENT = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 static final boolean DEBUG_ORIENTATION = false;
Dianne Hackbornbc7386c2011-06-06 17:27:54 -0700172 static final boolean DEBUG_APP_ORIENTATION = false;
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700173 static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 static final boolean DEBUG_APP_TRANSITIONS = false;
175 static final boolean DEBUG_STARTING_WINDOW = false;
176 static final boolean DEBUG_REORDER = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800177 static final boolean DEBUG_WALLPAPER = false;
Dianne Hackborn98129732012-11-01 16:28:16 -0700178 static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER;
Christopher Tate994ef922011-01-12 20:06:07 -0800179 static final boolean DEBUG_DRAG = false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700180 static final boolean DEBUG_SCREEN_ON = false;
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -0700181 static final boolean DEBUG_SCREENSHOT = false;
Dianne Hackborn38cc8962011-10-13 11:33:55 -0700182 static final boolean DEBUG_BOOT = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700183 static final boolean DEBUG_LAYOUT_REPEATS = true;
Craig Mautner7358fbf2012-04-12 21:06:33 -0700184 static final boolean DEBUG_SURFACE_TRACE = false;
Craig Mautner7d8df392012-04-06 15:26:23 -0700185 static final boolean DEBUG_WINDOW_TRACE = false;
Craig Mautner926f3832013-02-13 11:56:07 -0800186 static final boolean DEBUG_TASK_MOVEMENT = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700187 static final boolean DEBUG_STACK = false;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700188 static final boolean SHOW_SURFACE_ALLOC = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800189 static final boolean SHOW_TRANSACTIONS = false;
Dianne Hackborn36991742011-10-11 21:35:26 -0700190 static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700191 static final boolean HIDE_STACK_CRAWLS = true;
Craig Mautnercf8cbbe2012-03-25 21:54:36 -0700192 static final int LAYOUT_REPEAT_THRESHOLD = 4;
Michael Chan53071d62009-05-13 17:29:48 -0700193
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800194 static final boolean PROFILE_ORIENTATION = false;
Dave Bortcfe65242009-04-09 14:51:04 -0700195 static final boolean localLOGV = DEBUG;
Romain Guy06882f82009-06-10 13:36:04 -0700196
Craig Mautner343ad712013-02-13 22:37:26 -0800197 final static boolean REVERSE_ITERATOR = true;
198 final static boolean FORWARD_ITERATOR = false;
199
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200 /** How much to multiply the policy's type layer, to reserve room
201 * for multiple windows of the same type and Z-ordering adjustment
202 * with TYPE_LAYER_OFFSET. */
203 static final int TYPE_LAYER_MULTIPLIER = 10000;
Romain Guy06882f82009-06-10 13:36:04 -0700204
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
206 * or below others in the same layer. */
207 static final int TYPE_LAYER_OFFSET = 1000;
Romain Guy06882f82009-06-10 13:36:04 -0700208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 /** How much to increment the layer for each window, to reserve room
210 * for effect surfaces between them.
211 */
212 static final int WINDOW_LAYER_MULTIPLIER = 5;
Romain Guy06882f82009-06-10 13:36:04 -0700213
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800214 /**
215 * Dim surface layer is immediately below target window.
216 */
217 static final int LAYER_OFFSET_DIM = 1;
218
219 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700220 * Blur surface layer is immediately below dim layer.
221 */
222 static final int LAYER_OFFSET_BLUR = 2;
223
224 /**
Craig Mautnerf7666462013-04-28 08:58:21 -0700225 * FocusedStackFrame layer is immediately above focused window.
226 */
227 static final int LAYER_OFFSET_FOCUSED_STACK = 1;
228
229 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700230 * Animation thumbnail is as far as possible below the window above
231 * the thumbnail (or in other words as far as possible above the window
232 * below it).
233 */
234 static final int LAYER_OFFSET_THUMBNAIL = WINDOW_LAYER_MULTIPLIER-1;
235
236 /**
Dianne Hackborn7916ac62011-05-16 20:45:48 -0700237 * Layer at which to put the rotation freeze snapshot.
238 */
239 static final int FREEZE_LAYER = (TYPE_LAYER_MULTIPLIER * 200) + 1;
240
241 /**
242 * Layer at which to put the mask for emulated screen sizes.
243 */
244 static final int MASK_LAYER = TYPE_LAYER_MULTIPLIER * 200;
245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246 /** The maximum length we will accept for a loaded animation duration:
247 * this is 10 seconds.
248 */
249 static final int MAX_ANIMATION_DURATION = 10*1000;
250
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700251 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
252 * compatible windows.
253 */
254 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
255
Craig Mautner7dfcb012012-10-10 10:24:47 -0700256 /** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */
Craig Mautnera4942c92012-10-16 09:06:53 -0700257 static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000;
Craig Mautner7dfcb012012-10-10 10:24:47 -0700258
Dianne Hackborna1111872010-11-23 20:55:11 -0800259 /**
260 * If true, the window manager will do its own custom freezing and general
261 * management of the screen during rotation.
262 */
263 static final boolean CUSTOM_SCREEN_ROTATION = true;
264
Jeff Brownb09abc12011-01-13 21:08:27 -0800265 // Maximum number of milliseconds to wait for input devices to be enumerated before
266 // proceding with safe mode detection.
267 private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
Jim Miller28637ba2011-07-06 19:57:05 -0700268
Jeff Brown349703e2010-06-22 01:27:15 -0700269 // Default input dispatching timeout in nanoseconds.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800270 static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
Romain Guy06882f82009-06-10 13:36:04 -0700271
Craig Mautner967212c2013-04-13 21:10:58 -0700272 /** Minimum value for createStack and resizeStack weight value */
273 public static final float STACK_WEIGHT_MIN = 0.2f;
274
275 /** Maximum value for createStack and resizeStack weight value */
276 public static final float STACK_WEIGHT_MAX = 0.8f;
277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278 static final int UPDATE_FOCUS_NORMAL = 0;
279 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
280 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
281 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700282
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800283 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700284 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285
Colin Crossef96fd92013-07-18 17:09:56 -0700286 private static final String DENSITY_OVERRIDE = "ro.config.density_override";
287 private static final String SIZE_OVERRIDE = "ro.config.size_override";
288
Craig Mautner24d887472013-03-20 15:40:36 -0700289 private static final int MAX_SCREENSHOT_RETRIES = 3;
290
Craig Mautner5642a482012-08-23 12:16:53 -0700291 final private KeyguardDisableHandler mKeyguardDisableHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700293 private final boolean mHeadless;
294
Jim Miller284b62e2010-06-08 14:27:42 -0700295 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
296 @Override
297 public void onReceive(Context context, Intent intent) {
Craig Mautner9dc52bc2012-08-06 14:15:42 -0700298 final String action = intent.getAction();
299 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
Craig Mautner5642a482012-08-23 12:16:53 -0700300 mKeyguardDisableHandler.sendEmptyMessage(
301 KeyguardDisableHandler.KEYGUARD_POLICY_CHANGED);
Jim Miller284b62e2010-06-08 14:27:42 -0700302 }
303 }
304 };
305
Craig Mautner9dc52bc2012-08-06 14:15:42 -0700306 // Current user when multi-user is enabled. Don't show windows of non-current user.
307 int mCurrentUserId;
308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 final Context mContext;
310
311 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700312
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700313 final boolean mAllowBootMessages;
314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
318
319 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700320
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800321 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700322
Dianne Hackbornc2293022013-02-06 23:14:49 -0800323 final AppOpsManager mAppOps;
324
Dianne Hackbornc652de82013-02-15 16:32:56 -0800325 final DisplaySettings mDisplaySettings;
326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 /**
328 * All currently active sessions with clients.
329 */
330 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700331
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800332 /**
333 * Mapping from an IWindow IBinder to the server's Window object.
334 * This is also used as the lock for all of our state.
Craig Mautner58106812012-12-28 12:27:40 -0800335 * NOTE: Never call into methods that lock ActivityManagerService while holding this object.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 */
337 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
338
339 /**
340 * Mapping from a token IBinder to a WindowToken object.
341 */
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800342 final HashMap<IBinder, WindowToken> mTokenMap = new HashMap<IBinder, WindowToken>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343
344 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800345 * List of window tokens that have finished starting their application,
346 * and now need to have the policy remove their windows.
347 */
348 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
349
350 /**
Dianne Hackborndf89e652011-10-06 22:35:11 -0700351 * Fake windows added to the window manager. Note: ordered from top to
352 * bottom, opposite of mWindows.
353 */
354 final ArrayList<FakeWindowImpl> mFakeWindows = new ArrayList<FakeWindowImpl>();
355
356 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357 * Windows that are being resized. Used so we can tell the client about
358 * the resize after closing the transaction in which we resized the
359 * underlying surface.
360 */
361 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
362
363 /**
364 * Windows whose animations have ended and now must be removed.
365 */
366 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
367
368 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800369 * Used when processing mPendingRemove to avoid working on the original array.
370 */
371 WindowState[] mPendingRemoveTmp = new WindowState[20];
372
373 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374 * Windows whose surface should be destroyed.
375 */
376 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
377
378 /**
379 * Windows that have lost input focus and are waiting for the new
380 * focus window to be displayed before they are told about this.
381 */
382 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
383
384 /**
385 * This is set when we have run out of memory, and will either be an empty
386 * list or contain windows that need to be force removed.
387 */
388 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700389
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800390 /**
Dianne Hackborn38e29a62011-09-18 14:43:08 -0700391 * Windows that clients are waiting to have drawn.
392 */
393 ArrayList<Pair<WindowState, IRemoteCallback>> mWaitingForDrawn
394 = new ArrayList<Pair<WindowState, IRemoteCallback>>();
395
396 /**
Dianne Hackborn12d3a942012-04-27 14:16:30 -0700397 * Windows that have called relayout() while we were running animations,
398 * so we need to tell when the animation is done.
399 */
400 final ArrayList<WindowState> mRelayoutWhileAnimating = new ArrayList<WindowState>();
401
402 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800403 * Used when rebuilding window list to keep track of windows that have
404 * been removed.
405 */
406 WindowState[] mRebuildTmp = new WindowState[20];
407
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700409
Svetoslav Ganov545252f2012-12-10 18:29:24 -0800410 DisplayMagnifier mDisplayMagnifier;
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -0700411
Craig Mautner7358fbf2012-04-12 21:06:33 -0700412 final SurfaceSession mFxSession;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700413 Watermark mWatermark;
Brad Fitzpatrick68044332010-11-22 18:19:48 -0800414 StrictModeFlash mStrictModeFlash;
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700415 FocusedStackFrame mFocusedStackFrame;
Romain Guy06882f82009-06-10 13:36:04 -0700416
Craig Mautnerf7666462013-04-28 08:58:21 -0700417 int mFocusedStackLayer;
418
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 final float[] mTmpFloats = new float[9];
420
Jeff Browne215f262012-09-10 16:01:14 -0700421 boolean mDisplayReady;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422 boolean mSafeMode;
423 boolean mDisplayEnabled = false;
424 boolean mSystemBooted = false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700425 boolean mForceDisplayEnabled = false;
Dianne Hackborn661cd522011-08-22 00:26:20 -0700426 boolean mShowingBootMessages = false;
Dianne Hackborn1fbee792011-11-30 11:29:58 -0800427
Jeff Brownd7a04de2012-06-17 14:17:52 -0700428 String mLastANRState;
429
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800430 /** All DisplayContents in the world, kept here */
Craig Mautnerf8924152013-07-16 09:10:55 -0700431 SparseArray<DisplayContent> mDisplayContents = new SparseArray<DisplayContent>(2);
Craig Mautner343ad712013-02-13 22:37:26 -0800432
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800433 int mRotation = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800434 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborndacea8c2011-04-21 17:26:39 -0700435 boolean mAltOrientation = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800436 ArrayList<IRotationWatcher> mRotationWatchers
437 = new ArrayList<IRotationWatcher>();
Jeff Brown01a98dd2011-09-20 15:08:29 -0700438 int mDeferredRotationPauseCount;
Romain Guy06882f82009-06-10 13:36:04 -0700439
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700440 final Rect mSystemDecorRect = new Rect();
441 int mSystemDecorLayer = 0;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700442 final Rect mScreenRect = new Rect();
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700443
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800444 boolean mTraversalScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800445 boolean mDisplayFrozen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -0700446 long mDisplayFreezeTime = 0;
447 int mLastDisplayFreezeDuration = 0;
448 Object mLastFinishedFreezeSource = null;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800449 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450 boolean mWindowsFreezingScreen = false;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700451 boolean mClientFreezingScreen = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452 int mAppsFreezingScreen = 0;
Dianne Hackbornbc7386c2011-06-06 17:27:54 -0700453 int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800455 int mLayoutSeq = 0;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700456
457 int mLastStatusBarVisibility = 0;
458
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800459 // State while inside of layoutAndPlaceSurfacesLocked().
460 boolean mFocusMayChange;
Craig Mautner01cd0e72012-06-18 10:19:11 -0700461
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800462 Configuration mCurConfiguration = new Configuration();
Craig Mautner01cd0e72012-06-18 10:19:11 -0700463
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800464 // This is held as long as we have the screen frozen, to give us time to
465 // perform a rotation animation when turning off shows the lock screen which
466 // changes the orientation.
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800467 private PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700468
Craig Mautner164d4bb2012-11-26 13:51:23 -0800469 final AppTransition mAppTransition;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 boolean mStartingIconInTransition = false;
471 boolean mSkipAppTransitionAnimation = false;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800472
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
474 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700475
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700476 boolean mIsTouchDevice;
477
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700478 final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Jeff Brownbc68a592011-07-25 12:58:12 -0700479 final DisplayMetrics mRealDisplayMetrics = new DisplayMetrics();
Dianne Hackborn48a76512011-06-08 21:51:44 -0700480 final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics();
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700481 final DisplayMetrics mCompatDisplayMetrics = new DisplayMetrics();
482
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800483 final H mH = new H();
484
485 final Choreographer mChoreographer = Choreographer.getInstance();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486
487 WindowState mCurrentFocus = null;
488 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700489
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800490 /** This just indicates the window the input method is on top of, not
491 * necessarily the window its input is going to. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800492 WindowState mInputMethodTarget = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800493
494 /** If true hold off on modifying the animation layer of mInputMethodTarget */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 boolean mInputMethodTargetWaitingAnim;
496 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700497
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498 WindowState mInputMethodWindow = null;
499 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
500
Jeff Brown2992ea72011-01-28 22:04:14 -0800501 boolean mHardKeyboardAvailable;
502 boolean mHardKeyboardEnabled;
503 OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
504
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700505 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800506
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700507 // If non-null, this is the currently visible window that is associated
508 // with the wallpaper.
509 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700510 // If non-null, we are in the middle of animating from one wallpaper target
511 // to another, and this is the lower one in Z-order.
Dianne Hackborn98129732012-11-01 16:28:16 -0700512 WindowState mLowerWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700513 // If non-null, we are in the middle of animating from one wallpaper target
514 // to another, and this is the higher one in Z-order.
Craig Mautner96868332012-12-04 14:29:11 -0800515 WindowState mUpperWallpaperTarget = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700516 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700517 float mLastWallpaperX = -1;
518 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800519 float mLastWallpaperXStep = -1;
520 float mLastWallpaperYStep = -1;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700521 // This is set when we are waiting for a wallpaper to tell us it is done
522 // changing its scroll position.
523 WindowState mWaitingOnWallpaper;
524 // The last time we had a timeout when waiting for a wallpaper.
525 long mLastWallpaperTimeoutTime;
526 // We give a wallpaper up to 150ms to finish scrolling.
527 static final long WALLPAPER_TIMEOUT = 150;
528 // Time we wait after a timeout before trying to wait again.
529 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531 AppWindowToken mFocusedApp = null;
532
533 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535 float mWindowAnimationScale = 1.0f;
536 float mTransitionAnimationScale = 1.0f;
Chet Haasec38fa1f2012-02-01 16:37:46 -0800537 float mAnimatorDurationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700538
Jeff Brown4532e612012-04-05 14:27:12 -0700539 final InputManagerService mInputManager;
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700540 final DisplayManagerService mDisplayManagerService;
541 final DisplayManager mDisplayManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542
543 // Who is holding the screen on.
544 Session mHoldingScreenOn;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700545 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700546
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700547 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800548
Christopher Tatea53146c2010-09-07 11:57:52 -0700549 DragState mDragState = null;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800550
Craig Mautner3c174372013-02-21 17:54:37 -0800551 // For frozen screen animations.
552 int mExitAnimId, mEnterAnimId;
553
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800554 /** Pulled out of performLayoutAndPlaceSurfacesLockedInner in order to refactor into multiple
555 * methods. */
Craig Mautnera608b882012-03-30 13:03:49 -0700556 class LayoutFields {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700557 static final int SET_UPDATE_ROTATION = 1 << 0;
558 static final int SET_WALLPAPER_MAY_CHANGE = 1 << 1;
559 static final int SET_FORCE_HIDING_CHANGED = 1 << 2;
Craig Mautner2639da52012-07-09 09:39:06 -0700560 static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3;
Craig Mautner7d8df392012-04-06 15:26:23 -0700561 static final int SET_TURN_ON_SCREEN = 1 << 4;
Craig Mautner96868332012-12-04 14:29:11 -0800562 static final int SET_WALLPAPER_ACTION_PENDING = 1 << 5;
Craig Mautnera608b882012-03-30 13:03:49 -0700563
Craig Mautner764983d2012-03-22 11:37:36 -0700564 boolean mWallpaperForceHidingChanged = false;
565 boolean mWallpaperMayChange = false;
Craig Mautner764983d2012-03-22 11:37:36 -0700566 boolean mOrientationChangeComplete = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -0700567 Object mLastWindowFreezeSource = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800568 private Session mHoldScreen = null;
569 private boolean mObscured = false;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800570 private boolean mSyswin = false;
571 private float mScreenBrightness = -1;
572 private float mButtonBrightness = -1;
Jeff Brown1e3b98d2012-09-30 18:58:59 -0700573 private long mUserActivityTimeout = -1;
Craig Mautnera608b882012-03-30 13:03:49 -0700574 private boolean mUpdateRotation = false;
Craig Mautner96868332012-12-04 14:29:11 -0800575 boolean mWallpaperActionPending = false;
Craig Mautner65d11b32012-10-01 13:59:52 -0700576
577 private static final int DISPLAY_CONTENT_UNKNOWN = 0;
578 private static final int DISPLAY_CONTENT_MIRROR = 1;
579 private static final int DISPLAY_CONTENT_UNIQUE = 2;
580 private int mDisplayHasContent = DISPLAY_CONTENT_UNKNOWN;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800581 }
Craig Mautner01cd0e72012-06-18 10:19:11 -0700582 final LayoutFields mInnerFields = new LayoutFields();
583
Craig Mautner96868332012-12-04 14:29:11 -0800584 boolean mAnimationScheduled;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800585
Craig Mautner6fbda632012-07-03 09:26:39 -0700586 /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
587 * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
588 private int mTransactionSequence;
589
Craig Mautnerbb1449b2012-03-23 16:11:14 -0700590 /** Only do a maximum of 6 repeated layouts. After that quit */
591 private int mLayoutRepeatCount;
592
Craig Mautner764983d2012-03-22 11:37:36 -0700593 final WindowAnimator mAnimator;
Jeff Brown4a06c802012-02-15 15:06:01 -0800594
Craig Mautnerc00204b2013-03-05 15:02:14 -0800595 SparseArray<Task> mTaskIdToTask = new SparseArray<Task>();
596 SparseArray<TaskStack> mStackIdToStack = new SparseArray<TaskStack>();
597
Craig Mautner037aa8d2013-06-07 10:35:44 -0700598 private final PointerEventDispatcher mPointerEventDispatcher;
599
Jeff Brown32cbc38552011-12-01 14:01:49 -0800600 final class DragInputEventReceiver extends InputEventReceiver {
601 public DragInputEventReceiver(InputChannel inputChannel, Looper looper) {
602 super(inputChannel, looper);
603 }
604
Christopher Tatea53146c2010-09-07 11:57:52 -0700605 @Override
Jeff Brown32cbc38552011-12-01 14:01:49 -0800606 public void onInputEvent(InputEvent event) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700607 boolean handled = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700608 try {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800609 if (event instanceof MotionEvent
610 && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
Jeff Brown3915bb82010-11-05 15:02:16 -0700611 && mDragState != null) {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800612 final MotionEvent motionEvent = (MotionEvent)event;
Jeff Brown3915bb82010-11-05 15:02:16 -0700613 boolean endDrag = false;
Jeff Brown4952dfd2011-11-30 19:23:22 -0800614 final float newX = motionEvent.getRawX();
615 final float newY = motionEvent.getRawY();
Jeff Brown3915bb82010-11-05 15:02:16 -0700616
Jeff Brown4952dfd2011-11-30 19:23:22 -0800617 switch (motionEvent.getAction()) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700618 case MotionEvent.ACTION_DOWN: {
619 if (DEBUG_DRAG) {
620 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
621 }
622 } break;
623
624 case MotionEvent.ACTION_MOVE: {
625 synchronized (mWindowMap) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700626 // move the surface and tell the involved window(s) where we are
Christopher Tatea53146c2010-09-07 11:57:52 -0700627 mDragState.notifyMoveLw(newX, newY);
628 }
629 } break;
630
631 case MotionEvent.ACTION_UP: {
632 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
633 + newX + "," + newY);
634 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700635 endDrag = mDragState.notifyDropLw(newX, newY);
Christopher Tatea53146c2010-09-07 11:57:52 -0700636 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700637 } break;
638
639 case MotionEvent.ACTION_CANCEL: {
640 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
641 endDrag = true;
642 } break;
643 }
644
645 if (endDrag) {
646 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
647 // tell all the windows that the drag has ended
Chris Tate59943592010-10-11 20:33:44 -0700648 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700649 mDragState.endDragLw();
Chris Tate59943592010-10-11 20:33:44 -0700650 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700651 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700652
653 handled = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700654 }
655 } catch (Exception e) {
656 Slog.e(TAG, "Exception caught by drag handleMotion", e);
657 } finally {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800658 finishInputEvent(event, handled);
Christopher Tatea53146c2010-09-07 11:57:52 -0700659 }
660 }
Jeff Brown32cbc38552011-12-01 14:01:49 -0800661 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700662
663 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800664 * Whether the UI is currently running in touch mode (not showing
665 * navigational focus because the user is directly pressing the screen).
666 */
Michael Jurkae99adc72011-08-11 18:28:01 -0700667 boolean mInTouchMode = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668
669 private ViewServer mViewServer;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700670 private ArrayList<WindowChangeListener> mWindowChangeListeners =
671 new ArrayList<WindowChangeListener>();
672 private boolean mWindowsChanged = false;
673
674 public interface WindowChangeListener {
675 public void windowsChanged();
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -0700676 public void focusChanged();
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700677 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800678
Dianne Hackbornc485a602009-03-24 22:39:49 -0700679 final Configuration mTempConfiguration = new Configuration();
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700680
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700681 // The desired scaling factor for compatible apps.
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400682 float mCompatibleScreenScale;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700683
Jeff Brown780c46f2012-06-24 12:15:38 -0700684 // If true, only the core apps and services are being launched because the device
685 // is in a special boot mode, such as being encrypted or waiting for a decryption password.
686 // For example, when this flag is true, there will be no wallpaper service.
687 final boolean mOnlyCore;
688
Jeff Brownbd6e1502012-08-28 03:27:37 -0700689 public static WindowManagerService main(final Context context,
690 final PowerManagerService pm, final DisplayManagerService dm,
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700691 final InputManagerService im, final Handler wmHandler,
Jeff Brownbd6e1502012-08-28 03:27:37 -0700692 final boolean haveInputMethods, final boolean showBootMsgs,
693 final boolean onlyCore) {
694 final WindowManagerService[] holder = new WindowManagerService[1];
695 wmHandler.runWithScissors(new Runnable() {
696 @Override
697 public void run() {
Jeff Browna9d131c2012-09-20 16:48:17 -0700698 holder[0] = new WindowManagerService(context, pm, dm, im,
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700699 haveInputMethods, showBootMsgs, onlyCore);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800700 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700701 }, 0);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700702 return holder[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800703 }
Romain Guy06882f82009-06-10 13:36:04 -0700704
Jeff Brownbd6e1502012-08-28 03:27:37 -0700705 private void initPolicy(Handler uiHandler) {
706 uiHandler.runWithScissors(new Runnable() {
707 @Override
708 public void run() {
709 WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
Romain Guy06882f82009-06-10 13:36:04 -0700710
Jeff Brownbd6e1502012-08-28 03:27:37 -0700711 mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
712 mAnimator.mAboveUniverseLayer = mPolicy.getAboveUniverseLayer()
713 * TYPE_LAYER_MULTIPLIER
714 + TYPE_LAYER_OFFSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800715 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700716 }, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800717 }
718
719 private WindowManagerService(Context context, PowerManagerService pm,
Jeff Browna9d131c2012-09-20 16:48:17 -0700720 DisplayManagerService displayManager, InputManagerService inputManager,
Jeff Brown780c46f2012-06-24 12:15:38 -0700721 boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800722 mContext = context;
723 mHaveInputMethods = haveInputMethods;
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700724 mAllowBootMessages = showBootMsgs;
Jeff Brown780c46f2012-06-24 12:15:38 -0700725 mOnlyCore = onlyCore;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800726 mLimitedAlphaCompositing = context.getResources().getBoolean(
727 com.android.internal.R.bool.config_sf_limitedAlpha);
Craig Mautnercf910b02013-04-23 11:23:27 -0700728 mInputManager = inputManager; // Must be before createDisplayContentLocked.
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700729 mDisplayManagerService = displayManager;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700730 mHeadless = displayManager.isHeadless();
Dianne Hackbornc652de82013-02-15 16:32:56 -0800731 mDisplaySettings = new DisplaySettings(context);
732 mDisplaySettings.readSettingsLocked();
Romain Guy06882f82009-06-10 13:36:04 -0700733
Craig Mautner037aa8d2013-06-07 10:35:44 -0700734 mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG));
735
Craig Mautner722285e2012-09-07 13:55:58 -0700736 mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
737 mDisplayManager.registerDisplayListener(this, null);
738 Display[] displays = mDisplayManager.getDisplays();
739 for (Display display : displays) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -0700740 createDisplayContentLocked(display);
Craig Mautner722285e2012-09-07 13:55:58 -0700741 }
742
Craig Mautner5642a482012-08-23 12:16:53 -0700743 mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);
744
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800745 mPowerManager = pm;
746 mPowerManager.setPolicy(mPolicy);
747 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800748 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800749 mScreenFrozenLock.setReferenceCounted(false);
750
Craig Mautner164d4bb2012-11-26 13:51:23 -0800751 mAppTransition = new AppTransition(context, mH);
752
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800753 mActivityManager = ActivityManagerNative.getDefault();
754 mBatteryStats = BatteryStatsService.getService();
Dianne Hackbornc2293022013-02-06 23:14:49 -0800755 mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -0800756 mAppOps.startWatchingMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, null,
757 new AppOpsManager.Callback() {
758 @Override
759 public void opChanged(int op, String packageName) {
760 updateAppOpsState();
761 }
762 }
763 );
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800764
765 // Get persisted window scale setting
Jeff Sharkey6e2bee72012-10-01 13:39:08 -0700766 mWindowAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
767 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
768 mTransitionAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
769 Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
770 setAnimatorDurationScale(Settings.Global.getFloat(context.getContentResolver(),
Craig Mautnera7233fe32012-11-15 14:25:14 -0800771 Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale));
Romain Guy06882f82009-06-10 13:36:04 -0700772
Jim Miller284b62e2010-06-08 14:27:42 -0700773 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
774 IntentFilter filter = new IntentFilter();
775 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
776 mContext.registerReceiver(mBroadcastReceiver, filter);
777
Dianne Hackbornb80395c2012-06-14 19:38:20 -0700778 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
Craig Mautner259328c2012-08-21 19:30:58 -0700779 | PowerManager.ON_AFTER_RELEASE, TAG);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700780 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800781
Craig Mautner9e809442012-06-22 17:13:04 -0700782 mFxSession = new SurfaceSession();
Craig Mautner918b53b2012-07-09 14:15:54 -0700783 mAnimator = new WindowAnimator(this);
Romain Guy06882f82009-06-10 13:36:04 -0700784
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700785 initPolicy(UiThread.getHandler());
Romain Guy06882f82009-06-10 13:36:04 -0700786
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800787 // Add ourself to the Watchdog monitors.
788 Watchdog.getInstance().addMonitor(this);
Craig Mautner7358fbf2012-04-12 21:06:33 -0700789
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800790 SurfaceControl.openTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700791 try {
792 createWatermarkInTransaction();
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700793 mFocusedStackFrame = new FocusedStackFrame(
794 getDefaultDisplayContentLocked().getDisplay(), mFxSession);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700795 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800796 SurfaceControl.closeTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700797 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800798 }
799
Jeff Browna9d131c2012-09-20 16:48:17 -0700800 public InputMonitor getInputMonitor() {
801 return mInputMonitor;
Jeff Brown4532e612012-04-05 14:27:12 -0700802 }
803
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800804 @Override
805 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
806 throws RemoteException {
807 try {
808 return super.onTransact(code, data, reply, flags);
809 } catch (RuntimeException e) {
810 // The window manager only throws security exceptions, so let's
811 // log all others.
812 if (!(e instanceof SecurityException)) {
Dianne Hackborn89620282011-09-11 12:47:45 -0700813 Log.wtf(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800814 }
815 throw e;
816 }
817 }
818
Jeff Browne33348b2010-07-15 23:54:05 -0700819 private void placeWindowAfter(WindowState pos, WindowState window) {
Craig Mautner59c00972012-07-30 12:10:24 -0700820 final WindowList windows = pos.getWindowList();
821 final int i = windows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800822 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800823 TAG, "Adding window " + window + " at "
Craig Mautner59c00972012-07-30 12:10:24 -0700824 + (i+1) + " of " + windows.size() + " (after " + pos + ")");
825 windows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700826 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800827 }
828
Jeff Browne33348b2010-07-15 23:54:05 -0700829 private void placeWindowBefore(WindowState pos, WindowState window) {
Craig Mautner59c00972012-07-30 12:10:24 -0700830 final WindowList windows = pos.getWindowList();
Craig Mautnerf81b90872013-02-26 13:02:43 -0800831 int i = windows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800832 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800833 TAG, "Adding window " + window + " at "
Craig Mautner59c00972012-07-30 12:10:24 -0700834 + i + " of " + windows.size() + " (before " + pos + ")");
Craig Mautnerf81b90872013-02-26 13:02:43 -0800835 if (i < 0) {
836 Slog.w(TAG, "placeWindowBefore: Unable to find " + pos + " in " + windows);
837 i = 0;
838 }
Craig Mautner59c00972012-07-30 12:10:24 -0700839 windows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700840 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800841 }
842
843 //This method finds out the index of a window that has the same app token as
844 //win. used for z ordering the windows in mWindows
845 private int findIdxBasedOnAppTokens(WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -0700846 WindowList windows = win.getWindowList();
847 for(int j = windows.size() - 1; j >= 0; j--) {
848 WindowState wentry = windows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800849 if(wentry.mAppToken == win.mAppToken) {
850 return j;
851 }
852 }
853 return -1;
854 }
Romain Guy06882f82009-06-10 13:36:04 -0700855
Craig Mautnerefb735d2012-09-07 15:40:24 -0700856 /**
857 * Return the list of Windows from the passed token on the given Display.
858 * @param token The token with all the windows.
859 * @param displayContent The display we are interested in.
860 * @return List of windows from token that are on displayContent.
861 */
Craig Mautner69b08182012-09-05 13:07:13 -0700862 WindowList getTokenWindowsOnDisplay(WindowToken token, DisplayContent displayContent) {
863 final WindowList windowList = new WindowList();
864 final int count = token.windows.size();
865 for (int i = 0; i < count; i++) {
866 final WindowState win = token.windows.get(i);
867 if (win.mDisplayContent == displayContent) {
868 windowList.add(win);
869 }
870 }
871 return windowList;
872 }
873
Craig Mautner7b1aa772012-11-30 16:14:45 -0800874 /**
875 * Recursive search through a WindowList and all of its windows' children.
876 * @param targetWin The window to search for.
877 * @param windows The list to search.
878 * @return The index of win in windows or of the window that is an ancestor of win.
879 */
880 private int indexOfWinInWindowList(WindowState targetWin, WindowList windows) {
881 for (int i = windows.size() - 1; i >= 0; i--) {
882 final WindowState w = windows.get(i);
883 if (w == targetWin) {
884 return i;
885 }
886 if (!w.mChildWindows.isEmpty()) {
887 if (indexOfWinInWindowList(targetWin, w.mChildWindows) >= 0) {
888 return i;
889 }
890 }
891 }
892 return -1;
893 }
894
Craig Mautnera5eed0b2013-03-16 12:41:54 -0700895 private int addAppWindowToListLocked(final WindowState win) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800896 final IWindow client = win.mClient;
897 final WindowToken token = win.mToken;
Craig Mautner69b08182012-09-05 13:07:13 -0700898 final DisplayContent displayContent = win.mDisplayContent;
Romain Guy06882f82009-06-10 13:36:04 -0700899
Craig Mautner59c00972012-07-30 12:10:24 -0700900 final WindowList windows = win.getWindowList();
901 final int N = windows.size();
Craig Mautner69b08182012-09-05 13:07:13 -0700902 WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent);
Craig Mautnera5eed0b2013-03-16 12:41:54 -0700903 int tokenWindowsPos = 0;
904 int windowListPos = tokenWindowList.size();
905 if (!tokenWindowList.isEmpty()) {
906 // If this application has existing windows, we
907 // simply place the new window on top of them... but
908 // keep the starting window on top.
909 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
910 // Base windows go behind everything else.
911 WindowState lowestWindow = tokenWindowList.get(0);
912 placeWindowBefore(lowestWindow, win);
913 tokenWindowsPos = indexOfWinInWindowList(lowestWindow, token.windows);
914 } else {
915 AppWindowToken atoken = win.mAppToken;
916 WindowState lastWindow = tokenWindowList.get(windowListPos - 1);
917 if (atoken != null && lastWindow == atoken.startingWindow) {
918 placeWindowBefore(lastWindow, win);
919 tokenWindowsPos = indexOfWinInWindowList(lastWindow, token.windows);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800920 } else {
Craig Mautnera5eed0b2013-03-16 12:41:54 -0700921 int newIdx = findIdxBasedOnAppTokens(win);
922 //there is a window above this one associated with the same
923 //apptoken note that the window could be a floating window
924 //that was created later or a window at the top of the list of
925 //windows associated with this token.
926 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
927 "Adding window " + win + " at " + (newIdx + 1) + " of " + N);
928 windows.add(newIdx + 1, win);
929 if (newIdx < 0) {
930 // No window from token found on win's display.
931 tokenWindowsPos = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800932 } else {
Craig Mautnera5eed0b2013-03-16 12:41:54 -0700933 tokenWindowsPos = indexOfWinInWindowList(
934 windows.get(newIdx), token.windows) + 1;
935 }
936 mWindowsChanged = true;
937 }
938 }
939 return tokenWindowsPos;
940 }
941
942 // No windows from this token on this display
943 if (localLOGV) Slog.v(TAG, "Figuring out where to add app window " + client.asBinder()
944 + " (token=" + token + ")");
945 // Figure out where the window should go, based on the
946 // order of applications.
947 WindowState pos = null;
948
Craig Mautnerd9a22882013-03-16 15:00:36 -0700949 final ArrayList<Task> tasks = win.getStack().getTasks();
Craig Mautnera5eed0b2013-03-16 12:41:54 -0700950 int taskNdx;
951 int tokenNdx = -1;
952 for (taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
953 AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
954 for (tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
955 final AppWindowToken t = tokens.get(tokenNdx);
956 if (t == token) {
957 --tokenNdx;
958 if (tokenNdx < 0) {
959 --taskNdx;
960 if (taskNdx >= 0) {
961 tokenNdx = tasks.get(taskNdx).mAppTokens.size() - 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800962 }
963 }
Craig Mautnera5eed0b2013-03-16 12:41:54 -0700964 break;
965 }
966
967 // We haven't reached the token yet; if this token
968 // is not going to the bottom and has windows on this display, we can
969 // use it as an anchor for when we do reach the token.
970 tokenWindowList = getTokenWindowsOnDisplay(t, displayContent);
971 if (!t.sendingToBottom && tokenWindowList.size() > 0) {
972 pos = tokenWindowList.get(0);
973 }
974 }
975 if (tokenNdx >= 0) {
976 // early exit
977 break;
978 }
979 }
980
981 // We now know the index into the apps. If we found
982 // an app window above, that gives us the position; else
983 // we need to look some more.
984 if (pos != null) {
985 // Move behind any windows attached to this one.
986 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
987 if (atoken != null) {
988 tokenWindowList =
989 getTokenWindowsOnDisplay(atoken, displayContent);
990 final int NC = tokenWindowList.size();
991 if (NC > 0) {
992 WindowState bottom = tokenWindowList.get(0);
993 if (bottom.mSubLayer < 0) {
994 pos = bottom;
995 }
996 }
997 }
998 placeWindowBefore(pos, win);
999 return tokenWindowsPos;
1000 }
1001
1002 // Continue looking down until we find the first
1003 // token that has windows on this display.
1004 for ( ; taskNdx >= 0; --taskNdx) {
1005 AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
1006 for ( ; tokenNdx >= 0; --tokenNdx) {
1007 final AppWindowToken t = tokens.get(tokenNdx);
1008 tokenWindowList = getTokenWindowsOnDisplay(t, displayContent);
1009 final int NW = tokenWindowList.size();
1010 if (NW > 0) {
1011 pos = tokenWindowList.get(NW-1);
1012 break;
1013 }
1014 }
1015 if (tokenNdx >= 0) {
1016 // found
1017 break;
1018 }
1019 }
1020
1021 if (pos != null) {
1022 // Move in front of any windows attached to this
1023 // one.
1024 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
1025 if (atoken != null) {
1026 final int NC = atoken.windows.size();
1027 if (NC > 0) {
1028 WindowState top = atoken.windows.get(NC-1);
1029 if (top.mSubLayer >= 0) {
1030 pos = top;
1031 }
1032 }
1033 }
1034 placeWindowAfter(pos, win);
1035 return tokenWindowsPos;
1036 }
1037
1038 // Just search for the start of this layer.
1039 final int myLayer = win.mBaseLayer;
1040 int i;
1041 for (i = 0; i < N; i++) {
1042 WindowState w = windows.get(i);
1043 if (w.mBaseLayer > myLayer) {
1044 break;
1045 }
1046 }
1047 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
1048 "Adding window " + win + " at " + i + " of " + N);
1049 windows.add(i, win);
1050 mWindowsChanged = true;
1051 return tokenWindowsPos;
1052 }
1053
1054 private void addFreeWindowToListLocked(final WindowState win) {
1055 final WindowList windows = win.getWindowList();
1056
1057 // Figure out where window should go, based on layer.
1058 final int myLayer = win.mBaseLayer;
1059 int i;
1060 for (i = windows.size() - 1; i >= 0; i--) {
1061 if (windows.get(i).mBaseLayer <= myLayer) {
1062 break;
1063 }
1064 }
1065 i++;
1066 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
1067 "Adding window " + win + " at " + i + " of " + windows.size());
1068 windows.add(i, win);
1069 mWindowsChanged = true;
1070 }
1071
1072 private void addAttachedWindowToListLocked(final WindowState win, boolean addToToken) {
1073 final WindowToken token = win.mToken;
1074 final DisplayContent displayContent = win.mDisplayContent;
1075 final WindowState attached = win.mAttachedWindow;
1076
1077 WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent);
1078
1079 // Figure out this window's ordering relative to the window
1080 // it is attached to.
1081 final int NA = tokenWindowList.size();
1082 final int sublayer = win.mSubLayer;
1083 int largestSublayer = Integer.MIN_VALUE;
1084 WindowState windowWithLargestSublayer = null;
1085 int i;
1086 for (i = 0; i < NA; i++) {
1087 WindowState w = tokenWindowList.get(i);
1088 final int wSublayer = w.mSubLayer;
1089 if (wSublayer >= largestSublayer) {
1090 largestSublayer = wSublayer;
1091 windowWithLargestSublayer = w;
1092 }
1093 if (sublayer < 0) {
1094 // For negative sublayers, we go below all windows
1095 // in the same sublayer.
1096 if (wSublayer >= sublayer) {
1097 if (addToToken) {
1098 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
1099 token.windows.add(i, win);
1100 }
1101 placeWindowBefore(wSublayer >= 0 ? attached : w, win);
1102 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001103 }
1104 } else {
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001105 // For positive sublayers, we go above all windows
1106 // in the same sublayer.
1107 if (wSublayer > sublayer) {
1108 if (addToToken) {
1109 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
1110 token.windows.add(i, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001111 }
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001112 placeWindowBefore(w, win);
1113 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001114 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001115 }
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001116 }
1117 if (i >= NA) {
1118 if (addToToken) {
1119 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
1120 token.windows.add(win);
1121 }
1122 if (sublayer < 0) {
1123 placeWindowBefore(attached, win);
1124 } else {
1125 placeWindowAfter(largestSublayer >= 0
1126 ? windowWithLargestSublayer
1127 : attached,
1128 win);
1129 }
1130 }
1131 }
Craig Mautner59c00972012-07-30 12:10:24 -07001132
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001133 private void addWindowToListInOrderLocked(final WindowState win, boolean addToToken) {
1134 if (win.mAttachedWindow == null) {
1135 final WindowToken token = win.mToken;
1136 int tokenWindowsPos = 0;
1137 if (token.appWindowToken != null) {
1138 tokenWindowsPos = addAppWindowToListLocked(win);
1139 } else {
1140 addFreeWindowToListLocked(win);
1141 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001142 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001143 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001144 token.windows.add(tokenWindowsPos, win);
1145 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001146 } else {
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001147 addAttachedWindowToListLocked(win, addToToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001148 }
Romain Guy06882f82009-06-10 13:36:04 -07001149
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001150 if (win.mAppToken != null && addToToken) {
1151 win.mAppToken.allAppWindows.add(win);
1152 }
1153 }
Romain Guy06882f82009-06-10 13:36:04 -07001154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001155 static boolean canBeImeTarget(WindowState w) {
1156 final int fl = w.mAttrs.flags
1157 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
Dianne Hackborne75d8722011-01-27 19:37:40 -08001158 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)
Craig Mautner65d11b32012-10-01 13:59:52 -07001159 || w.mAttrs.type == TYPE_APPLICATION_STARTING) {
Dianne Hackborne75d8722011-01-27 19:37:40 -08001160 if (DEBUG_INPUT_METHOD) {
1161 Slog.i(TAG, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
1162 if (!w.isVisibleOrAdding()) {
Mathias Agopian29479eb2013-02-14 14:36:04 -08001163 Slog.i(TAG, " mSurface=" + w.mWinAnimator.mSurfaceControl
Dianne Hackborne75d8722011-01-27 19:37:40 -08001164 + " relayoutCalled=" + w.mRelayoutCalled + " viewVis=" + w.mViewVisibility
Dianne Hackbornac920872012-05-22 11:49:49 -07001165 + " policyVis=" + w.mPolicyVisibility
1166 + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim
1167 + " attachHid=" + w.mAttachedHidden
Dianne Hackborne75d8722011-01-27 19:37:40 -08001168 + " exiting=" + w.mExiting + " destroying=" + w.mDestroying);
1169 if (w.mAppToken != null) {
1170 Slog.i(TAG, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
1171 }
1172 }
1173 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001174 return w.isVisibleOrAdding();
1175 }
1176 return false;
1177 }
Romain Guy06882f82009-06-10 13:36:04 -07001178
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001179 /**
1180 * Dig through the WindowStates and find the one that the Input Method will target.
1181 * @param willMove
1182 * @return The index+1 in mWindows of the discovered target.
1183 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001184 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001185 // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
1186 // same display. Or even when the current IME/target are not on the same screen as the next
1187 // IME/target. For now only look for input windows on the main screen.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001188 WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07001189 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001190 WindowState w = null;
1191 int i = N;
1192 while (i > 0) {
1193 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07001194 w = windows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -07001195
Dianne Hackborne75d8722011-01-27 19:37:40 -08001196 if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG, "Checking window @" + i
1197 + " " + w + " fl=0x" + Integer.toHexString(w.mAttrs.flags));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001198 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001199 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -07001200
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001201 // Yet more tricksyness! If this window is a "starting"
1202 // window, we do actually want to be on top of it, but
1203 // it is not -really- where input will go. So if the caller
1204 // is not actually looking to move the IME, look down below
1205 // for a real window to target...
1206 if (!willMove
Craig Mautner65d11b32012-10-01 13:59:52 -07001207 && w.mAttrs.type == TYPE_APPLICATION_STARTING
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001208 && i > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001209 WindowState wb = windows.get(i-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001210 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1211 i--;
1212 w = wb;
1213 }
1214 }
1215 break;
1216 }
1217 }
Romain Guy06882f82009-06-10 13:36:04 -07001218
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001219 // Now w is either mWindows[0] or an IME (or null if mWindows is empty).
1220
Dianne Hackborne75d8722011-01-27 19:37:40 -08001221 if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG, "Proposed new IME target: " + w);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001222
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001223 // Now, a special case -- if the last target's window is in the
1224 // process of exiting, and is above the new target, keep on the
1225 // last target to avoid flicker. Consider for example a Dialog with
1226 // the IME shown: when the Dialog is dismissed, we want to keep
1227 // the IME above it until it is completely gone so it doesn't drop
1228 // behind the dialog or its full-screen scrim.
Craig Mautner59c00972012-07-30 12:10:24 -07001229 final WindowState curTarget = mInputMethodTarget;
1230 if (curTarget != null && w != null
1231 && curTarget.isDisplayedLw()
Craig Mautnera987d432012-10-11 14:07:58 -07001232 && curTarget.isClosing()
Craig Mautnere6f7d5052012-10-08 10:34:17 -07001233 && (curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) {
1234 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Current target higher, not changing");
1235 return windows.indexOf(curTarget) + 1;
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001236 }
Romain Guy06882f82009-06-10 13:36:04 -07001237
Joe Onorato8a9b2202010-02-26 18:56:32 -08001238 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001239 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -07001240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001241 if (willMove && w != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07001242 AppWindowToken token = curTarget == null ? null : curTarget.mAppToken;
1243 if (token != null) {
Romain Guy06882f82009-06-10 13:36:04 -07001244
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001245 // Now some fun for dealing with window animations that
1246 // modify the Z order. We need to look at all windows below
1247 // the current target that are in this app, finding the highest
1248 // visible one in layering.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001249 WindowState highestTarget = null;
1250 int highestPos = 0;
Craig Mautner59431632012-04-04 11:56:44 -07001251 if (token.mAppAnimator.animating || token.mAppAnimator.animation != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07001252 WindowList curWindows = curTarget.getWindowList();
1253 int pos = curWindows.indexOf(curTarget);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001254 while (pos >= 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001255 WindowState win = curWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001256 if (win.mAppToken != token) {
1257 break;
1258 }
1259 if (!win.mRemoved) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001260 if (highestTarget == null || win.mWinAnimator.mAnimLayer >
1261 highestTarget.mWinAnimator.mAnimLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001262 highestTarget = win;
1263 highestPos = pos;
1264 }
1265 }
1266 pos--;
1267 }
1268 }
Romain Guy06882f82009-06-10 13:36:04 -07001269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001270 if (highestTarget != null) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08001271 if (DEBUG_INPUT_METHOD) Slog.v(TAG, mAppTransition + " " + highestTarget
Craig Mautnera2c77052012-03-26 12:14:43 -07001272 + " animating=" + highestTarget.mWinAnimator.isAnimating()
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001273 + " layer=" + highestTarget.mWinAnimator.mAnimLayer
1274 + " new layer=" + w.mWinAnimator.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001275
Craig Mautner164d4bb2012-11-26 13:51:23 -08001276 if (mAppTransition.isTransitionSet()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001277 // If we are currently setting up for an animation,
1278 // hold everything until we can find out what will happen.
1279 mInputMethodTargetWaitingAnim = true;
1280 mInputMethodTarget = highestTarget;
1281 return highestPos + 1;
Craig Mautnera2c77052012-03-26 12:14:43 -07001282 } else if (highestTarget.mWinAnimator.isAnimating() &&
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001283 highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001284 // If the window we are currently targeting is involved
1285 // with an animation, and it is on top of the next target
1286 // we will be over, then hold off on moving until
1287 // that is done.
Dianne Hackborne75d8722011-01-27 19:37:40 -08001288 mInputMethodTargetWaitingAnim = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001289 mInputMethodTarget = highestTarget;
1290 return highestPos + 1;
1291 }
1292 }
1293 }
1294 }
Romain Guy06882f82009-06-10 13:36:04 -07001295
Joe Onorato8a9b2202010-02-26 18:56:32 -08001296 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001297 if (w != null) {
1298 if (willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001299 if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to "
1300 + w + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001301 mInputMethodTarget = w;
Dianne Hackborne75d8722011-01-27 19:37:40 -08001302 mInputMethodTargetWaitingAnim = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001303 if (w.mAppToken != null) {
Craig Mautner59431632012-04-04 11:56:44 -07001304 setInputMethodAnimLayerAdjustment(w.mAppToken.mAppAnimator.animLayerAdjustment);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001305 } else {
1306 setInputMethodAnimLayerAdjustment(0);
1307 }
1308 }
1309 return i+1;
1310 }
1311 if (willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001312 if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to null."
1313 + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314 mInputMethodTarget = null;
1315 setInputMethodAnimLayerAdjustment(0);
1316 }
1317 return -1;
1318 }
Romain Guy06882f82009-06-10 13:36:04 -07001319
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001320 void addInputMethodWindowToListLocked(WindowState win) {
1321 int pos = findDesiredInputMethodWindowIndexLocked(true);
1322 if (pos >= 0) {
1323 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001324 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001325 TAG, "Adding input method window " + win + " at " + pos);
Craig Mautner59c00972012-07-30 12:10:24 -07001326 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001327 getDefaultWindowListLocked().add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001328 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001329 moveInputMethodDialogsLocked(pos+1);
1330 return;
1331 }
1332 win.mTargetAppToken = null;
1333 addWindowToListInOrderLocked(win, true);
1334 moveInputMethodDialogsLocked(pos);
1335 }
Romain Guy06882f82009-06-10 13:36:04 -07001336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001337 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001338 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001339 mInputMethodAnimLayerAdjustment = adj;
1340 WindowState imw = mInputMethodWindow;
1341 if (imw != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001342 imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001343 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001344 + " anim layer: " + imw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001345 int wi = imw.mChildWindows.size();
1346 while (wi > 0) {
1347 wi--;
Jeff Browne33348b2010-07-15 23:54:05 -07001348 WindowState cw = imw.mChildWindows.get(wi);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001349 cw.mWinAnimator.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001350 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001351 + " anim layer: " + cw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001352 }
1353 }
1354 int di = mInputMethodDialogs.size();
1355 while (di > 0) {
1356 di --;
1357 imw = mInputMethodDialogs.get(di);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001358 imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001359 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001360 + " anim layer: " + imw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001361 }
1362 }
Romain Guy06882f82009-06-10 13:36:04 -07001363
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001364 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -07001365 WindowList windows = win.getWindowList();
1366 int wpos = windows.indexOf(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001367 if (wpos >= 0) {
1368 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001369 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
Craig Mautner59c00972012-07-30 12:10:24 -07001370 windows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001371 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001372 int NC = win.mChildWindows.size();
1373 while (NC > 0) {
1374 NC--;
Jeff Browne33348b2010-07-15 23:54:05 -07001375 WindowState cw = win.mChildWindows.get(NC);
Craig Mautner59c00972012-07-30 12:10:24 -07001376 int cpos = windows.indexOf(cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001377 if (cpos >= 0) {
1378 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001379 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001380 + cpos + ": " + cw);
Craig Mautner59c00972012-07-30 12:10:24 -07001381 windows.remove(cpos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001382 }
1383 }
1384 }
1385 return interestingPos;
1386 }
Romain Guy06882f82009-06-10 13:36:04 -07001387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001388 private void reAddWindowToListInOrderLocked(WindowState win) {
1389 addWindowToListInOrderLocked(win, false);
1390 // This is a hack to get all of the child windows added as well
1391 // at the right position. Child windows should be rare and
1392 // this case should be rare, so it shouldn't be that big a deal.
Craig Mautner59c00972012-07-30 12:10:24 -07001393 WindowList windows = win.getWindowList();
1394 int wpos = windows.indexOf(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001395 if (wpos >= 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001396 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos + ": " + win);
1397 windows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001398 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001399 reAddWindowLocked(wpos, win);
1400 }
1401 }
Romain Guy06882f82009-06-10 13:36:04 -07001402
Craig Mautner59c00972012-07-30 12:10:24 -07001403 void logWindowList(final WindowList windows, String prefix) {
1404 int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001405 while (N > 0) {
1406 N--;
Craig Mautner59c00972012-07-30 12:10:24 -07001407 Slog.v(TAG, prefix + "#" + N + ": " + windows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001408 }
1409 }
Romain Guy06882f82009-06-10 13:36:04 -07001410
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001411 void moveInputMethodDialogsLocked(int pos) {
1412 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001413
Craig Mautner59c00972012-07-30 12:10:24 -07001414 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001415 WindowList windows = getDefaultWindowListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001416 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001417 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001418 for (int i=0; i<N; i++) {
1419 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1420 }
1421 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001422 Slog.v(TAG, "Window list w/pos=" + pos);
Craig Mautner59c00972012-07-30 12:10:24 -07001423 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001424 }
Romain Guy06882f82009-06-10 13:36:04 -07001425
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001426 if (pos >= 0) {
1427 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
Craig Mautner59c00972012-07-30 12:10:24 -07001428 if (pos < windows.size()) {
1429 WindowState wp = windows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001430 if (wp == mInputMethodWindow) {
1431 pos++;
1432 }
1433 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001434 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001435 for (int i=0; i<N; i++) {
1436 WindowState win = dialogs.get(i);
1437 win.mTargetAppToken = targetAppToken;
1438 pos = reAddWindowLocked(pos, win);
1439 }
1440 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001441 Slog.v(TAG, "Final window list:");
Craig Mautner59c00972012-07-30 12:10:24 -07001442 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001443 }
1444 return;
1445 }
1446 for (int i=0; i<N; i++) {
1447 WindowState win = dialogs.get(i);
1448 win.mTargetAppToken = null;
1449 reAddWindowToListInOrderLocked(win);
1450 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001451 Slog.v(TAG, "No IM target, final list:");
Craig Mautner59c00972012-07-30 12:10:24 -07001452 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001453 }
1454 }
1455 }
Romain Guy06882f82009-06-10 13:36:04 -07001456
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001457 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1458 final WindowState imWin = mInputMethodWindow;
1459 final int DN = mInputMethodDialogs.size();
1460 if (imWin == null && DN == 0) {
1461 return false;
1462 }
Romain Guy06882f82009-06-10 13:36:04 -07001463
Craig Mautner59c00972012-07-30 12:10:24 -07001464 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001465 WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07001466
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001467 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1468 if (imPos >= 0) {
1469 // In this case, the input method windows are to be placed
1470 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001472 // First check to see if the input method windows are already
1473 // located here, and contiguous.
Craig Mautner59c00972012-07-30 12:10:24 -07001474 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001475 WindowState firstImWin = imPos < N
Craig Mautner59c00972012-07-30 12:10:24 -07001476 ? windows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001478 // Figure out the actual input method window that should be
1479 // at the bottom of their stack.
1480 WindowState baseImWin = imWin != null
1481 ? imWin : mInputMethodDialogs.get(0);
1482 if (baseImWin.mChildWindows.size() > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001483 WindowState cw = baseImWin.mChildWindows.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001484 if (cw.mSubLayer < 0) baseImWin = cw;
1485 }
Romain Guy06882f82009-06-10 13:36:04 -07001486
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487 if (firstImWin == baseImWin) {
1488 // The windows haven't moved... but are they still contiguous?
1489 // First find the top IM window.
1490 int pos = imPos+1;
1491 while (pos < N) {
Craig Mautner59c00972012-07-30 12:10:24 -07001492 if (!(windows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001493 break;
1494 }
1495 pos++;
1496 }
1497 pos++;
1498 // Now there should be no more input method windows above.
1499 while (pos < N) {
Craig Mautner59c00972012-07-30 12:10:24 -07001500 if ((windows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001501 break;
1502 }
1503 pos++;
1504 }
1505 if (pos >= N) {
Carrie Xu5c971842012-10-30 17:28:39 +08001506 // Z order is good.
1507 // The IM target window may be changed, so update the mTargetAppToken.
1508 if (imWin != null) {
1509 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1510 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 return false;
1512 }
1513 }
Romain Guy06882f82009-06-10 13:36:04 -07001514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001515 if (imWin != null) {
1516 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001517 Slog.v(TAG, "Moving IM from " + imPos);
Craig Mautner59c00972012-07-30 12:10:24 -07001518 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001519 }
1520 imPos = tmpRemoveWindowLocked(imPos, imWin);
1521 if (DEBUG_INPUT_METHOD) {
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001522 Slog.v(TAG, "List after removing with new pos " + imPos + ":");
Craig Mautner59c00972012-07-30 12:10:24 -07001523 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001524 }
1525 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1526 reAddWindowLocked(imPos, imWin);
1527 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001528 Slog.v(TAG, "List after moving IM to " + imPos + ":");
Craig Mautner59c00972012-07-30 12:10:24 -07001529 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001530 }
1531 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1532 } else {
1533 moveInputMethodDialogsLocked(imPos);
1534 }
Romain Guy06882f82009-06-10 13:36:04 -07001535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001536 } else {
1537 // In this case, the input method windows go in a fixed layer,
1538 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001539
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001540 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001541 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001542 tmpRemoveWindowLocked(0, imWin);
1543 imWin.mTargetAppToken = null;
1544 reAddWindowToListInOrderLocked(imWin);
1545 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001546 Slog.v(TAG, "List with no IM target:");
Craig Mautner59c00972012-07-30 12:10:24 -07001547 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001548 }
Craig Mautner01cd0e72012-06-18 10:19:11 -07001549 if (DN > 0) moveInputMethodDialogsLocked(-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001550 } else {
Craig Mautner01cd0e72012-06-18 10:19:11 -07001551 moveInputMethodDialogsLocked(-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001552 }
Romain Guy06882f82009-06-10 13:36:04 -07001553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001554 }
Romain Guy06882f82009-06-10 13:36:04 -07001555
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001556 if (needAssignLayers) {
Craig Mautner59c00972012-07-30 12:10:24 -07001557 assignLayersLocked(windows);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001558 }
Romain Guy06882f82009-06-10 13:36:04 -07001559
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001560 return true;
1561 }
Romain Guy06882f82009-06-10 13:36:04 -07001562
Dianne Hackborn25994b42009-09-04 14:21:19 -07001563 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Craig Mautnerad3a9bb2012-03-09 11:31:06 -08001564 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001565 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1566 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
Craig Mautner59431632012-04-04 11:56:44 -07001567 ? wallpaperTarget.mAppToken.mAppAnimator.animation : null)
Dianne Hackborn25994b42009-09-04 14:21:19 -07001568 + " upper=" + mUpperWallpaperTarget
1569 + " lower=" + mLowerWallpaperTarget);
1570 return (wallpaperTarget != null
1571 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
Craig Mautner59431632012-04-04 11:56:44 -07001572 && wallpaperTarget.mAppToken.mAppAnimator.animation != null)))
Dianne Hackborn25994b42009-09-04 14:21:19 -07001573 || mUpperWallpaperTarget != null
1574 || mLowerWallpaperTarget != null;
1575 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001576
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001577 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1578 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001579
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001580 int adjustWallpaperWindowsLocked() {
Craig Mautnera608b882012-03-30 13:03:49 -07001581 mInnerFields.mWallpaperMayChange = false;
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001582 boolean targetChanged = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001583
Craig Mautner59c00972012-07-30 12:10:24 -07001584 // TODO(multidisplay): Wallpapers on main screen only.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001585 final DisplayInfo displayInfo = getDefaultDisplayContentLocked().getDisplayInfo();
Craig Mautner59c00972012-07-30 12:10:24 -07001586 final int dw = displayInfo.appWidth;
1587 final int dh = displayInfo.appHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001588
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001589 // First find top-most window that has asked to be on top of the
1590 // wallpaper; all wallpapers go behind it.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001591 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07001592 int N = windows.size();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001593 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001594 WindowState foundW = null;
1595 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001596 WindowState topCurW = null;
1597 int topCurI = 0;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001598 int windowDetachedI = -1;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001599 int i = N;
1600 while (i > 0) {
1601 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07001602 w = windows.get(i);
Craig Mautner65d11b32012-10-01 13:59:52 -07001603 if ((w.mAttrs.type == TYPE_WALLPAPER)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001604 if (topCurW == null) {
1605 topCurW = w;
1606 topCurI = i;
1607 }
1608 continue;
1609 }
1610 topCurW = null;
Craig Mautner96868332012-12-04 14:29:11 -08001611 if (w != mAnimator.mWindowDetachedWallpaper && w.mAppToken != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001612 // If this window's app token is hidden and not animating,
1613 // it is of no interest to us.
Craig Mautner59431632012-04-04 11:56:44 -07001614 if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001615 if (DEBUG_WALLPAPER) Slog.v(TAG,
Craig Mautner1d961d42012-05-27 12:02:11 -07001616 "Skipping hidden and not animating token: " + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001617 continue;
1618 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001619 }
Craig Mautnerae446592012-12-06 19:05:05 -08001620 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win #" + i + " " + w + ": isOnScreen="
1621 + w.isOnScreen() + " mDrawState=" + w.mWinAnimator.mDrawState);
1622 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isOnScreen()
1623 && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001624 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001625 "Found wallpaper target: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001626 foundW = w;
1627 foundI = i;
Craig Mautner4d7349b2012-04-20 14:52:47 -07001628 if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001629 // The current wallpaper target is animating, so we'll
1630 // look behind it for another possible target and figure
1631 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001632 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001633 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001634 continue;
1635 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001636 break;
Craig Mautner96868332012-12-04 14:29:11 -08001637 } else if (w == mAnimator.mWindowDetachedWallpaper) {
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001638 windowDetachedI = i;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001639 }
1640 }
1641
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001642 if (foundW == null && windowDetachedI >= 0) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001643 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001644 "Found animating detached wallpaper activity: #" + i + "=" + w);
1645 foundW = w;
1646 foundI = windowDetachedI;
1647 }
1648
Craig Mautner8863cca2012-09-18 15:04:34 -07001649 if (mWallpaperTarget != foundW
1650 && (mLowerWallpaperTarget == null || mLowerWallpaperTarget != foundW)) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001651 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001652 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001653 + " oldTarget: " + mWallpaperTarget);
1654 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001655
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001656 mLowerWallpaperTarget = null;
1657 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001658
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001659 WindowState oldW = mWallpaperTarget;
1660 mWallpaperTarget = foundW;
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001661 targetChanged = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001662
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001663 // Now what is happening... if the current and new targets are
1664 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001665 if (foundW != null && oldW != null) {
Craig Mautnerae446592012-12-06 19:05:05 -08001666 boolean oldAnim = oldW.isAnimatingLw();
1667 boolean foundAnim = foundW.isAnimatingLw();
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001668 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001669 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001670 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001671 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001672 if (foundAnim && oldAnim) {
Craig Mautner59c00972012-07-30 12:10:24 -07001673 int oldI = windows.indexOf(oldW);
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001674 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001675 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001676 }
1677 if (oldI >= 0) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001678 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001679 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001680 + "=" + oldW + "; new#" + foundI
1681 + "=" + foundW);
1682 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001683
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001684 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001685 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001686 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001687 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001688 }
1689 mWallpaperTarget = oldW;
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001690 foundW = oldW;
1691 foundI = oldI;
Craig Mautner711f90a2012-07-03 18:43:52 -07001692 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001693 // Now set the upper and lower wallpaper targets
1694 // correctly, and make sure that we are positioning
1695 // the wallpaper below the lower.
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001696 else if (foundI > oldI) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001697 // The new target is on top of the old one.
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001698 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001699 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001700 }
1701 mUpperWallpaperTarget = foundW;
1702 mLowerWallpaperTarget = oldW;
1703 foundW = oldW;
1704 foundI = oldI;
1705 } else {
1706 // The new target is below the old one.
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001707 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001708 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001709 }
1710 mUpperWallpaperTarget = oldW;
1711 mLowerWallpaperTarget = foundW;
1712 }
1713 }
1714 }
1715 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001716
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001717 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001718 // Is it time to stop animating?
Craig Mautnerae446592012-12-06 19:05:05 -08001719 if (!mLowerWallpaperTarget.isAnimatingLw() || !mUpperWallpaperTarget.isAnimatingLw()) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001720 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001721 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001722 }
1723 mLowerWallpaperTarget = null;
1724 mUpperWallpaperTarget = null;
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001725 mWallpaperTarget = foundW;
1726 targetChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001727 }
1728 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001729
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001730 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001731 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001732 // The window is visible to the compositor... but is it visible
1733 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001734 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001735 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001736
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001737 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001738 // its layer adjustment. Only do this if we are not transfering
1739 // between two wallpaper targets.
1740 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001741 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Craig Mautner59431632012-04-04 11:56:44 -07001742 ? foundW.mAppToken.mAppAnimator.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001743
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001744 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1745 * TYPE_LAYER_MULTIPLIER
1746 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001747
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001748 // Now w is the window we are supposed to be behind... but we
1749 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001750 // AND any starting window associated with it, AND below the
1751 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001752 while (foundI > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001753 WindowState wb = windows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001754 if (wb.mBaseLayer < maxLayer &&
1755 wb.mAttachedWindow != foundW &&
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001756 (foundW.mAttachedWindow == null ||
1757 wb.mAttachedWindow != foundW.mAttachedWindow) &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001758 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001759 foundW.mToken == null || wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001760 // This window is not related to the previous one in any
1761 // interesting way, so stop here.
1762 break;
1763 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001764 foundW = wb;
1765 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001766 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001767 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001768 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001769 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001770
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001771 if (foundW == null && topCurW != null) {
1772 // There is no wallpaper target, so it goes at the bottom.
1773 // We will assume it is the same place as last time, if known.
1774 foundW = topCurW;
1775 foundI = topCurI+1;
1776 } else {
1777 // Okay i is the position immediately above the wallpaper. Look at
1778 // what is below it for later.
Craig Mautner59c00972012-07-30 12:10:24 -07001779 foundW = foundI > 0 ? windows.get(foundI-1) : null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001780 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001781
Dianne Hackborn284ac932009-08-28 10:34:25 -07001782 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001783 if (mWallpaperTarget.mWallpaperX >= 0) {
1784 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001785 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001786 }
1787 if (mWallpaperTarget.mWallpaperY >= 0) {
1788 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001789 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001790 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001791 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001792
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001793 // Start stepping backwards from here, ensuring that our wallpaper windows
1794 // are correctly placed.
Craig Mautnerae446592012-12-06 19:05:05 -08001795 int changed = 0;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001796 int curTokenIndex = mWallpaperTokens.size();
1797 while (curTokenIndex > 0) {
1798 curTokenIndex--;
1799 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001800 if (token.hidden == visible) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001801 if (DEBUG_WALLPAPER_LIGHT) Slog.d(TAG,
1802 "Wallpaper token " + token + " hidden=" + !visible);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001803 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1804 token.hidden = !visible;
1805 // Need to do a layout to ensure the wallpaper now has the
1806 // correct size.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001807 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001808 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001809
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001810 int curWallpaperIndex = token.windows.size();
1811 while (curWallpaperIndex > 0) {
1812 curWallpaperIndex--;
1813 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001814
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001815 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001816 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001817 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001818
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001819 // First, make sure the client has the current visibility
1820 // state.
Craig Mautner507a2ee2012-06-13 08:39:38 -07001821 dispatchWallpaperVisibility(wallpaper, visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001822
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001823 wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001824 if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "adjustWallpaper win "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001825 + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001826
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001827 // First, if this window is at the current index, then all
1828 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001829 if (wallpaper == foundW) {
1830 foundI--;
1831 foundW = foundI > 0
Craig Mautner59c00972012-07-30 12:10:24 -07001832 ? windows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001833 continue;
1834 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001835
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001836 // The window didn't match... the current wallpaper window,
1837 // wherever it is, is in the wrong place, so make sure it is
1838 // not in the list.
Craig Mautner59c00972012-07-30 12:10:24 -07001839 int oldIndex = windows.indexOf(wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001840 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001841 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001842 + oldIndex + ": " + wallpaper);
Craig Mautner59c00972012-07-30 12:10:24 -07001843 windows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001844 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001845 if (oldIndex < foundI) {
1846 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001847 }
1848 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001849
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001850 // Now stick it in.
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001851 if (DEBUG_WALLPAPER_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001852 Slog.v(TAG, "Moving wallpaper " + wallpaper
Craig Mautner5457e612013-05-10 16:25:02 -07001853 + " from " + oldIndex + " to " + 0);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001854 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001855
Craig Mautner5457e612013-05-10 16:25:02 -07001856 windows.add(0, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001857 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001858 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001859 }
1860 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001861
Craig Mautner5457e612013-05-10 16:25:02 -07001862 /*
Craig Mautner05d29032013-05-03 13:40:13 -07001863 final TaskStack targetStack =
1864 mWallpaperTarget == null ? null : mWallpaperTarget.getStack();
1865 if ((changed & ADJUST_WALLPAPER_LAYERS_CHANGED) != 0 &&
1866 targetStack != null && !targetStack.isHomeStack()) {
1867 // If the wallpaper target is not on the home stack then make sure that all windows
1868 // from other non-home stacks are above the wallpaper.
1869 for (i = foundI - 1; i >= 0; --i) {
1870 WindowState win = windows.get(i);
1871 if (!win.isVisibleLw()) {
1872 continue;
1873 }
1874 final TaskStack winStack = win.getStack();
1875 if (winStack != null && !winStack.isHomeStack() && winStack != targetStack) {
1876 windows.remove(i);
1877 windows.add(foundI + 1, win);
1878 }
1879 }
1880 }
Craig Mautner5457e612013-05-10 16:25:02 -07001881 */
Craig Mautner05d29032013-05-03 13:40:13 -07001882
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001883 if (targetChanged && DEBUG_WALLPAPER_LIGHT) {
1884 Slog.d(TAG, "New wallpaper: target=" + mWallpaperTarget
1885 + " lower=" + mLowerWallpaperTarget + " upper="
1886 + mUpperWallpaperTarget);
1887 }
1888
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001889 return changed;
1890 }
1891
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001892 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001893 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001894 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001895 mWallpaperAnimLayerAdjustment = adj;
1896 int curTokenIndex = mWallpaperTokens.size();
1897 while (curTokenIndex > 0) {
1898 curTokenIndex--;
1899 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1900 int curWallpaperIndex = token.windows.size();
1901 while (curWallpaperIndex > 0) {
1902 curWallpaperIndex--;
1903 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001904 wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + adj;
Craig Mautneref25d7a2012-05-15 23:01:47 -07001905 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "setWallpaper win "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001906 + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001907 }
1908 }
1909 }
1910
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001911 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
1912 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001913 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001914 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001915 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001916 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackbornffb3d932011-05-17 17:44:51 -07001917 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001918 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
1919 changed = wallpaperWin.mXOffset != offset;
1920 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001921 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001922 + wallpaperWin + " x: " + offset);
1923 wallpaperWin.mXOffset = offset;
1924 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001925 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001926 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001927 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001928 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001929 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001930
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001931 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001932 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001933 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1934 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1935 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001936 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001937 + wallpaperWin + " y: " + offset);
1938 changed = true;
1939 wallpaperWin.mYOffset = offset;
1940 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001941 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001942 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001943 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001944 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001945 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001946
Craig Mautnerbb1449b2012-03-23 16:11:14 -07001947 if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
Chet Haasea8e5a2b2011-10-28 13:18:16 -07001948 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001949 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001950 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001951 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
1952 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001953 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001954 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001955 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001956 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001957 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
1958 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001959 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001960 if (mWaitingOnWallpaper != null) {
1961 long start = SystemClock.uptimeMillis();
1962 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
1963 < start) {
1964 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001965 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07001966 "Waiting for offset complete...");
1967 mWindowMap.wait(WALLPAPER_TIMEOUT);
1968 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001969 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001970 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07001971 if ((start+WALLPAPER_TIMEOUT)
1972 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001973 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07001974 + wallpaperWin);
1975 mLastWallpaperTimeoutTime = start;
1976 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001977 }
Dianne Hackborn75804932009-10-20 20:15:20 -07001978 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001979 }
1980 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001981 } catch (RemoteException e) {
1982 }
1983 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001984
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001985 return changed;
1986 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001987
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001988 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001989 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001990 if (mWaitingOnWallpaper != null &&
1991 mWaitingOnWallpaper.mClient.asBinder() == window) {
1992 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07001993 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001994 }
1995 }
1996 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001997
Chet Haasea8e5a2b2011-10-28 13:18:16 -07001998 void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Craig Mautner59c00972012-07-30 12:10:24 -07001999 final DisplayContent displayContent = changingTarget.mDisplayContent;
2000 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
2001 final int dw = displayInfo.appWidth;
2002 final int dh = displayInfo.appHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002003
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002004 WindowState target = mWallpaperTarget;
2005 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002006 if (target.mWallpaperX >= 0) {
2007 mLastWallpaperX = target.mWallpaperX;
2008 } else if (changingTarget.mWallpaperX >= 0) {
2009 mLastWallpaperX = changingTarget.mWallpaperX;
2010 }
2011 if (target.mWallpaperY >= 0) {
2012 mLastWallpaperY = target.mWallpaperY;
2013 } else if (changingTarget.mWallpaperY >= 0) {
2014 mLastWallpaperY = changingTarget.mWallpaperY;
2015 }
2016 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002017
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002018 int curTokenIndex = mWallpaperTokens.size();
2019 while (curTokenIndex > 0) {
2020 curTokenIndex--;
2021 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2022 int curWallpaperIndex = token.windows.size();
2023 while (curWallpaperIndex > 0) {
2024 curWallpaperIndex--;
2025 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2026 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002027 WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
2028 winAnimator.computeShownFrameLocked();
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002029 // No need to lay out the windows - we can just set the wallpaper position
2030 // directly.
Craig Mautner58106812012-12-28 12:27:40 -08002031 winAnimator.setWallpaperOffset(wallpaper.mShownFrame);
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002032 // We only want to be synchronous with one wallpaper.
2033 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002034 }
2035 }
2036 }
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002037 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002038
Craig Mautner507a2ee2012-06-13 08:39:38 -07002039 /**
2040 * Check wallpaper for visiblity change and notify window if so.
2041 * @param wallpaper The wallpaper to test and notify.
2042 * @param visible Current visibility.
2043 */
2044 void dispatchWallpaperVisibility(final WindowState wallpaper, final boolean visible) {
2045 if (wallpaper.mWallpaperVisible != visible) {
2046 wallpaper.mWallpaperVisible = visible;
2047 try {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07002048 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
2049 "Updating vis of wallpaper " + wallpaper
2050 + ": " + visible + " from:\n" + Debug.getCallers(4, " "));
Craig Mautner507a2ee2012-06-13 08:39:38 -07002051 wallpaper.mClient.dispatchAppVisibility(visible);
2052 } catch (RemoteException e) {
2053 }
2054 }
2055 }
2056
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002057 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07002058 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Craig Mautner59c00972012-07-30 12:10:24 -07002059 final DisplayContent displayContent = mWallpaperTarget.mDisplayContent;
2060 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
2061 final int dw = displayInfo.appWidth;
2062 final int dh = displayInfo.appHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002063
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002064 int curTokenIndex = mWallpaperTokens.size();
2065 while (curTokenIndex > 0) {
2066 curTokenIndex--;
2067 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002068 if (token.hidden == visible) {
2069 token.hidden = !visible;
2070 // Need to do a layout to ensure the wallpaper now has the
2071 // correct size.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07002072 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002073 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002074
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002075 int curWallpaperIndex = token.windows.size();
2076 while (curWallpaperIndex > 0) {
2077 curWallpaperIndex--;
2078 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2079 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002080 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002081 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002082
Craig Mautner507a2ee2012-06-13 08:39:38 -07002083 dispatchWallpaperVisibility(wallpaper, visible);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002084 }
2085 }
2086 }
Craig Mautner711f90a2012-07-03 18:43:52 -07002087
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002088 public int addWindow(Session session, IWindow client, int seq,
Craig Mautner6881a102012-07-27 13:04:51 -07002089 WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002090 Rect outContentInsets, InputChannel outInputChannel) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08002091 int[] appOp = new int[1];
2092 int res = mPolicy.checkAddPermission(attrs, appOp);
Jeff Brown98365d72012-08-19 20:30:52 -07002093 if (res != WindowManagerGlobal.ADD_OKAY) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002094 return res;
2095 }
Romain Guy06882f82009-06-10 13:36:04 -07002096
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002097 boolean reportNewConfig = false;
2098 WindowState attachedWindow = null;
2099 WindowState win = null;
Dianne Hackborn5132b372010-07-29 12:51:35 -07002100 long origId;
Craig Mautner88400d32012-09-30 12:35:45 -07002101 final int type = attrs.type;
Romain Guy06882f82009-06-10 13:36:04 -07002102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002103 synchronized(mWindowMap) {
Jeff Browne215f262012-09-10 16:01:14 -07002104 if (!mDisplayReady) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07002105 throw new IllegalStateException("Display has not been initialialized");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002106 }
Romain Guy06882f82009-06-10 13:36:04 -07002107
Craig Mautner2d5618c2012-10-18 13:55:47 -07002108 final DisplayContent displayContent = getDisplayContentLocked(displayId);
2109 if (displayContent == null) {
Jeff Browna506a6e2013-06-04 00:02:38 -07002110 Slog.w(TAG, "Attempted to add window to a display that does not exist: "
2111 + displayId + ". Aborting.");
2112 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
2113 }
2114 if (!displayContent.hasAccess(session.mUid)) {
2115 Slog.w(TAG, "Attempted to add window to a display for which the application "
2116 + "does not have access: " + displayId + ". Aborting.");
Craig Mautner2d5618c2012-10-18 13:55:47 -07002117 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
2118 }
2119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002120 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002121 Slog.w(TAG, "Window " + client + " is already added");
Jeff Brown98365d72012-08-19 20:30:52 -07002122 return WindowManagerGlobal.ADD_DUPLICATE_ADD;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002123 }
2124
Craig Mautner88400d32012-09-30 12:35:45 -07002125 if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002126 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002127 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002128 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002129 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002130 return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002131 }
2132 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
2133 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002134 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002135 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002136 return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002137 }
2138 }
2139
keunyounga446bf02013-06-21 19:07:57 -07002140 if (type == TYPE_PRIVATE_PRESENTATION && !displayContent.isPrivate()) {
2141 Slog.w(TAG, "Attempted to add private presentation window to a non-private display. Aborting.");
2142 return WindowManagerGlobal.ADD_PERMISSION_DENIED;
2143 }
2144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002145 boolean addToken = false;
2146 WindowToken token = mTokenMap.get(attrs.token);
2147 if (token == null) {
Craig Mautner88400d32012-09-30 12:35:45 -07002148 if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002149 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002150 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002151 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002152 }
Craig Mautner88400d32012-09-30 12:35:45 -07002153 if (type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002154 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002155 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002156 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002157 }
Craig Mautner88400d32012-09-30 12:35:45 -07002158 if (type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002159 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002160 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002161 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002162 }
Craig Mautner88400d32012-09-30 12:35:45 -07002163 if (type == TYPE_DREAM) {
Daniel Sandler7d276c32012-01-30 14:33:52 -05002164 Slog.w(TAG, "Attempted to add Dream window with unknown token "
2165 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002166 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Daniel Sandler7d276c32012-01-30 14:33:52 -05002167 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002168 token = new WindowToken(this, attrs.token, -1, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002169 addToken = true;
Craig Mautner88400d32012-09-30 12:35:45 -07002170 } else if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002171 AppWindowToken atoken = token.appWindowToken;
2172 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002173 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002174 + token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002175 return WindowManagerGlobal.ADD_NOT_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002176 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002177 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002178 + token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002179 return WindowManagerGlobal.ADD_APP_EXITING;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002180 }
Craig Mautner88400d32012-09-30 12:35:45 -07002181 if (type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002182 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002183 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002184 TAG, "**** NO NEED TO START: " + attrs.getTitle());
Jeff Brown98365d72012-08-19 20:30:52 -07002185 return WindowManagerGlobal.ADD_STARTING_NOT_NEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002186 }
Craig Mautner88400d32012-09-30 12:35:45 -07002187 } else if (type == TYPE_INPUT_METHOD) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002188 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002189 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002190 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002191 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002192 }
Craig Mautner88400d32012-09-30 12:35:45 -07002193 } else if (type == TYPE_WALLPAPER) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002194 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002195 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002196 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002197 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002198 }
Craig Mautner88400d32012-09-30 12:35:45 -07002199 } else if (type == TYPE_DREAM) {
Daniel Sandler7d276c32012-01-30 14:33:52 -05002200 if (token.windowType != TYPE_DREAM) {
2201 Slog.w(TAG, "Attempted to add Dream window with bad token "
2202 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002203 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Daniel Sandler7d276c32012-01-30 14:33:52 -05002204 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002205 }
2206
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002207 win = new WindowState(this, session, client, token,
Dianne Hackbornc2293022013-02-06 23:14:49 -08002208 attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002209 if (win.mDeathRecipient == null) {
2210 // Client has apparently died, so there is no reason to
2211 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002212 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002213 + " that is dead, aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002214 return WindowManagerGlobal.ADD_APP_EXITING;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002215 }
2216
2217 mPolicy.adjustWindowParamsLw(win.mAttrs);
Craig Mautner88400d32012-09-30 12:35:45 -07002218 win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));
Romain Guy06882f82009-06-10 13:36:04 -07002219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002220 res = mPolicy.prepareAddWindowLw(win, attrs);
Jeff Brown98365d72012-08-19 20:30:52 -07002221 if (res != WindowManagerGlobal.ADD_OKAY) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002222 return res;
2223 }
Craig Mautner918b53b2012-07-09 14:15:54 -07002224
Jeff Browncc4f7db2011-08-30 20:34:48 -07002225 if (outInputChannel != null && (attrs.inputFeatures
2226 & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002227 String name = win.makeInputChannelName();
2228 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
Jeff Browncc4f7db2011-08-30 20:34:48 -07002229 win.setInputChannel(inputChannels[0]);
Jeff Brown0a0ab122011-08-12 18:08:08 -07002230 inputChannels[1].transferTo(outInputChannel);
Craig Mautner918b53b2012-07-09 14:15:54 -07002231
Jeff Brown928e0542011-01-10 11:17:36 -08002232 mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002233 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002234
2235 // From now on, no exceptions or errors allowed!
2236
Jeff Brown98365d72012-08-19 20:30:52 -07002237 res = WindowManagerGlobal.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002238
Dianne Hackborn5132b372010-07-29 12:51:35 -07002239 origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002241 if (addToken) {
2242 mTokenMap.put(attrs.token, token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002243 }
2244 win.attach();
2245 mWindowMap.put(client.asBinder(), win);
Dianne Hackbornc2293022013-02-06 23:14:49 -08002246 if (win.mAppOp != AppOpsManager.OP_NONE) {
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002247 if (mAppOps.startOpNoThrow(win.mAppOp, win.getOwningUid(), win.getOwningPackage())
2248 != AppOpsManager.MODE_ALLOWED) {
2249 win.setAppOpVisibilityLw(false);
2250 }
Dianne Hackbornc2293022013-02-06 23:14:49 -08002251 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002252
Craig Mautner88400d32012-09-30 12:35:45 -07002253 if (type == TYPE_APPLICATION_STARTING && token.appWindowToken != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002254 token.appWindowToken.startingWindow = win;
Craig Mautner38b24782012-07-02 16:21:28 -07002255 if (DEBUG_STARTING_WINDOW) Slog.v (TAG, "addWindow: " + token.appWindowToken
2256 + " startingWindow=" + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002257 }
2258
2259 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002260
Craig Mautner88400d32012-09-30 12:35:45 -07002261 if (type == TYPE_INPUT_METHOD) {
satok1bc0a492012-04-25 22:47:12 +09002262 win.mGivenInsetsPending = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002263 mInputMethodWindow = win;
2264 addInputMethodWindowToListLocked(win);
2265 imMayMove = false;
Craig Mautner88400d32012-09-30 12:35:45 -07002266 } else if (type == TYPE_INPUT_METHOD_DIALOG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002267 mInputMethodDialogs.add(win);
2268 addWindowToListInOrderLocked(win, true);
Craig Mautnerc00204b2013-03-05 15:02:14 -08002269 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002270 imMayMove = false;
2271 } else {
2272 addWindowToListInOrderLocked(win, true);
Craig Mautner88400d32012-09-30 12:35:45 -07002273 if (type == TYPE_WALLPAPER) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002274 mLastWallpaperTimeoutTime = 0;
Craig Mautnerae446592012-12-06 19:05:05 -08002275 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002276 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Craig Mautnerae446592012-12-06 19:05:05 -08002277 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborn7ad44382012-10-18 17:46:00 -07002278 } else if (mWallpaperTarget != null
2279 && mWallpaperTarget.mLayer >= win.mBaseLayer) {
2280 // If there is currently a wallpaper being shown, and
2281 // the base layer of the new window is below the current
2282 // layer of the target window, then adjust the wallpaper.
2283 // This is to avoid a new window being placed between the
2284 // wallpaper and its target.
Craig Mautnerae446592012-12-06 19:05:05 -08002285 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002286 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002287 }
Romain Guy06882f82009-06-10 13:36:04 -07002288
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002289 win.mWinAnimator.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002290
Craig Mautner69b08182012-09-05 13:07:13 -07002291 if (displayContent.isDefaultDisplay) {
2292 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
2293 } else {
2294 outContentInsets.setEmpty();
2295 }
Romain Guy06882f82009-06-10 13:36:04 -07002296
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002297 if (mInTouchMode) {
Jeff Brown98365d72012-08-19 20:30:52 -07002298 res |= WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002299 }
Craig Mautner764983d2012-03-22 11:37:36 -07002300 if (win.mAppToken == null || !win.mAppToken.clientHidden) {
Jeff Brown98365d72012-08-19 20:30:52 -07002301 res |= WindowManagerGlobal.ADD_FLAG_APP_VISIBLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002302 }
Romain Guy06882f82009-06-10 13:36:04 -07002303
Jeff Brown2e44b072011-01-24 15:21:56 -08002304 mInputMonitor.setUpdateInputWindowsNeededLw();
2305
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002306 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002307 if (win.canReceiveKeys()) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002308 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
2309 false /*updateInputWindows*/);
Jeff Brown349703e2010-06-22 01:27:15 -07002310 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002311 imMayMove = false;
2312 }
2313 }
Romain Guy06882f82009-06-10 13:36:04 -07002314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002315 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002316 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002317 }
Romain Guy06882f82009-06-10 13:36:04 -07002318
Craig Mautner59c00972012-07-30 12:10:24 -07002319 assignLayersLocked(displayContent.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002320 // Don't do layout here, the window must call
2321 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002322
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002323 if (focusChanged) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002324 finishUpdateFocusedWindowAfterAssignLayersLocked(false /*updateInputWindows*/);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002325 }
Jeff Brown2e44b072011-01-24 15:21:56 -08002326 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08002327
Joe Onorato8a9b2202010-02-26 18:56:32 -08002328 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002329 TAG, "New client " + client.asBinder()
2330 + ": window=" + win);
Craig Mautner9e809442012-06-22 17:13:04 -07002331
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002332 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002333 reportNewConfig = true;
2334 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002335 }
2336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002337 if (reportNewConfig) {
2338 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002339 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07002340
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002341 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002342
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002343 return res;
2344 }
Romain Guy06882f82009-06-10 13:36:04 -07002345
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002346 public void removeWindow(Session session, IWindow client) {
2347 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002348 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002349 if (win == null) {
2350 return;
2351 }
2352 removeWindowLocked(session, win);
2353 }
2354 }
Romain Guy06882f82009-06-10 13:36:04 -07002355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002356 public void removeWindowLocked(Session session, WindowState win) {
2357
Joe Onorato8a9b2202010-02-26 18:56:32 -08002358 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002359 TAG, "Remove " + win + " client="
Craig Mautnerde4ef022013-04-07 19:01:33 -07002360 + Integer.toHexString(System.identityHashCode(win.mClient.asBinder()))
2361 + ", surface=" + win.mWinAnimator.mSurfaceControl,
2362 new RuntimeException("here").fillInStackTrace());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002363
2364 final long origId = Binder.clearCallingIdentity();
Craig Mautner764983d2012-03-22 11:37:36 -07002365
Jeff Brownc5ed5912010-07-14 18:48:53 -07002366 win.disposeInputChannel();
Romain Guy06882f82009-06-10 13:36:04 -07002367
Joe Onorato8a9b2202010-02-26 18:56:32 -08002368 if (DEBUG_APP_TRANSITIONS) Slog.v(
Mathias Agopian29479eb2013-02-14 14:36:04 -08002369 TAG, "Remove " + win + ": mSurface=" + win.mWinAnimator.mSurfaceControl
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002370 + " mExiting=" + win.mExiting
Craig Mautnera2c77052012-03-26 12:14:43 -07002371 + " isAnimating=" + win.mWinAnimator.isAnimating()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002372 + " app-animation="
Craig Mautner59431632012-04-04 11:56:44 -07002373 + (win.mAppToken != null ? win.mAppToken.mAppAnimator.animation : null)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002374 + " inPendingTransaction="
2375 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2376 + " mDisplayFrozen=" + mDisplayFrozen);
2377 // Visibility of the removed window. Will be used later to update orientation later on.
2378 boolean wasVisible = false;
2379 // First, see if we need to run an animation. If we do, we have
2380 // to hold off on removing the window until the animation is done.
2381 // If the display is frozen, just remove immediately, since the
2382 // animation wouldn't be seen.
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002383 if (win.mHasSurface && okToDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002384 // If we are not currently running the exit animation, we
2385 // need to see about starting one.
Craig Mautner764983d2012-03-22 11:37:36 -07002386 wasVisible = win.isWinVisibleLw();
2387 if (wasVisible) {
Romain Guy06882f82009-06-10 13:36:04 -07002388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002389 int transit = WindowManagerPolicy.TRANSIT_EXIT;
Craig Mautnerbb1449b2012-03-23 16:11:14 -07002390 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002391 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2392 }
2393 // Try starting an animation.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002394 if (win.mWinAnimator.applyAnimationLocked(transit, false)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002395 win.mExiting = true;
2396 }
Svetoslav Ganov545252f2012-12-10 18:29:24 -08002397 //TODO (multidisplay): Magnification is supported only for the default display.
2398 if (mDisplayMagnifier != null
2399 && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
2400 mDisplayMagnifier.onWindowTransitionLocked(win, transit);
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07002401 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002402 }
Craig Mautnera2c77052012-03-26 12:14:43 -07002403 if (win.mExiting || win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002404 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002405 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002406 win.mExiting = true;
2407 win.mRemoveOnExit = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07002408 win.mDisplayContent.layoutNeeded = true;
Jeff Brown3a22cd92011-01-21 13:59:04 -08002409 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2410 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002411 performLayoutAndPlaceSurfacesLocked();
2412 if (win.mAppToken != null) {
2413 win.mAppToken.updateReportedVisibilityLocked();
2414 }
2415 //dump();
2416 Binder.restoreCallingIdentity(origId);
2417 return;
2418 }
2419 }
2420
2421 removeWindowInnerLocked(session, win);
2422 // Removing a visible window will effect the computed orientation
2423 // So just update orientation if needed.
Craig Mautner2268e7e2012-12-13 15:40:00 -08002424 if (wasVisible && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002425 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002426 }
Jeff Brown3a22cd92011-01-21 13:59:04 -08002427 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002428 Binder.restoreCallingIdentity(origId);
2429 }
Romain Guy06882f82009-06-10 13:36:04 -07002430
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002431 private void removeWindowInnerLocked(Session session, WindowState win) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002432 if (win.mRemoved) {
2433 // Nothing to do.
2434 return;
2435 }
2436
2437 for (int i=win.mChildWindows.size()-1; i>=0; i--) {
2438 WindowState cwin = win.mChildWindows.get(i);
2439 Slog.w(TAG, "Force-removing child win " + cwin + " from container "
2440 + win);
2441 removeWindowInnerLocked(cwin.mSession, cwin);
2442 }
2443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002444 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002446 if (mInputMethodTarget == win) {
2447 moveInputMethodWindowsIfNeededLocked(false);
2448 }
Romain Guy06882f82009-06-10 13:36:04 -07002449
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002450 if (false) {
2451 RuntimeException e = new RuntimeException("here");
2452 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002453 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002454 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002456 mPolicy.removeWindowLw(win);
2457 win.removeLocked();
2458
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002459 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002460 mWindowMap.remove(win.mClient.asBinder());
Dianne Hackbornc2293022013-02-06 23:14:49 -08002461 if (win.mAppOp != AppOpsManager.OP_NONE) {
2462 mAppOps.finishOp(win.mAppOp, win.getOwningUid(), win.getOwningPackage());
2463 }
Craig Mautner59c00972012-07-30 12:10:24 -07002464
2465 final WindowList windows = win.getWindowList();
2466 windows.remove(win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002467 mPendingRemove.remove(win);
Craig Mautner860f6602012-10-18 09:38:10 -07002468 mResizingWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002469 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002470 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002471
2472 if (mInputMethodWindow == win) {
2473 mInputMethodWindow = null;
2474 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2475 mInputMethodDialogs.remove(win);
2476 }
Romain Guy06882f82009-06-10 13:36:04 -07002477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002478 final WindowToken token = win.mToken;
2479 final AppWindowToken atoken = win.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002480 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + win + " from " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002481 token.windows.remove(win);
2482 if (atoken != null) {
2483 atoken.allAppWindows.remove(win);
2484 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002485 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002486 TAG, "**** Removing window " + win + ": count="
2487 + token.windows.size());
2488 if (token.windows.size() == 0) {
2489 if (!token.explicit) {
2490 mTokenMap.remove(token.token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002491 } else if (atoken != null) {
2492 atoken.firstWindowDrawn = false;
2493 }
2494 }
2495
2496 if (atoken != null) {
2497 if (atoken.startingWindow == win) {
Craig Mautner38b24782012-07-02 16:21:28 -07002498 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling startingWindow " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002499 atoken.startingWindow = null;
2500 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2501 // If this is the last window and we had requested a starting
2502 // transition window, well there is no point now.
Craig Mautner38b24782012-07-02 16:21:28 -07002503 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling last startingWindow");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002504 atoken.startingData = null;
2505 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2506 // If this is the last window except for a starting transition
2507 // window, we need to get rid of the starting transition.
2508 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002509 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002510 + ": no more real windows");
2511 }
2512 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2513 mH.sendMessage(m);
2514 }
2515 }
Romain Guy06882f82009-06-10 13:36:04 -07002516
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002517 if (win.mAttrs.type == TYPE_WALLPAPER) {
2518 mLastWallpaperTimeoutTime = 0;
Craig Mautnerae446592012-12-06 19:05:05 -08002519 getDefaultDisplayContentLocked().pendingLayoutChanges |=
2520 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002521 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Craig Mautnerae446592012-12-06 19:05:05 -08002522 getDefaultDisplayContentLocked().pendingLayoutChanges |=
2523 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002524 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002526 if (!mInLayout) {
Craig Mautner59c00972012-07-30 12:10:24 -07002527 assignLayersLocked(windows);
Craig Mautner19d59bc2012-09-04 11:15:56 -07002528 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002529 performLayoutAndPlaceSurfacesLocked();
2530 if (win.mAppToken != null) {
2531 win.mAppToken.updateReportedVisibilityLocked();
2532 }
2533 }
Craig Mautner9e809442012-06-22 17:13:04 -07002534
Jeff Brown2e44b072011-01-24 15:21:56 -08002535 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002536 }
2537
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002538 public void updateAppOpsState() {
2539 synchronized(mWindowMap) {
Craig Mautnerf8924152013-07-16 09:10:55 -07002540 final int numDisplays = mDisplayContents.size();
2541 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2542 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
2543 final int numWindows = windows.size();
2544 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
2545 final WindowState win = windows.get(winNdx);
2546 if (win.mAppOp != AppOpsManager.OP_NONE) {
2547 final int mode = mAppOps.checkOpNoThrow(win.mAppOp, win.getOwningUid(),
2548 win.getOwningPackage());
2549 win.setAppOpVisibilityLw(mode == AppOpsManager.MODE_ALLOWED);
2550 }
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002551 }
2552 }
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002553 }
2554 }
2555
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002556 static void logSurface(WindowState w, String msg, RuntimeException where) {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002557 String str = " SURFACE " + msg + ": " + w;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002558 if (where != null) {
2559 Slog.i(TAG, str, where);
2560 } else {
2561 Slog.i(TAG, str);
2562 }
2563 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002564
Mathias Agopian3866f0d2013-02-11 22:08:48 -08002565 static void logSurface(SurfaceControl s, String title, String msg, RuntimeException where) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002566 String str = " SURFACE " + s + ": " + msg + " / " + title;
2567 if (where != null) {
2568 Slog.i(TAG, str, where);
2569 } else {
2570 Slog.i(TAG, str);
2571 }
2572 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07002573
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002574 void setTransparentRegionWindow(Session session, IWindow client, Region region) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002575 long origId = Binder.clearCallingIdentity();
2576 try {
2577 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002578 WindowState w = windowForClientLocked(session, client, false);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002579 if ((w != null) && w.mHasSurface) {
Craig Mautneref655012013-01-03 11:20:24 -08002580 w.mWinAnimator.setTransparentRegionHintLocked(region);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002581 }
2582 }
2583 } finally {
2584 Binder.restoreCallingIdentity(origId);
2585 }
2586 }
2587
2588 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002589 int touchableInsets, Rect contentInsets,
Jeff Brownfbf09772011-01-16 14:06:57 -08002590 Rect visibleInsets, Region touchableRegion) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002591 long origId = Binder.clearCallingIdentity();
2592 try {
2593 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002594 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002595 if (w != null) {
2596 w.mGivenInsetsPending = false;
2597 w.mGivenContentInsets.set(contentInsets);
2598 w.mGivenVisibleInsets.set(visibleInsets);
Jeff Brownfbf09772011-01-16 14:06:57 -08002599 w.mGivenTouchableRegion.set(touchableRegion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002600 w.mTouchableInsets = touchableInsets;
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002601 if (w.mGlobalScale != 1) {
2602 w.mGivenContentInsets.scale(w.mGlobalScale);
2603 w.mGivenVisibleInsets.scale(w.mGlobalScale);
2604 w.mGivenTouchableRegion.scale(w.mGlobalScale);
2605 }
Craig Mautner19d59bc2012-09-04 11:15:56 -07002606 w.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002607 performLayoutAndPlaceSurfacesLocked();
2608 }
2609 }
2610 } finally {
2611 Binder.restoreCallingIdentity(origId);
2612 }
2613 }
Romain Guy06882f82009-06-10 13:36:04 -07002614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002615 public void getWindowDisplayFrame(Session session, IWindow client,
2616 Rect outDisplayFrame) {
2617 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002618 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002619 if (win == null) {
2620 outDisplayFrame.setEmpty();
2621 return;
2622 }
2623 outDisplayFrame.set(win.mDisplayFrame);
2624 }
2625 }
2626
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002627 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2628 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002629 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2630 window.mWallpaperX = x;
2631 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002632 window.mWallpaperXStep = xStep;
2633 window.mWallpaperYStep = yStep;
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002634 updateWallpaperOffsetLocked(window, true);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002635 }
2636 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002637
Dianne Hackborn75804932009-10-20 20:15:20 -07002638 void wallpaperCommandComplete(IBinder window, Bundle result) {
2639 synchronized (mWindowMap) {
2640 if (mWaitingOnWallpaper != null &&
2641 mWaitingOnWallpaper.mClient.asBinder() == window) {
2642 mWaitingOnWallpaper = null;
2643 mWindowMap.notifyAll();
2644 }
2645 }
2646 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002647
Dianne Hackborn75804932009-10-20 20:15:20 -07002648 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2649 String action, int x, int y, int z, Bundle extras, boolean sync) {
2650 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2651 || window == mUpperWallpaperTarget) {
2652 boolean doWait = sync;
2653 int curTokenIndex = mWallpaperTokens.size();
2654 while (curTokenIndex > 0) {
2655 curTokenIndex--;
2656 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2657 int curWallpaperIndex = token.windows.size();
2658 while (curWallpaperIndex > 0) {
2659 curWallpaperIndex--;
2660 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2661 try {
2662 wallpaper.mClient.dispatchWallpaperCommand(action,
2663 x, y, z, extras, sync);
2664 // We only want to be synchronous with one wallpaper.
2665 sync = false;
2666 } catch (RemoteException e) {
2667 }
2668 }
2669 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002670
Dianne Hackborn75804932009-10-20 20:15:20 -07002671 if (doWait) {
2672 // XXX Need to wait for result.
2673 }
2674 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002675
Dianne Hackborn75804932009-10-20 20:15:20 -07002676 return null;
2677 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002678
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002679 public void setUniverseTransformLocked(WindowState window, float alpha,
2680 float offx, float offy, float dsdx, float dtdx, float dsdy, float dtdy) {
2681 Transformation transform = window.mWinAnimator.mUniverseTransform;
2682 transform.setAlpha(alpha);
2683 Matrix matrix = transform.getMatrix();
2684 matrix.getValues(mTmpFloats);
2685 mTmpFloats[Matrix.MTRANS_X] = offx;
2686 mTmpFloats[Matrix.MTRANS_Y] = offy;
2687 mTmpFloats[Matrix.MSCALE_X] = dsdx;
2688 mTmpFloats[Matrix.MSKEW_Y] = dtdx;
2689 mTmpFloats[Matrix.MSKEW_X] = dsdy;
2690 mTmpFloats[Matrix.MSCALE_Y] = dtdy;
2691 matrix.setValues(mTmpFloats);
Craig Mautner59c00972012-07-30 12:10:24 -07002692 final DisplayInfo displayInfo = window.mDisplayContent.getDisplayInfo();
Jeff Brownfa25bf52012-07-23 19:26:30 -07002693 final RectF dispRect = new RectF(0, 0,
Craig Mautner59c00972012-07-30 12:10:24 -07002694 displayInfo.logicalWidth, displayInfo.logicalHeight);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002695 matrix.mapRect(dispRect);
Jeff Brownfa25bf52012-07-23 19:26:30 -07002696 window.mGivenTouchableRegion.set(0, 0,
Craig Mautner59c00972012-07-30 12:10:24 -07002697 displayInfo.logicalWidth, displayInfo.logicalHeight);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002698 window.mGivenTouchableRegion.op((int)dispRect.left, (int)dispRect.top,
2699 (int)dispRect.right, (int)dispRect.bottom, Region.Op.DIFFERENCE);
2700 window.mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
Craig Mautner19d59bc2012-09-04 11:15:56 -07002701 window.mDisplayContent.layoutNeeded = true;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002702 performLayoutAndPlaceSurfacesLocked();
2703 }
2704
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002705 public void onRectangleOnScreenRequested(IBinder token, Rect rectangle, boolean immediate) {
2706 synchronized (mWindowMap) {
Svetoslav Ganov545252f2012-12-10 18:29:24 -08002707 if (mDisplayMagnifier != null) {
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07002708 WindowState window = mWindowMap.get(token);
Svetoslav Ganov545252f2012-12-10 18:29:24 -08002709 //TODO (multidisplay): Magnification is supported only for the default display.
2710 if (window != null && window.getDisplayId() == Display.DEFAULT_DISPLAY) {
2711 mDisplayMagnifier.onRectangleOnScreenRequestedLocked(rectangle, immediate);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002712 }
2713 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002714 }
2715 }
2716
Dianne Hackborne3f23a32013-03-01 13:25:35 -08002717 public IWindowId getWindowId(IBinder token) {
2718 synchronized (mWindowMap) {
2719 WindowState window = mWindowMap.get(token);
2720 return window != null ? window.mWindowId : null;
2721 }
2722 }
2723
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002724 public int relayoutWindow(Session session, IWindow client, int seq,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002725 WindowManager.LayoutParams attrs, int requestedWidth,
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002726 int requestedHeight, int viewVisibility, int flags,
Dianne Hackbornc4aad012013-02-22 15:05:25 -08002727 Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
Dianne Hackborn5c58de32012-04-28 19:52:37 -07002728 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07002729 boolean toBeDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002730 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002731 boolean configChanged;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002732 boolean surfaceChanged = false;
Dianne Hackborn12d3a942012-04-27 14:16:30 -07002733 boolean animating;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002734
2735 // if they don't have this permission, mask out the status bar bits
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002736 int systemUiVisibility = 0;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002737 if (attrs != null) {
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002738 systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
2739 if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -07002740 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
2741 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002742 systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
Dianne Hackborna44abeb2011-08-08 19:24:01 -07002743 }
Joe Onoratoac0ee892011-01-30 15:38:30 -08002744 }
2745 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002746 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002748 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002749 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002750 if (win == null) {
2751 return 0;
2752 }
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002753 WindowStateAnimator winAnimator = win.mWinAnimator;
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08002754 if (win.mRequestedWidth != requestedWidth
2755 || win.mRequestedHeight != requestedHeight) {
2756 win.mLayoutNeeded = true;
2757 win.mRequestedWidth = requestedWidth;
2758 win.mRequestedHeight = requestedHeight;
2759 }
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002760 if (attrs != null && seq == win.mSeq) {
2761 win.mSystemUiVisibility = systemUiVisibility;
2762 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002763
2764 if (attrs != null) {
2765 mPolicy.adjustWindowParamsLw(attrs);
2766 }
Romain Guy06882f82009-06-10 13:36:04 -07002767
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002768 winAnimator.mSurfaceDestroyDeferred =
Jeff Brown98365d72012-08-19 20:30:52 -07002769 (flags&WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002770
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002771 int attrChanges = 0;
2772 int flagChanges = 0;
2773 if (attrs != null) {
Dianne Hackborn0e60db22011-09-01 11:17:57 -07002774 if (win.mAttrs.type != attrs.type) {
2775 throw new IllegalArgumentException(
2776 "Window type can not be changed after the window is added.");
2777 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002778 flagChanges = win.mAttrs.flags ^= attrs.flags;
2779 attrChanges = win.mAttrs.copyFrom(attrs);
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002780 if ((attrChanges & (WindowManager.LayoutParams.LAYOUT_CHANGED
2781 | WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED)) != 0) {
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08002782 win.mLayoutNeeded = true;
2783 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002784 }
2785
Dianne Hackborn7ff30112012-11-08 11:12:09 -08002786 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": viewVisibility=" + viewVisibility
Chet Haased5d11af2012-10-31 08:57:17 -07002787 + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002788
Dianne Hackborn5fd21692011-06-07 14:09:47 -07002789 win.mEnforceSizeCompat = (win.mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0;
2790
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002791 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002792 winAnimator.mAlpha = attrs.alpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002793 }
2794
2795 final boolean scaledWindow =
2796 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2797
2798 if (scaledWindow) {
2799 // requested{Width|Height} Surface's physical size
2800 // attrs.{width|height} Size on screen
2801 win.mHScale = (attrs.width != requestedWidth) ?
2802 (attrs.width / (float)requestedWidth) : 1.0f;
2803 win.mVScale = (attrs.height != requestedHeight) ?
2804 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002805 } else {
2806 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002807 }
2808
Craig Mautner65d11b32012-10-01 13:59:52 -07002809 boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002810
Craig Mautner69b08182012-09-05 13:07:13 -07002811 final boolean isDefaultDisplay = win.isDefaultDisplay();
2812 boolean focusMayChange = isDefaultDisplay && (win.mViewVisibility != viewVisibility
Craig Mautner65d11b32012-10-01 13:59:52 -07002813 || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0)
Craig Mautner69b08182012-09-05 13:07:13 -07002814 || (!win.mRelayoutCalled));
Romain Guy06882f82009-06-10 13:36:04 -07002815
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002816 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2817 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07002818 wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002819
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002820 win.mRelayoutCalled = true;
2821 final int oldVisibility = win.mViewVisibility;
2822 win.mViewVisibility = viewVisibility;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07002823 if (DEBUG_SCREEN_ON) {
2824 RuntimeException stack = new RuntimeException();
2825 stack.fillInStackTrace();
2826 Slog.i(TAG, "Relayout " + win + ": oldVis=" + oldVisibility
2827 + " newVis=" + viewVisibility, stack);
2828 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002829 if (viewVisibility == View.VISIBLE &&
2830 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07002831 toBeDisplayed = !win.isVisibleLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002832 if (win.mExiting) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002833 winAnimator.cancelExitAnimationForNextAnimationLocked();
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002834 win.mExiting = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002835 }
2836 if (win.mDestroying) {
2837 win.mDestroying = false;
2838 mDestroySurface.remove(win);
2839 }
2840 if (oldVisibility == View.GONE) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002841 winAnimator.mEnterAnimationPending = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002842 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002843 if (toBeDisplayed) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07002844 if (win.isDrawnLw() && okToDisplay()) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002845 winAnimator.applyEnterAnimationLocked();
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002846 }
2847 if ((win.mAttrs.flags
2848 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2849 if (DEBUG_VISIBILITY) Slog.v(TAG,
2850 "Relayout window turning screen on: " + win);
2851 win.mTurnOnScreen = true;
2852 }
Craig Mautnera3f4bf52012-10-10 20:37:48 -07002853 if (win.isConfigChanged()) {
2854 if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + win
Craig Mautnere8552142012-11-07 13:55:47 -08002855 + " visible with new config: " + mCurConfiguration);
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002856 outConfig.setTo(mCurConfiguration);
2857 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002858 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002859 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2860 // To change the format, we need to re-build the surface.
Craig Mautner96868332012-12-04 14:29:11 -08002861 winAnimator.destroySurfaceLocked();
Craig Mautnerbf08af32012-05-16 19:43:42 -07002862 toBeDisplayed = true;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002863 surfaceChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002864 }
2865 try {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002866 if (!win.mHasSurface) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002867 surfaceChanged = true;
2868 }
Mathias Agopian29479eb2013-02-14 14:36:04 -08002869 SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
2870 if (surfaceControl != null) {
2871 outSurface.copyFrom(surfaceControl);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002872 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002873 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002874 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002875 // For some reason there isn't a surface. Clear the
2876 // caller's object so they see the same state.
2877 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002878 }
2879 } catch (Exception e) {
Jeff Brown2e44b072011-01-24 15:21:56 -08002880 mInputMonitor.updateInputWindowsLw(true /*force*/);
Craig Mautner9e809442012-06-22 17:13:04 -07002881
Joe Onorato8a9b2202010-02-26 18:56:32 -08002882 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002883 + client + " (" + win.mAttrs.getTitle() + ")",
2884 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002885 Binder.restoreCallingIdentity(origId);
2886 return 0;
2887 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002888 if (toBeDisplayed) {
Craig Mautner69b08182012-09-05 13:07:13 -07002889 focusMayChange = isDefaultDisplay;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002890 }
2891 if (win.mAttrs.type == TYPE_INPUT_METHOD
2892 && mInputMethodWindow == null) {
2893 mInputMethodWindow = win;
2894 imMayMove = true;
2895 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002896 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2897 && win.mAppToken != null
2898 && win.mAppToken.startingWindow != null) {
2899 // Special handling of starting window over the base
2900 // window of the app: propagate lock screen flags to it,
2901 // to provide the correct semantics while starting.
2902 final int mask =
2903 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002904 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2905 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002906 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2907 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2908 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002909 } else {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002910 winAnimator.mEnterAnimationPending = false;
Mathias Agopian29479eb2013-02-14 14:36:04 -08002911 if (winAnimator.mSurfaceControl != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002912 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Craig Mautnerbf08af32012-05-16 19:43:42 -07002913 + ": mExiting=" + win.mExiting);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002914 // If we are not currently running the exit animation, we
2915 // need to see about starting one.
Craig Mautnerbf08af32012-05-16 19:43:42 -07002916 if (!win.mExiting) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002917 surfaceChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002918 // Try starting an animation; if there isn't one, we
2919 // can destroy the surface right away.
2920 int transit = WindowManagerPolicy.TRANSIT_EXIT;
Craig Mautnerbb1449b2012-03-23 16:11:14 -07002921 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002922 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2923 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002924 if (win.isWinVisibleLw() &&
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002925 winAnimator.applyAnimationLocked(transit, false)) {
Craig Mautner69b08182012-09-05 13:07:13 -07002926 focusMayChange = isDefaultDisplay;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002927 win.mExiting = true;
Craig Mautnera2c77052012-03-26 12:14:43 -07002928 } else if (win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002929 // Currently in a hide animation... turn this into
2930 // an exit.
2931 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002932 } else if (win == mWallpaperTarget) {
2933 // If the wallpaper is currently behind this
2934 // window, we need to change both of them inside
2935 // of a transaction to avoid artifacts.
2936 win.mExiting = true;
Craig Mautnera2c77052012-03-26 12:14:43 -07002937 win.mWinAnimator.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002938 } else {
2939 if (mInputMethodWindow == win) {
2940 mInputMethodWindow = null;
2941 }
Craig Mautner96868332012-12-04 14:29:11 -08002942 winAnimator.destroySurfaceLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002943 }
Svetoslav Ganov545252f2012-12-10 18:29:24 -08002944 //TODO (multidisplay): Magnification is supported only for the default
2945 if (mDisplayMagnifier != null
2946 && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
2947 mDisplayMagnifier.onWindowTransitionLocked(win, transit);
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07002948 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002949 }
2950 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002951
Craig Mautnerbf08af32012-05-16 19:43:42 -07002952 outSurface.release();
2953 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002954 }
2955
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002956 if (focusMayChange) {
2957 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
Jeff Brown3a22cd92011-01-21 13:59:04 -08002958 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2959 false /*updateInputWindows*/)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002960 imMayMove = false;
2961 }
2962 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2963 }
Romain Guy06882f82009-06-10 13:36:04 -07002964
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002965 // updateFocusedWindowLocked() already assigned layers so we only need to
2966 // reassign them at this point if the IM window state gets shuffled
Craig Mautnerb5eb5502013-01-10 17:29:30 -08002967 if (imMayMove && (moveInputMethodWindowsIfNeededLocked(false) || toBeDisplayed)) {
2968 // Little hack here -- we -should- be able to rely on the
2969 // function to return true if the IME has moved and needs
2970 // its layer recomputed. However, if the IME was hidden
2971 // and isn't actually moved in the list, its layer may be
2972 // out of data so we make sure to recompute it.
2973 assignLayersLocked(win.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002974 }
Craig Mautnerb5eb5502013-01-10 17:29:30 -08002975
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002976 if (wallpaperMayMove) {
Craig Mautnerae446592012-12-06 19:05:05 -08002977 getDefaultDisplayContentLocked().pendingLayoutChanges |=
2978 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002979 }
Romain Guy06882f82009-06-10 13:36:04 -07002980
Craig Mautner19d59bc2012-09-04 11:15:56 -07002981 win.mDisplayContent.layoutNeeded = true;
Jeff Brown98365d72012-08-19 20:30:52 -07002982 win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002983 configChanged = updateOrientationFromAppTokensLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002984 performLayoutAndPlaceSurfacesLocked();
Craig Mautnerbf08af32012-05-16 19:43:42 -07002985 if (toBeDisplayed && win.mIsWallpaper) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07002986 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Jeff Brownfa25bf52012-07-23 19:26:30 -07002987 updateWallpaperOffsetLocked(win,
Craig Mautner59c00972012-07-30 12:10:24 -07002988 displayInfo.appWidth, displayInfo.appHeight, false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002989 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002990 if (win.mAppToken != null) {
2991 win.mAppToken.updateReportedVisibilityLocked();
2992 }
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002993 outFrame.set(win.mCompatFrame);
Dianne Hackbornc4aad012013-02-22 15:05:25 -08002994 outOverscanInsets.set(win.mOverscanInsets);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002995 outContentInsets.set(win.mContentInsets);
2996 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002997 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002998 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002999 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003000 + ", requestedHeight=" + requestedHeight
3001 + ", viewVisibility=" + viewVisibility
3002 + "\nRelayout returning frame=" + outFrame
3003 + ", surface=" + outSurface);
3004
Joe Onorato8a9b2202010-02-26 18:56:32 -08003005 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003006 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
3007
3008 inTouchMode = mInTouchMode;
Dianne Hackborn12d3a942012-04-27 14:16:30 -07003009 animating = mAnimator.mAnimating;
3010 if (animating && !mRelayoutWhileAnimating.contains(win)) {
3011 mRelayoutWhileAnimating.add(win);
3012 }
3013
Jeff Brown2e44b072011-01-24 15:21:56 -08003014 mInputMonitor.updateInputWindowsLw(true /*force*/);
Chet Haased5d11af2012-10-31 08:57:17 -07003015
3016 if (DEBUG_LAYOUT) {
3017 Slog.v(TAG, "Relayout complete " + win + ": outFrame=" + outFrame.toShortString());
3018 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003019 }
3020
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003021 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003022 sendNewConfiguration();
3023 }
Romain Guy06882f82009-06-10 13:36:04 -07003024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003025 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07003026
Jeff Brown98365d72012-08-19 20:30:52 -07003027 return (inTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0)
3028 | (toBeDisplayed ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0)
3029 | (surfaceChanged ? WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED : 0)
3030 | (animating ? WindowManagerGlobal.RELAYOUT_RES_ANIMATING : 0);
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003031 }
3032
3033 public void performDeferredDestroyWindow(Session session, IWindow client) {
3034 long origId = Binder.clearCallingIdentity();
3035
3036 try {
Craig Mautnerae446592012-12-06 19:05:05 -08003037 synchronized (mWindowMap) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003038 WindowState win = windowForClientLocked(session, client, false);
3039 if (win == null) {
3040 return;
3041 }
Craig Mautner96868332012-12-04 14:29:11 -08003042 win.mWinAnimator.destroyDeferredSurfaceLocked();
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003043 }
3044 } finally {
3045 Binder.restoreCallingIdentity(origId);
3046 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003047 }
3048
Dianne Hackborn64825172011-03-02 21:32:58 -08003049 public boolean outOfMemoryWindow(Session session, IWindow client) {
3050 long origId = Binder.clearCallingIdentity();
3051
3052 try {
Craig Mautnerae446592012-12-06 19:05:05 -08003053 synchronized (mWindowMap) {
Dianne Hackborn64825172011-03-02 21:32:58 -08003054 WindowState win = windowForClientLocked(session, client, false);
3055 if (win == null) {
3056 return false;
3057 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003058 return reclaimSomeSurfaceMemoryLocked(win.mWinAnimator, "from-client", false);
Dianne Hackborn64825172011-03-02 21:32:58 -08003059 }
3060 } finally {
3061 Binder.restoreCallingIdentity(origId);
3062 }
3063 }
3064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003065 public void finishDrawingWindow(Session session, IWindow client) {
3066 final long origId = Binder.clearCallingIdentity();
Craig Mautneref655012013-01-03 11:20:24 -08003067 try {
3068 synchronized (mWindowMap) {
3069 WindowState win = windowForClientLocked(session, client, false);
3070 if (win != null && win.mWinAnimator.finishDrawingLocked()) {
3071 if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
3072 getDefaultDisplayContentLocked().pendingLayoutChanges |=
3073 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
3074 }
3075 win.mDisplayContent.layoutNeeded = true;
3076 requestTraversalLocked();
Dianne Hackborn759a39e2009-08-09 17:20:27 -07003077 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003078 }
Craig Mautneref655012013-01-03 11:20:24 -08003079 } finally {
3080 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003081 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003082 }
3083
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003084 @Override
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07003085 public void getWindowFrame(IBinder token, Rect outBounds) {
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003086 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
3087 "getWindowInfo()")) {
3088 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
3089 }
3090 synchronized (mWindowMap) {
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07003091 WindowState windowState = mWindowMap.get(token);
3092 if (windowState != null) {
3093 outBounds.set(windowState.mFrame);
3094 } else {
3095 outBounds.setEmpty();
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003096 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003097 }
3098 }
3099
3100 @Override
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003101 public void setMagnificationSpec(MagnificationSpec spec) {
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07003102 if (!checkCallingPermission(android.Manifest.permission.MAGNIFY_DISPLAY,
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003103 "setMagnificationSpec()")) {
3104 throw new SecurityException("Requires MAGNIFY_DISPLAY permission.");
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003105 }
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003106 synchronized (mWindowMap) {
3107 if (mDisplayMagnifier != null) {
3108 mDisplayMagnifier.setMagnificationSpecLocked(spec);
3109 } else {
3110 throw new IllegalStateException("Magnification callbacks not set!");
3111 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003112 }
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003113 if (Binder.getCallingPid() != android.os.Process.myPid()) {
3114 spec.recycle();
3115 }
3116 }
3117
3118 @Override
3119 public MagnificationSpec getCompatibleMagnificationSpecForWindow(IBinder windowToken) {
3120 if (!checkCallingPermission(android.Manifest.permission.MAGNIFY_DISPLAY,
3121 "getCompatibleMagnificationSpecForWindow()")) {
3122 throw new SecurityException("Requires MAGNIFY_DISPLAY permission.");
3123 }
3124 synchronized (mWindowMap) {
3125 WindowState windowState = mWindowMap.get(windowToken);
3126 if (windowState == null) {
3127 return null;
3128 }
3129 MagnificationSpec spec = null;
3130 if (mDisplayMagnifier != null) {
3131 spec = mDisplayMagnifier.getMagnificationSpecForWindowLocked(windowState);
3132 }
3133 if ((spec == null || spec.isNop()) && windowState.mGlobalScale == 1.0f) {
3134 return null;
3135 }
3136 spec = (spec == null) ? MagnificationSpec.obtain() : MagnificationSpec.obtain(spec);
3137 spec.scale *= windowState.mGlobalScale;
3138 return spec;
3139 }
3140 }
3141
3142 @Override
3143 public void setMagnificationCallbacks(IMagnificationCallbacks callbacks) {
3144 if (!checkCallingPermission(android.Manifest.permission.MAGNIFY_DISPLAY,
3145 "setMagnificationCallbacks()")) {
3146 throw new SecurityException("Requires MAGNIFY_DISPLAY permission.");
3147 }
3148 synchronized (mWindowMap) {
3149 if (mDisplayMagnifier == null) {
3150 mDisplayMagnifier = new DisplayMagnifier(this, callbacks);
3151 } else {
3152 if (callbacks == null) {
Svetoslavcb9a61b2013-01-22 18:11:42 -08003153 if (mDisplayMagnifier != null) {
3154 mDisplayMagnifier.destroyLocked();
3155 mDisplayMagnifier = null;
3156 }
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003157 } else {
3158 throw new IllegalStateException("Magnification callbacks already set!");
3159 }
3160 }
3161 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003162 }
3163
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003164 private boolean applyAnimationLocked(AppWindowToken atoken,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07003165 WindowManager.LayoutParams lp, int transit, boolean enter) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003166 // Only apply an animation if the display isn't frozen. If it is
3167 // frozen, there is no reason to animate and it can cause strange
3168 // artifacts when we unfreeze the display if some different animation
3169 // is running.
Craig Mautner2fb98b12012-03-20 17:24:00 -07003170 if (okToDisplay()) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003171 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Craig Mautner9339c402012-11-30 11:23:56 -08003172 final int width = displayInfo.appWidth;
3173 final int height = displayInfo.appHeight;
Craig Mautner164d4bb2012-11-26 13:51:23 -08003174 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "applyAnimation: atoken="
3175 + atoken);
Craig Mautner9339c402012-11-30 11:23:56 -08003176 Animation a = mAppTransition.loadAnimation(lp, transit, enter, width, height);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003177 if (a != null) {
3178 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003179 RuntimeException e = null;
3180 if (!HIDE_STACK_CRAWLS) {
3181 e = new RuntimeException();
3182 e.fillInStackTrace();
3183 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003184 Slog.v(TAG, "Loaded animation " + a + " for " + atoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003185 }
Craig Mautner9339c402012-11-30 11:23:56 -08003186 atoken.mAppAnimator.setAnimation(a, width, height);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003187 }
3188 } else {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003189 atoken.mAppAnimator.clearAnimation();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003190 }
3191
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003192 return atoken.mAppAnimator.animation != null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003193 }
3194
3195 // -------------------------------------------------------------
3196 // Application Window Tokens
3197 // -------------------------------------------------------------
3198
Craig Mautner00af9fe2013-03-25 09:13:41 -07003199 public void validateAppTokens(int stackId, List<TaskGroup> tasks) {
Craig Mautner343ad712013-02-13 22:37:26 -08003200 synchronized (mWindowMap) {
3201 int t = tasks.size() - 1;
3202 if (t < 0) {
3203 Slog.w(TAG, "validateAppTokens: empty task list");
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08003204 return;
3205 }
3206
Craig Mautner343ad712013-02-13 22:37:26 -08003207 TaskGroup task = tasks.get(0);
3208 int taskId = task.taskId;
Craig Mautnerc00204b2013-03-05 15:02:14 -08003209 Task targetTask = mTaskIdToTask.get(taskId);
3210 DisplayContent displayContent = targetTask.getDisplayContent();
Craig Mautner343ad712013-02-13 22:37:26 -08003211 if (displayContent == null) {
3212 Slog.w(TAG, "validateAppTokens: no Display for taskId=" + taskId);
3213 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003214 }
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08003215
Craig Mautner00af9fe2013-03-25 09:13:41 -07003216 final ArrayList<Task> localTasks = mStackIdToStack.get(stackId).getTasks();
Craig Mautnerf81b90872013-02-26 13:02:43 -08003217 int taskNdx;
3218 for (taskNdx = localTasks.size() - 1; taskNdx >= 0 && t >= 0; --taskNdx, --t) {
3219 AppTokenList localTokens = localTasks.get(taskNdx).mAppTokens;
Craig Mautner343ad712013-02-13 22:37:26 -08003220 task = tasks.get(t);
3221 List<IApplicationToken> tokens = task.tokens;
Craig Mautner343ad712013-02-13 22:37:26 -08003222
3223 DisplayContent lastDisplayContent = displayContent;
Craig Mautnerc00204b2013-03-05 15:02:14 -08003224 displayContent = mTaskIdToTask.get(taskId).getDisplayContent();
Craig Mautner343ad712013-02-13 22:37:26 -08003225 if (displayContent != lastDisplayContent) {
3226 Slog.w(TAG, "validateAppTokens: displayContent changed in TaskGroup list!");
3227 return;
3228 }
3229
Craig Mautnerf81b90872013-02-26 13:02:43 -08003230 int tokenNdx;
3231 int v;
3232 for (tokenNdx = localTokens.size() - 1, v = task.tokens.size() - 1;
3233 tokenNdx >= 0 && v >= 0; ) {
3234 final AppWindowToken atoken = localTokens.get(tokenNdx);
Craig Mautner343ad712013-02-13 22:37:26 -08003235 if (atoken.removed) {
Craig Mautnerf81b90872013-02-26 13:02:43 -08003236 --tokenNdx;
Craig Mautner343ad712013-02-13 22:37:26 -08003237 continue;
3238 }
3239 if (tokens.get(v) != atoken.token) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08003240 break;
Craig Mautner343ad712013-02-13 22:37:26 -08003241 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08003242 --tokenNdx;
Craig Mautner343ad712013-02-13 22:37:26 -08003243 v--;
3244 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08003245
3246 if (tokenNdx >= 0 || v >= 0) {
3247 break;
3248 }
Craig Mautner343ad712013-02-13 22:37:26 -08003249 }
3250
Craig Mautnerf81b90872013-02-26 13:02:43 -08003251 if (taskNdx >= 0 || t >= 0) {
Craig Mautner11bf9a52013-02-19 14:08:51 -08003252 Slog.w(TAG, "validateAppTokens: Mismatch! ActivityManager=" + tasks);
Craig Mautner1d001b62013-06-18 16:52:43 -07003253 Slog.w(TAG, "validateAppTokens: Mismatch! WindowManager=" + localTasks);
Craig Mautnerb44de0d2013-02-21 20:00:58 -08003254 Slog.w(TAG, "validateAppTokens: Mismatch! Callers=" + Debug.getCallers(4));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003255 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003256 }
3257 }
3258
Craig Mautner00af9fe2013-03-25 09:13:41 -07003259 public void validateStackOrder(Integer[] remoteStackIds) {
3260 // TODO:
3261 }
3262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003263 boolean checkCallingPermission(String permission, String func) {
3264 // Quick check: if the calling permission is me, it's all okay.
3265 if (Binder.getCallingPid() == Process.myPid()) {
3266 return true;
3267 }
Romain Guy06882f82009-06-10 13:36:04 -07003268
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003269 if (mContext.checkCallingPermission(permission)
3270 == PackageManager.PERMISSION_GRANTED) {
3271 return true;
3272 }
3273 String msg = "Permission Denial: " + func + " from pid="
3274 + Binder.getCallingPid()
3275 + ", uid=" + Binder.getCallingUid()
3276 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003277 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003278 return false;
3279 }
Craig Mautner9e809442012-06-22 17:13:04 -07003280
Craig Mautner2fb98b12012-03-20 17:24:00 -07003281 boolean okToDisplay() {
3282 return !mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully();
3283 }
Romain Guy06882f82009-06-10 13:36:04 -07003284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003285 AppWindowToken findAppWindowToken(IBinder token) {
3286 WindowToken wtoken = mTokenMap.get(token);
3287 if (wtoken == null) {
3288 return null;
3289 }
3290 return wtoken.appWindowToken;
3291 }
Romain Guy06882f82009-06-10 13:36:04 -07003292
Craig Mautnercf8cbbe2012-03-25 21:54:36 -07003293 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003294 public void addWindowToken(IBinder token, int type) {
3295 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3296 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003297 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003298 }
Romain Guy06882f82009-06-10 13:36:04 -07003299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003300 synchronized(mWindowMap) {
3301 WindowToken wtoken = mTokenMap.get(token);
3302 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003303 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003304 return;
3305 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003306 wtoken = new WindowToken(this, token, type, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003307 mTokenMap.put(token, wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003308 if (type == TYPE_WALLPAPER) {
3309 mWallpaperTokens.add(wtoken);
3310 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003311 }
3312 }
Romain Guy06882f82009-06-10 13:36:04 -07003313
Craig Mautner9e809442012-06-22 17:13:04 -07003314 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003315 public void removeWindowToken(IBinder token) {
3316 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3317 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003318 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003319 }
3320
3321 final long origId = Binder.clearCallingIdentity();
3322 synchronized(mWindowMap) {
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08003323 DisplayContent displayContent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003324 WindowToken wtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003325 if (wtoken != null) {
3326 boolean delayed = false;
3327 if (!wtoken.hidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003328 final int N = wtoken.windows.size();
3329 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003330
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003331 for (int i=0; i<N; i++) {
3332 WindowState win = wtoken.windows.get(i);
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08003333 displayContent = win.mDisplayContent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003334
Craig Mautnera2c77052012-03-26 12:14:43 -07003335 if (win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003336 delayed = true;
3337 }
Romain Guy06882f82009-06-10 13:36:04 -07003338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003339 if (win.isVisibleNow()) {
Craig Mautner59c00972012-07-30 12:10:24 -07003340 win.mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT,
3341 false);
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003342 //TODO (multidisplay): Magnification is supported only for the default
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08003343 if (mDisplayMagnifier != null && win.isDefaultDisplay()) {
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003344 mDisplayMagnifier.onWindowTransitionLocked(win,
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07003345 WindowManagerPolicy.TRANSIT_EXIT);
3346 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003347 changed = true;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08003348 displayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003349 }
3350 }
3351
Craig Mautner4b5aa782012-10-02 18:11:25 -07003352 wtoken.hidden = true;
3353
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003354 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003355 performLayoutAndPlaceSurfacesLocked();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003356 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
3357 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003358 }
Romain Guy06882f82009-06-10 13:36:04 -07003359
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003360 if (delayed) {
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08003361 displayContent.mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003362 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3363 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003364 }
3365 }
Romain Guy06882f82009-06-10 13:36:04 -07003366
Jeff Brown2e44b072011-01-24 15:21:56 -08003367 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003368 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003369 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003370 }
3371 }
3372 Binder.restoreCallingIdentity(origId);
3373 }
3374
Craig Mautneref25d7a2012-05-15 23:01:47 -07003375 @Override
Craig Mautnerc00204b2013-03-05 15:02:14 -08003376 public void addAppToken(int addPos, IApplicationToken token, int taskId, int stackId,
3377 int requestedOrientation, boolean fullscreen, boolean showWhenLocked) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003378 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3379 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003380 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003381 }
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07003382
Jeff Brown349703e2010-06-22 01:27:15 -07003383 // Get the dispatching timeout here while we are not holding any locks so that it
3384 // can be cached by the AppWindowToken. The timeout value is used later by the
3385 // input dispatcher in code that does hold locks. If we did not cache the value
3386 // here we would run the chance of introducing a deadlock between the window manager
3387 // (which holds locks while updating the input dispatcher state) and the activity manager
3388 // (which holds locks while querying the application token).
3389 long inputDispatchingTimeoutNanos;
3390 try {
3391 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3392 } catch (RemoteException ex) {
3393 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3394 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3395 }
Romain Guy06882f82009-06-10 13:36:04 -07003396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003397 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003398 AppWindowToken atoken = findAppWindowToken(token.asBinder());
3399 if (atoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003400 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003401 return;
3402 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003403 atoken = new AppWindowToken(this, token);
3404 atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08003405 atoken.groupId = taskId;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003406 atoken.appFullscreen = fullscreen;
Craig Mautner5962b122012-10-05 14:45:52 -07003407 atoken.showWhenLocked = showWhenLocked;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003408 atoken.requestedOrientation = requestedOrientation;
3409 if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + atoken
Craig Mautner06a94f72012-05-29 10:46:00 -07003410 + " at " + addPos);
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08003411
Craig Mautnerc00204b2013-03-05 15:02:14 -08003412 Task task = mTaskIdToTask.get(taskId);
3413 if (task == null) {
3414 TaskStack stack = mStackIdToStack.get(stackId);
3415 if (stack == null) {
3416 throw new IllegalArgumentException("addAppToken: invalid stackId=" + stackId);
3417 }
3418 task = new Task(atoken, stack);
Craig Mautnerd9a22882013-03-16 15:00:36 -07003419 stack.addTask(task, true);
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07003420 stack.getDisplayContent().moveStack(stack, true);
Craig Mautnerc00204b2013-03-05 15:02:14 -08003421 mTaskIdToTask.put(taskId, task);
Craig Mautnerc00204b2013-03-05 15:02:14 -08003422 } else {
3423 task.addAppToken(addPos, atoken);
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08003424 }
Craig Mautnerc00204b2013-03-05 15:02:14 -08003425
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003426 mTokenMap.put(token.asBinder(), atoken);
Romain Guy06882f82009-06-10 13:36:04 -07003427
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003428 // Application tokens start out hidden.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003429 atoken.hidden = true;
3430 atoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003431
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003432 //dump();
3433 }
3434 }
Romain Guy06882f82009-06-10 13:36:04 -07003435
Craig Mautner9e809442012-06-22 17:13:04 -07003436 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003437 public void setAppGroupId(IBinder token, int groupId) {
3438 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner6fbda632012-07-03 09:26:39 -07003439 "setAppGroupId()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003440 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003441 }
3442
3443 synchronized(mWindowMap) {
Craig Mautner32b44d02013-02-21 08:26:06 -08003444 final AppWindowToken atoken = findAppWindowToken(token);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003445 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003446 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003447 return;
3448 }
Craig Mautnerc00204b2013-03-05 15:02:14 -08003449 Task oldTask = mTaskIdToTask.get(atoken.groupId);
3450 oldTask.removeAppToken(atoken);
3451
3452 atoken.groupId = groupId;
3453 Task newTask = mTaskIdToTask.get(groupId);
3454 if (newTask == null) {
3455 throw new IllegalStateException("setAppGroupId: groupId=" + groupId
3456 + " does not exist");
Craig Mautner32b44d02013-02-21 08:26:06 -08003457 }
Craig Mautnerc00204b2013-03-05 15:02:14 -08003458 newTask.mAppTokens.add(atoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003459 }
3460 }
Romain Guy06882f82009-06-10 13:36:04 -07003461
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003462 public int getOrientationFromWindowsLocked() {
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003463 if (mDisplayFrozen || mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
3464 // If the display is frozen, some activities may be in the middle
3465 // of restarting, and thus have removed their old window. If the
3466 // window has the flag to hide the lock screen, then the lock screen
3467 // can re-appear and inflict its own orientation on us. Keep the
3468 // orientation stable until this all settles down.
3469 return mLastWindowForcedOrientation;
3470 }
3471
Craig Mautner59c00972012-07-30 12:10:24 -07003472 // TODO(multidisplay): Change to the correct display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003473 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07003474 int pos = windows.size() - 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003475 while (pos >= 0) {
Craig Mautnere8552142012-11-07 13:55:47 -08003476 WindowState win = windows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003477 pos--;
Craig Mautnere8552142012-11-07 13:55:47 -08003478 if (win.mAppToken != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003479 // We hit an application window. so the orientation will be determined by the
3480 // app window. No point in continuing further.
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003481 return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003482 }
Craig Mautnere8552142012-11-07 13:55:47 -08003483 if (!win.isVisibleLw() || !win.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003484 continue;
3485 }
Craig Mautnere8552142012-11-07 13:55:47 -08003486 int req = win.mAttrs.screenOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003487 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3488 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3489 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003490 }
Craig Mautner9e809442012-06-22 17:13:04 -07003491
Craig Mautnere8552142012-11-07 13:55:47 -08003492 if (DEBUG_ORIENTATION) Slog.v(TAG, win + " forcing orientation to " + req);
Craig Mautner9e809442012-06-22 17:13:04 -07003493 return (mLastWindowForcedOrientation=req);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003494 }
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003495 return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003496 }
Romain Guy06882f82009-06-10 13:36:04 -07003497
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003498 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003499 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3500 boolean findingBehind = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003501 boolean lastFullscreen = false;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08003502 // TODO: Multi window.
3503 DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautnerd9a22882013-03-16 15:00:36 -07003504 final ArrayList<Task> tasks = displayContent.getTasks();
Craig Mautnerf81b90872013-02-26 13:02:43 -08003505 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
3506 AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
Craig Mautnerd9a22882013-03-16 15:00:36 -07003507 final int firstToken = tokens.size() - 1;
3508 for (int tokenNdx = firstToken; tokenNdx >= 0; --tokenNdx) {
Craig Mautnerf81b90872013-02-26 13:02:43 -08003509 final AppWindowToken atoken = tokens.get(tokenNdx);
Craig Mautnerc5a6e442013-06-05 17:22:35 -07003510
Craig Mautnerf81b90872013-02-26 13:02:43 -08003511 if (DEBUG_APP_ORIENTATION) Slog.v(TAG, "Checking app orientation: " + atoken);
Craig Mautnerc5a6e442013-06-05 17:22:35 -07003512
Craig Mautnerf81b90872013-02-26 13:02:43 -08003513 // if we're about to tear down this window and not seek for
3514 // the behind activity, don't use it for orientation
3515 if (!findingBehind
3516 && (!atoken.hidden && atoken.hiddenRequested)) {
3517 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
3518 + " -- going to hide");
3519 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003520 }
Craig Mautnerc5a6e442013-06-05 17:22:35 -07003521
Craig Mautnerd9a22882013-03-16 15:00:36 -07003522 if (tokenNdx == firstToken) {
3523 // If we have hit a new Task, and the bottom
Craig Mautnerf81b90872013-02-26 13:02:43 -08003524 // of the previous group didn't explicitly say to use
3525 // the orientation behind it, and the last app was
3526 // full screen, then we'll stick with the
3527 // user's orientation.
3528 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3529 && lastFullscreen) {
3530 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
3531 + " -- end of group, return " + lastOrientation);
3532 return lastOrientation;
3533 }
3534 }
Craig Mautnerc5a6e442013-06-05 17:22:35 -07003535
Craig Mautnerf81b90872013-02-26 13:02:43 -08003536 // We ignore any hidden applications on the top.
3537 if (atoken.hiddenRequested || atoken.willBeHidden) {
3538 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
3539 + " -- hidden on top");
3540 continue;
3541 }
Craig Mautnerc5a6e442013-06-05 17:22:35 -07003542
Craig Mautnerd9a22882013-03-16 15:00:36 -07003543 if (tokenNdx == 0) {
3544 // Last token in this task.
Craig Mautnerf81b90872013-02-26 13:02:43 -08003545 lastOrientation = atoken.requestedOrientation;
3546 }
Craig Mautnerc5a6e442013-06-05 17:22:35 -07003547
Craig Mautnerf81b90872013-02-26 13:02:43 -08003548 int or = atoken.requestedOrientation;
3549 // If this application is fullscreen, and didn't explicitly say
3550 // to use the orientation behind it, then just take whatever
3551 // orientation it has and ignores whatever is under it.
3552 lastFullscreen = atoken.appFullscreen;
3553 if (lastFullscreen
3554 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3555 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
3556 + " -- full screen, return " + or);
3557 return or;
3558 }
3559 // If this application has requested an explicit orientation,
3560 // then use it.
3561 if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
3562 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3563 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
3564 + " -- explicitly set, return " + or);
3565 return or;
3566 }
3567 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003568 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003569 }
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003570 if (DEBUG_ORIENTATION) Slog.v(TAG, "No app is requesting an orientation");
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003571 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003572 }
Romain Guy06882f82009-06-10 13:36:04 -07003573
Craig Mautner711f90a2012-07-03 18:43:52 -07003574 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003575 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003576 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003577 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3578 "updateOrientationFromAppTokens()")) {
3579 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3580 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003581
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003582 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003583 long ident = Binder.clearCallingIdentity();
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003584
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003585 synchronized(mWindowMap) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003586 config = updateOrientationFromAppTokensLocked(currentConfig,
3587 freezeThisOneIfNeeded);
3588 }
3589
3590 Binder.restoreCallingIdentity(ident);
3591 return config;
3592 }
3593
3594 private Configuration updateOrientationFromAppTokensLocked(
3595 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
3596 Configuration config = null;
3597
3598 if (updateOrientationFromAppTokensLocked(false)) {
3599 if (freezeThisOneIfNeeded != null) {
Craig Mautner2268e7e2012-12-13 15:40:00 -08003600 AppWindowToken atoken = findAppWindowToken(freezeThisOneIfNeeded);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003601 if (atoken != null) {
Craig Mautner2268e7e2012-12-13 15:40:00 -08003602 startAppFreezingScreenLocked(atoken, ActivityInfo.CONFIG_ORIENTATION);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003603 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003604 }
3605 config = computeNewConfigurationLocked();
3606
3607 } else if (currentConfig != null) {
3608 // No obvious action we need to take, but if our current
3609 // state mismatches the activity manager's, update it,
3610 // disregarding font scale, which should remain set to
3611 // the value of the previous configuration.
3612 mTempConfiguration.setToDefaults();
3613 mTempConfiguration.fontScale = currentConfig.fontScale;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08003614 if (computeScreenConfigurationLocked(mTempConfiguration)) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003615 if (currentConfig.diff(mTempConfiguration) != 0) {
3616 mWaitingForConfig = true;
Craig Mautner05d29032013-05-03 13:40:13 -07003617 final DisplayContent displayContent = getDefaultDisplayContentLocked();
3618 displayContent.layoutNeeded = true;
Craig Mautner3c174372013-02-21 17:54:37 -08003619 int anim[] = new int[2];
Craig Mautner05d29032013-05-03 13:40:13 -07003620 if (displayContent.isDimming()) {
Craig Mautner3c174372013-02-21 17:54:37 -08003621 anim[0] = anim[1] = 0;
3622 } else {
3623 mPolicy.selectRotationAnimationLw(anim);
3624 }
3625 startFreezingDisplayLocked(false, anim[0], anim[1]);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003626 config = new Configuration(mTempConfiguration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003627 }
3628 }
3629 }
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003630
Dianne Hackborncfaef692009-06-15 14:24:44 -07003631 return config;
3632 }
3633
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003634 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003635 * Determine the new desired orientation of the display, returning
3636 * a non-null new Configuration if it has changed from the current
3637 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3638 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3639 * SCREEN. This will typically be done for you if you call
3640 * sendNewConfiguration().
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003641 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003642 * The orientation is computed from non-application windows first. If none of
3643 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003644 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003645 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3646 * android.os.IBinder)
3647 */
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003648 boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003649 long ident = Binder.clearCallingIdentity();
3650 try {
Craig Mautner2268e7e2012-12-13 15:40:00 -08003651 int req = getOrientationFromWindowsLocked();
3652 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3653 req = getOrientationFromAppTokensLocked();
3654 }
Romain Guy06882f82009-06-10 13:36:04 -07003655
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003656 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003657 mForcedAppOrientation = req;
3658 //send a message to Policy indicating orientation change to take
3659 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003660 mPolicy.setCurrentOrientationLw(req);
Jeff Brown01a98dd2011-09-20 15:08:29 -07003661 if (updateRotationUncheckedLocked(inTransaction)) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003662 // changed
3663 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003664 }
3665 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003666
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003667 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003668 } finally {
3669 Binder.restoreCallingIdentity(ident);
3670 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003671 }
Romain Guy06882f82009-06-10 13:36:04 -07003672
Craig Mautner918b53b2012-07-09 14:15:54 -07003673 @Override
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003674 public void setNewConfiguration(Configuration config) {
3675 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3676 "setNewConfiguration()")) {
3677 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3678 }
3679
3680 synchronized(mWindowMap) {
3681 mCurConfiguration = new Configuration(config);
Dianne Hackborna57c6952013-03-29 14:46:40 -07003682 if (mWaitingForConfig) {
3683 mWaitingForConfig = false;
3684 mLastFinishedFreezeSource = "new-config";
3685 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003686 performLayoutAndPlaceSurfacesLocked();
3687 }
3688 }
Craig Mautner918b53b2012-07-09 14:15:54 -07003689
3690 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003691 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3692 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3693 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003694 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003695 }
Romain Guy06882f82009-06-10 13:36:04 -07003696
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003697 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003698 AppWindowToken atoken = findAppWindowToken(token.asBinder());
3699 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003700 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003701 return;
3702 }
Romain Guy06882f82009-06-10 13:36:04 -07003703
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003704 atoken.requestedOrientation = requestedOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003705 }
3706 }
Romain Guy06882f82009-06-10 13:36:04 -07003707
Craig Mautner76a71652012-09-03 23:23:58 -07003708 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003709 public int getAppOrientation(IApplicationToken token) {
3710 synchronized(mWindowMap) {
3711 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3712 if (wtoken == null) {
3713 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3714 }
Romain Guy06882f82009-06-10 13:36:04 -07003715
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003716 return wtoken.requestedOrientation;
3717 }
3718 }
Romain Guy06882f82009-06-10 13:36:04 -07003719
Craig Mautnerf7666462013-04-28 08:58:21 -07003720 /** Call while in a Surface transaction. */
3721 void setFocusedStackLayer() {
3722 mFocusedStackLayer = 0;
Craig Mautner05d29032013-05-03 13:40:13 -07003723 if (mFocusedApp != null) {
3724 final WindowList windows = mFocusedApp.allAppWindows;
3725 for (int i = windows.size() - 1; i >= 0; --i) {
3726 final WindowState win = windows.get(i);
3727 final int animLayer = win.mWinAnimator.mAnimLayer;
3728 if (win.mAttachedWindow == null && win.isVisibleLw() &&
3729 animLayer > mFocusedStackLayer) {
3730 mFocusedStackLayer = animLayer + LAYER_OFFSET_FOCUSED_STACK;
3731 }
Craig Mautnerf7666462013-04-28 08:58:21 -07003732 }
3733 }
3734 if (DEBUG_LAYERS) Slog.v(TAG, "Setting FocusedStackFrame to layer=" +
3735 mFocusedStackLayer);
3736 mFocusedStackFrame.setLayer(mFocusedStackLayer);
3737 }
3738
3739 void setFocusedStackFrame() {
3740 final TaskStack stack;
3741 if (mFocusedApp != null) {
3742 Task task = mTaskIdToTask.get(mFocusedApp.groupId);
3743 stack = task.mStack;
Craig Mautner6601b7b2013-04-29 10:29:11 -07003744 task.getDisplayContent().setTouchExcludeRegion(stack);
Craig Mautnerf7666462013-04-28 08:58:21 -07003745 } else {
3746 stack = null;
3747 }
Craig Mautnera9a3fb12013-04-18 10:01:00 -07003748 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setFocusedStackFrame");
3749 SurfaceControl.openTransaction();
3750 try {
3751 if (stack == null) {
3752 mFocusedStackFrame.setVisibility(false);
3753 } else {
3754 final StackBox box = stack.mStackBox;
3755 final Rect bounds = box.mBounds;
3756 final boolean multipleStacks = box.mParent != null;
3757 mFocusedStackFrame.setBounds(bounds);
3758 mFocusedStackFrame.setVisibility(multipleStacks);
3759 }
3760 } finally {
3761 SurfaceControl.closeTransaction();
3762 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> CLOSE TRANSACTION setFocusedStackFrame");
3763 }
3764 }
3765
Craig Mautner76a71652012-09-03 23:23:58 -07003766 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003767 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3768 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3769 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003770 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003771 }
3772
3773 synchronized(mWindowMap) {
3774 boolean changed = false;
3775 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003776 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003777 changed = mFocusedApp != null;
3778 mFocusedApp = null;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003779 if (changed) {
3780 mInputMonitor.setFocusedAppLw(null);
Jeff Brown349703e2010-06-22 01:27:15 -07003781 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003782 } else {
3783 AppWindowToken newFocus = findAppWindowToken(token);
3784 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003785 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003786 return;
3787 }
3788 changed = mFocusedApp != newFocus;
3789 mFocusedApp = newFocus;
Craig Mautner812d2ca2012-09-27 15:35:34 -07003790 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp
3791 + " moveFocusNow=" + moveFocusNow);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003792 if (changed) {
3793 mInputMonitor.setFocusedAppLw(newFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07003794 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003795 }
3796
3797 if (moveFocusNow && changed) {
3798 final long origId = Binder.clearCallingIdentity();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003799 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003800 Binder.restoreCallingIdentity(origId);
3801 }
3802 }
3803 }
3804
Craig Mautner76a71652012-09-03 23:23:58 -07003805 @Override
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003806 public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003807 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3808 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003809 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003810 }
Romain Guy06882f82009-06-10 13:36:04 -07003811
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003812 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003813 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003814 TAG, "Prepare app transition: transit=" + transit
Craig Mautner164d4bb2012-11-26 13:51:23 -08003815 + " " + mAppTransition
Craig Mautner1d961d42012-05-27 12:02:11 -07003816 + " alwaysKeepCurrent=" + alwaysKeepCurrent
Craig Mautneref25d7a2012-05-15 23:01:47 -07003817 + " Callers=" + Debug.getCallers(3));
Craig Mautner2fb98b12012-03-20 17:24:00 -07003818 if (okToDisplay()) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003819 if (!mAppTransition.isTransitionSet() || mAppTransition.isTransitionNone()) {
3820 mAppTransition.setAppTransition(transit);
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003821 } else if (!alwaysKeepCurrent) {
Craig Mautner4b71aa12012-12-27 17:20:01 -08003822 if (transit == AppTransition.TRANSIT_TASK_OPEN
Craig Mautner164d4bb2012-11-26 13:51:23 -08003823 && mAppTransition.isTransitionEqual(
Craig Mautner4b71aa12012-12-27 17:20:01 -08003824 AppTransition.TRANSIT_TASK_CLOSE)) {
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003825 // Opening a new task always supersedes a close for the anim.
Craig Mautner164d4bb2012-11-26 13:51:23 -08003826 mAppTransition.setAppTransition(transit);
Craig Mautner4b71aa12012-12-27 17:20:01 -08003827 } else if (transit == AppTransition.TRANSIT_ACTIVITY_OPEN
Craig Mautner164d4bb2012-11-26 13:51:23 -08003828 && mAppTransition.isTransitionEqual(
Craig Mautner4b71aa12012-12-27 17:20:01 -08003829 AppTransition.TRANSIT_ACTIVITY_CLOSE)) {
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003830 // Opening a new activity always supersedes a close for the anim.
Craig Mautner164d4bb2012-11-26 13:51:23 -08003831 mAppTransition.setAppTransition(transit);
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003832 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003833 }
Craig Mautner164d4bb2012-11-26 13:51:23 -08003834 mAppTransition.prepare();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003835 mStartingIconInTransition = false;
3836 mSkipAppTransitionAnimation = false;
3837 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
You Kimcb6291c2012-12-04 23:22:28 +09003838 mH.sendEmptyMessageDelayed(H.APP_TRANSITION_TIMEOUT, 5000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003839 }
3840 }
3841 }
3842
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003843 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003844 public int getPendingAppTransition() {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003845 return mAppTransition.getAppTransition();
Dianne Hackborn84375872012-06-01 19:03:50 -07003846 }
3847
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003848 @Override
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003849 public void overridePendingAppTransition(String packageName,
Dianne Hackborn84375872012-06-01 19:03:50 -07003850 int enterAnim, int exitAnim, IRemoteCallback startedCallback) {
3851 synchronized(mWindowMap) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003852 mAppTransition.overridePendingAppTransition(packageName, enterAnim, exitAnim,
3853 startedCallback);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003854 }
3855 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003856
Craig Mautnera91f9e22012-09-14 16:22:08 -07003857 @Override
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003858 public void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
3859 int startHeight) {
Dianne Hackborn84375872012-06-01 19:03:50 -07003860 synchronized(mWindowMap) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003861 mAppTransition.overridePendingAppTransitionScaleUp(startX, startY, startWidth,
3862 startHeight);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003863 }
3864 }
3865
Craig Mautnera91f9e22012-09-14 16:22:08 -07003866 @Override
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003867 public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX,
Michael Jurka832cb222012-04-13 09:32:47 -07003868 int startY, IRemoteCallback startedCallback, boolean scaleUp) {
Dianne Hackborn84375872012-06-01 19:03:50 -07003869 synchronized(mWindowMap) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003870 mAppTransition.overridePendingAppTransitionThumb(srcThumb, startX, startY,
3871 startedCallback, scaleUp);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003872 }
3873 }
3874
Craig Mautnera91f9e22012-09-14 16:22:08 -07003875 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003876 public void executeAppTransition() {
3877 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3878 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003879 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003880 }
Romain Guy06882f82009-06-10 13:36:04 -07003881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003882 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003883 if (DEBUG_APP_TRANSITIONS) {
3884 RuntimeException e = new RuntimeException("here");
3885 e.fillInStackTrace();
Craig Mautner164d4bb2012-11-26 13:51:23 -08003886 Slog.w(TAG, "Execute app transition: " + mAppTransition, e);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003887 }
Craig Mautner164d4bb2012-11-26 13:51:23 -08003888 if (mAppTransition.isTransitionSet()) {
Craig Mautnerae446592012-12-06 19:05:05 -08003889 mAppTransition.setReady();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003890 final long origId = Binder.clearCallingIdentity();
3891 performLayoutAndPlaceSurfacesLocked();
3892 Binder.restoreCallingIdentity(origId);
3893 }
3894 }
3895 }
3896
Craig Mautnere6f7d5052012-10-08 10:34:17 -07003897 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003898 public void setAppStartingWindow(IBinder token, String pkg,
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07003899 int theme, CompatibilityInfo compatInfo,
Adam Powell04fe6eb2013-05-31 14:39:48 -07003900 CharSequence nonLocalizedLabel, int labelRes, int icon, int logo,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003901 int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003902 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner6fbda632012-07-03 09:26:39 -07003903 "setAppStartingWindow()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003904 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003905 }
3906
3907 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003908 if (DEBUG_STARTING_WINDOW) Slog.v(
Craig Mautner8863cca2012-09-18 15:04:34 -07003909 TAG, "setAppStartingWindow: token=" + token + " pkg=" + pkg
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003910 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003911
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003912 AppWindowToken wtoken = findAppWindowToken(token);
3913 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003914 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003915 return;
3916 }
3917
3918 // If the display is frozen, we won't do anything until the
3919 // actual window is displayed so there is no reason to put in
3920 // the starting window.
Craig Mautner2fb98b12012-03-20 17:24:00 -07003921 if (!okToDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003922 return;
3923 }
Romain Guy06882f82009-06-10 13:36:04 -07003924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003925 if (wtoken.startingData != null) {
3926 return;
3927 }
Romain Guy06882f82009-06-10 13:36:04 -07003928
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003929 if (transferFrom != null) {
3930 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3931 if (ttoken != null) {
3932 WindowState startingWindow = ttoken.startingWindow;
3933 if (startingWindow != null) {
3934 if (mStartingIconInTransition) {
3935 // In this case, the starting icon has already
3936 // been displayed, so start letting windows get
3937 // shown immediately without any more transitions.
3938 mSkipAppTransitionAnimation = true;
3939 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003940 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
Craig Mautner8863cca2012-09-18 15:04:34 -07003941 "Moving existing starting " + startingWindow + " from " + ttoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003942 + " to " + wtoken);
3943 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003944
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003945 // Transfer the starting window over to the new
3946 // token.
3947 wtoken.startingData = ttoken.startingData;
3948 wtoken.startingView = ttoken.startingView;
Craig Mautnerf4120952012-06-21 18:25:39 -07003949 wtoken.startingDisplayed = ttoken.startingDisplayed;
Craig Mautner8863cca2012-09-18 15:04:34 -07003950 ttoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003951 wtoken.startingWindow = startingWindow;
Craig Mautnerf4120952012-06-21 18:25:39 -07003952 wtoken.reportedVisible = ttoken.reportedVisible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003953 ttoken.startingData = null;
3954 ttoken.startingView = null;
3955 ttoken.startingWindow = null;
3956 ttoken.startingMoved = true;
3957 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003958 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003959 startingWindow.mAppToken = wtoken;
Craig Mautner8863cca2012-09-18 15:04:34 -07003960 startingWindow.mWinAnimator.mAppAnimator = wtoken.mAppAnimator;
3961
Craig Mautner6fbda632012-07-03 09:26:39 -07003962 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) {
3963 Slog.v(TAG, "Removing starting window: " + startingWindow);
3964 }
Craig Mautner59c00972012-07-30 12:10:24 -07003965 startingWindow.getWindowList().remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07003966 mWindowsChanged = true;
Craig Mautner6fbda632012-07-03 09:26:39 -07003967 if (DEBUG_ADD_REMOVE) Slog.v(TAG,
3968 "Removing starting " + startingWindow + " from " + ttoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003969 ttoken.windows.remove(startingWindow);
3970 ttoken.allAppWindows.remove(startingWindow);
3971 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003973 // Propagate other interesting state between the
3974 // tokens. If the old token is displayed, we should
3975 // immediately force the new one to be displayed. If
3976 // it is animating, we need to move that animation to
3977 // the new one.
3978 if (ttoken.allDrawn) {
3979 wtoken.allDrawn = true;
Craig Mautner7636dfb2012-11-16 15:24:11 -08003980 wtoken.deferClearAllDrawn = ttoken.deferClearAllDrawn;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003981 }
3982 if (ttoken.firstWindowDrawn) {
3983 wtoken.firstWindowDrawn = true;
3984 }
3985 if (!ttoken.hidden) {
3986 wtoken.hidden = false;
3987 wtoken.hiddenRequested = false;
3988 wtoken.willBeHidden = false;
3989 }
3990 if (wtoken.clientHidden != ttoken.clientHidden) {
3991 wtoken.clientHidden = ttoken.clientHidden;
3992 wtoken.sendAppVisibilityToClients();
3993 }
Craig Mautner59431632012-04-04 11:56:44 -07003994 final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
3995 final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
3996 if (tAppAnimator.animation != null) {
3997 wAppAnimator.animation = tAppAnimator.animation;
3998 wAppAnimator.animating = tAppAnimator.animating;
3999 wAppAnimator.animLayerAdjustment = tAppAnimator.animLayerAdjustment;
4000 tAppAnimator.animation = null;
4001 tAppAnimator.animLayerAdjustment = 0;
4002 wAppAnimator.updateLayers();
4003 tAppAnimator.updateLayers();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004004 }
Romain Guy06882f82009-06-10 13:36:04 -07004005
Jeff Brown3a22cd92011-01-21 13:59:04 -08004006 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4007 true /*updateInputWindows*/);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07004008 getDefaultDisplayContentLocked().layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004009 performLayoutAndPlaceSurfacesLocked();
4010 Binder.restoreCallingIdentity(origId);
4011 return;
4012 } else if (ttoken.startingData != null) {
4013 // The previous app was getting ready to show a
4014 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004015 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004016 "Moving pending starting from " + ttoken
4017 + " to " + wtoken);
4018 wtoken.startingData = ttoken.startingData;
4019 ttoken.startingData = null;
4020 ttoken.startingMoved = true;
4021 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
4022 // Note: we really want to do sendMessageAtFrontOfQueue() because we
4023 // want to process the message ASAP, before any other queued
4024 // messages.
4025 mH.sendMessageAtFrontOfQueue(m);
4026 return;
4027 }
Craig Mautner59431632012-04-04 11:56:44 -07004028 final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
4029 final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
4030 if (tAppAnimator.thumbnail != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004031 // The old token is animating with a thumbnail, transfer
4032 // that to the new token.
Craig Mautner59431632012-04-04 11:56:44 -07004033 if (wAppAnimator.thumbnail != null) {
4034 wAppAnimator.thumbnail.destroy();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004035 }
Craig Mautner59431632012-04-04 11:56:44 -07004036 wAppAnimator.thumbnail = tAppAnimator.thumbnail;
4037 wAppAnimator.thumbnailX = tAppAnimator.thumbnailX;
4038 wAppAnimator.thumbnailY = tAppAnimator.thumbnailY;
4039 wAppAnimator.thumbnailLayer = tAppAnimator.thumbnailLayer;
4040 wAppAnimator.thumbnailAnimation = tAppAnimator.thumbnailAnimation;
4041 tAppAnimator.thumbnail = null;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004042 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004043 }
4044 }
4045
4046 // There is no existing starting window, and the caller doesn't
4047 // want us to create one, so that's it!
4048 if (!createIfNeeded) {
4049 return;
4050 }
Romain Guy06882f82009-06-10 13:36:04 -07004051
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08004052 // If this is a translucent window, then don't
Dianne Hackborn284ac932009-08-28 10:34:25 -07004053 // show a starting window -- the current effect (a full-screen
4054 // opaque starting window that fades away to the real contents
4055 // when it is ready) does not work for this.
Craig Mautner6fbda632012-07-03 09:26:39 -07004056 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Checking theme of starting window: 0x"
4057 + Integer.toHexString(theme));
Dianne Hackborn284ac932009-08-28 10:34:25 -07004058 if (theme != 0) {
4059 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
Amith Yamasani4befbec2013-07-10 16:18:01 -07004060 com.android.internal.R.styleable.Window, mCurrentUserId);
Dianne Hackborn0b800192012-06-21 15:29:36 -07004061 if (ent == null) {
4062 // Whoops! App doesn't exist. Um. Okay. We'll just
4063 // pretend like we didn't see that.
4064 return;
4065 }
Craig Mautner6fbda632012-07-03 09:26:39 -07004066 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Translucent="
4067 + ent.array.getBoolean(
4068 com.android.internal.R.styleable.Window_windowIsTranslucent, false)
4069 + " Floating="
4070 + ent.array.getBoolean(
4071 com.android.internal.R.styleable.Window_windowIsFloating, false)
4072 + " ShowWallpaper="
4073 + ent.array.getBoolean(
4074 com.android.internal.R.styleable.Window_windowShowWallpaper, false));
Dianne Hackborn284ac932009-08-28 10:34:25 -07004075 if (ent.array.getBoolean(
4076 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
4077 return;
4078 }
4079 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07004080 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
4081 return;
4082 }
4083 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07004084 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08004085 if (mWallpaperTarget == null) {
4086 // If this theme is requesting a wallpaper, and the wallpaper
4087 // is not curently visible, then this effectively serves as
4088 // an opaque window and our starting window transition animation
4089 // can still work. We just need to make sure the starting window
4090 // is also showing the wallpaper.
Craig Mautner65d11b32012-10-01 13:59:52 -07004091 windowFlags |= FLAG_SHOW_WALLPAPER;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08004092 } else {
4093 return;
4094 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07004095 }
4096 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004097
Craig Mautner6fbda632012-07-03 09:26:39 -07004098 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Creating StartingData");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004099 mStartingIconInTransition = true;
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07004100 wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
Adam Powell04fe6eb2013-05-31 14:39:48 -07004101 labelRes, icon, logo, windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004102 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
4103 // Note: we really want to do sendMessageAtFrontOfQueue() because we
4104 // want to process the message ASAP, before any other queued
4105 // messages.
Craig Mautner6fbda632012-07-03 09:26:39 -07004106 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Enqueueing ADD_STARTING");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004107 mH.sendMessageAtFrontOfQueue(m);
4108 }
4109 }
4110
Craig Mautner312eac42012-11-13 10:56:22 -08004111 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004112 public void setAppWillBeHidden(IBinder token) {
4113 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4114 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004115 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004116 }
4117
4118 AppWindowToken wtoken;
4119
4120 synchronized(mWindowMap) {
4121 wtoken = findAppWindowToken(token);
4122 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004123 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 -08004124 return;
4125 }
4126 wtoken.willBeHidden = true;
4127 }
4128 }
Romain Guy06882f82009-06-10 13:36:04 -07004129
Craig Mautner5eda9b32013-07-02 11:58:16 -07004130 public void setAppFullscreen(IBinder token, boolean toOpaque) {
Craig Mautner4addfc52013-06-25 08:05:45 -07004131 AppWindowToken atoken = findAppWindowToken(token);
4132 if (atoken != null) {
Craig Mautner5eda9b32013-07-02 11:58:16 -07004133 atoken.appFullscreen = toOpaque;
4134 requestTraversal();
Craig Mautner4addfc52013-06-25 08:05:45 -07004135 }
4136 }
4137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004138 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004139 boolean visible, int transit, boolean performLayout) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004140 boolean delayed = false;
4141
4142 if (wtoken.clientHidden == visible) {
4143 wtoken.clientHidden = !visible;
4144 wtoken.sendAppVisibilityToClients();
4145 }
Romain Guy06882f82009-06-10 13:36:04 -07004146
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004147 wtoken.willBeHidden = false;
4148 if (wtoken.hidden == visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004149 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004150 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004151 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
4152 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07004153
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004154 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07004155
Craig Mautner4b71aa12012-12-27 17:20:01 -08004156 if (transit != AppTransition.TRANSIT_UNSET) {
Craig Mautnerfbf378c2012-04-23 17:24:21 -07004157 if (wtoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) {
Craig Mautner59431632012-04-04 11:56:44 -07004158 wtoken.mAppAnimator.animation = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004159 }
Craig Mautnerf20588f2012-04-11 17:06:21 -07004160 if (applyAnimationLocked(wtoken, lp, transit, visible)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004161 delayed = runningAppAnimation = true;
4162 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07004163 WindowState window = wtoken.findMainWindow();
Svetoslav Ganov545252f2012-12-10 18:29:24 -08004164 //TODO (multidisplay): Magnification is supported only for the default display.
4165 if (window != null && mDisplayMagnifier != null
4166 && window.getDisplayId() == Display.DEFAULT_DISPLAY) {
Craig Mautner4b71aa12012-12-27 17:20:01 -08004167 mDisplayMagnifier.onAppWindowTransitionLocked(window, transit);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07004168 }
Craig Mautnerf20588f2012-04-11 17:06:21 -07004169 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004170 }
Romain Guy06882f82009-06-10 13:36:04 -07004171
Craig Mautnerf20588f2012-04-11 17:06:21 -07004172 final int N = wtoken.allAppWindows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004173 for (int i=0; i<N; i++) {
4174 WindowState win = wtoken.allAppWindows.get(i);
4175 if (win == wtoken.startingWindow) {
4176 continue;
4177 }
4178
Joe Onorato8a9b2202010-02-26 18:56:32 -08004179 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004180 //win.dump(" ");
4181 if (visible) {
4182 if (!win.isVisibleNow()) {
4183 if (!runningAppAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07004184 win.mWinAnimator.applyAnimationLocked(
4185 WindowManagerPolicy.TRANSIT_ENTER, true);
Svetoslav Ganov545252f2012-12-10 18:29:24 -08004186 //TODO (multidisplay): Magnification is supported only for the default
4187 if (mDisplayMagnifier != null
4188 && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
4189 mDisplayMagnifier.onWindowTransitionLocked(win,
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07004190 WindowManagerPolicy.TRANSIT_ENTER);
4191 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004192 }
4193 changed = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07004194 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004195 }
4196 } else if (win.isVisibleNow()) {
4197 if (!runningAppAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07004198 win.mWinAnimator.applyAnimationLocked(
4199 WindowManagerPolicy.TRANSIT_EXIT, false);
Svetoslav Ganov545252f2012-12-10 18:29:24 -08004200 //TODO (multidisplay): Magnification is supported only for the default
4201 if (mDisplayMagnifier != null
4202 && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
4203 mDisplayMagnifier.onWindowTransitionLocked(win,
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07004204 WindowManagerPolicy.TRANSIT_EXIT);
4205 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004206 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004207 changed = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07004208 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004209 }
4210 }
4211
4212 wtoken.hidden = wtoken.hiddenRequested = !visible;
4213 if (!visible) {
4214 unsetAppFreezingScreenLocked(wtoken, true, true);
4215 } else {
4216 // If we are being set visible, and the starting window is
4217 // not yet displayed, then make sure it doesn't get displayed.
4218 WindowState swin = wtoken.startingWindow;
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07004219 if (swin != null && !swin.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004220 swin.mPolicyVisibility = false;
4221 swin.mPolicyVisibilityAfterAnim = false;
4222 }
4223 }
Romain Guy06882f82009-06-10 13:36:04 -07004224
Joe Onorato8a9b2202010-02-26 18:56:32 -08004225 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004226 + ": hidden=" + wtoken.hidden + " hiddenRequested="
4227 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07004228
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004229 if (changed) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08004230 mInputMonitor.setUpdateInputWindowsNeededLw();
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004231 if (performLayout) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08004232 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4233 false /*updateInputWindows*/);
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004234 performLayoutAndPlaceSurfacesLocked();
4235 }
Jeff Brown2e44b072011-01-24 15:21:56 -08004236 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004237 }
4238 }
4239
Craig Mautner59431632012-04-04 11:56:44 -07004240 if (wtoken.mAppAnimator.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004241 delayed = true;
4242 }
Romain Guy06882f82009-06-10 13:36:04 -07004243
Craig Mautnerf20588f2012-04-11 17:06:21 -07004244 for (int i = wtoken.allAppWindows.size() - 1; i >= 0 && !delayed; i--) {
4245 if (wtoken.allAppWindows.get(i).mWinAnimator.isWindowAnimating()) {
4246 delayed = true;
4247 }
4248 }
4249
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004250 return delayed;
4251 }
4252
Craig Mautner312eac42012-11-13 10:56:22 -08004253 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004254 public void setAppVisibility(IBinder token, boolean visible) {
4255 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4256 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004257 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004258 }
4259
4260 AppWindowToken wtoken;
4261
4262 synchronized(mWindowMap) {
4263 wtoken = findAppWindowToken(token);
4264 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004265 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004266 return;
4267 }
4268
4269 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004270 RuntimeException e = null;
4271 if (!HIDE_STACK_CRAWLS) {
4272 e = new RuntimeException();
4273 e.fillInStackTrace();
4274 }
Craig Mautner0afddcb2012-05-08 15:38:00 -07004275 Slog.v(TAG, "setAppVisibility(" + token + ", visible=" + visible
Craig Mautner164d4bb2012-11-26 13:51:23 -08004276 + "): " + mAppTransition
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004277 + " hidden=" + wtoken.hidden
4278 + " hiddenRequested=" + wtoken.hiddenRequested, e);
4279 }
Romain Guy06882f82009-06-10 13:36:04 -07004280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004281 // If we are preparing an app transition, then delay changing
4282 // the visibility of this token until we execute that transition.
Craig Mautner164d4bb2012-11-26 13:51:23 -08004283 if (okToDisplay() && mAppTransition.isTransitionSet()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004284 // Already in requested state, don't do anything more.
4285 if (wtoken.hiddenRequested != visible) {
4286 return;
4287 }
4288 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07004289
Craig Mautnerf4120952012-06-21 18:25:39 -07004290 if (!wtoken.startingDisplayed) {
Craig Mautner8863cca2012-09-18 15:04:34 -07004291 if (DEBUG_APP_TRANSITIONS) Slog.v(
4292 TAG, "Setting dummy animation on: " + wtoken);
Craig Mautnerf4120952012-06-21 18:25:39 -07004293 wtoken.mAppAnimator.setDummyAnimation();
4294 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004295 mOpeningApps.remove(wtoken);
4296 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004297 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004298 wtoken.inPendingTransaction = true;
4299 if (visible) {
4300 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004301 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004302
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004303 // If the token is currently hidden (should be the
4304 // common case), then we need to set up to wait for
4305 // its windows to be ready.
4306 if (wtoken.hidden) {
4307 wtoken.allDrawn = false;
Craig Mautner7636dfb2012-11-16 15:24:11 -08004308 wtoken.deferClearAllDrawn = false;
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004309 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004310
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004311 if (wtoken.clientHidden) {
4312 // In the case where we are making an app visible
4313 // but holding off for a transition, we still need
4314 // to tell the client to make its windows visible so
4315 // they get drawn. Otherwise, we will wait on
4316 // performing the transition until all windows have
4317 // been drawn, they never will be, and we are sad.
4318 wtoken.clientHidden = false;
4319 wtoken.sendAppVisibilityToClients();
4320 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004321 }
4322 } else {
4323 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004324
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004325 // If the token is currently visible (should be the
4326 // common case), then set up to wait for it to be hidden.
4327 if (!wtoken.hidden) {
4328 wtoken.waitingToHide = true;
4329 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004330 }
4331 return;
4332 }
Romain Guy06882f82009-06-10 13:36:04 -07004333
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004334 final long origId = Binder.clearCallingIdentity();
Craig Mautner4b71aa12012-12-27 17:20:01 -08004335 setTokenVisibilityLocked(wtoken, null, visible, AppTransition.TRANSIT_UNSET,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004336 true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004337 wtoken.updateReportedVisibilityLocked();
4338 Binder.restoreCallingIdentity(origId);
4339 }
4340 }
4341
4342 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
4343 boolean unfreezeSurfaceNow, boolean force) {
Craig Mautner59431632012-04-04 11:56:44 -07004344 if (wtoken.mAppAnimator.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004345 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004346 + " force=" + force);
4347 final int N = wtoken.allAppWindows.size();
4348 boolean unfrozeWindows = false;
4349 for (int i=0; i<N; i++) {
4350 WindowState w = wtoken.allAppWindows.get(i);
4351 if (w.mAppFreezing) {
4352 w.mAppFreezing = false;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07004353 if (w.mHasSurface && !w.mOrientationChanging) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07004354 if (DEBUG_ORIENTATION) Slog.v(TAG, "set mOrientationChanging of " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004355 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07004356 mInnerFields.mOrientationChangeComplete = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004357 }
Dianne Hackborna57c6952013-03-29 14:46:40 -07004358 w.mLastFreezeDuration = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004359 unfrozeWindows = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07004360 w.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004361 }
4362 }
4363 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004364 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
Craig Mautner59431632012-04-04 11:56:44 -07004365 wtoken.mAppAnimator.freezingScreen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07004366 wtoken.mAppAnimator.lastFreezeDuration = (int)(SystemClock.elapsedRealtime()
4367 - mDisplayFreezeTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004368 mAppsFreezingScreen--;
Dianne Hackborna57c6952013-03-29 14:46:40 -07004369 mLastFinishedFreezeSource = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004370 }
4371 if (unfreezeSurfaceNow) {
4372 if (unfrozeWindows) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004373 performLayoutAndPlaceSurfacesLocked();
4374 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004375 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004376 }
4377 }
4378 }
Romain Guy06882f82009-06-10 13:36:04 -07004379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004380 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
4381 int configChanges) {
4382 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004383 RuntimeException e = null;
4384 if (!HIDE_STACK_CRAWLS) {
4385 e = new RuntimeException();
4386 e.fillInStackTrace();
4387 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004388 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004389 + ": hidden=" + wtoken.hidden + " freezing="
Craig Mautner59431632012-04-04 11:56:44 -07004390 + wtoken.mAppAnimator.freezingScreen, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004391 }
4392 if (!wtoken.hiddenRequested) {
Craig Mautner59431632012-04-04 11:56:44 -07004393 if (!wtoken.mAppAnimator.freezingScreen) {
4394 wtoken.mAppAnimator.freezingScreen = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -07004395 wtoken.mAppAnimator.lastFreezeDuration = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004396 mAppsFreezingScreen++;
4397 if (mAppsFreezingScreen == 1) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07004398 startFreezingDisplayLocked(false, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004399 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
You Kimcb6291c2012-12-04 23:22:28 +09004400 mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 5000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004401 }
4402 }
4403 final int N = wtoken.allAppWindows.size();
4404 for (int i=0; i<N; i++) {
4405 WindowState w = wtoken.allAppWindows.get(i);
4406 w.mAppFreezing = true;
4407 }
4408 }
4409 }
Romain Guy06882f82009-06-10 13:36:04 -07004410
Craig Mautner312eac42012-11-13 10:56:22 -08004411 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004412 public void startAppFreezingScreen(IBinder token, int configChanges) {
4413 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4414 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004415 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004416 }
4417
4418 synchronized(mWindowMap) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07004419 if (configChanges == 0 && okToDisplay()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004420 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004421 return;
4422 }
Romain Guy06882f82009-06-10 13:36:04 -07004423
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004424 AppWindowToken wtoken = findAppWindowToken(token);
4425 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004426 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004427 return;
4428 }
4429 final long origId = Binder.clearCallingIdentity();
4430 startAppFreezingScreenLocked(wtoken, configChanges);
4431 Binder.restoreCallingIdentity(origId);
4432 }
4433 }
Romain Guy06882f82009-06-10 13:36:04 -07004434
Craig Mautner312eac42012-11-13 10:56:22 -08004435 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004436 public void stopAppFreezingScreen(IBinder token, boolean force) {
4437 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4438 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004439 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004440 }
4441
4442 synchronized(mWindowMap) {
4443 AppWindowToken wtoken = findAppWindowToken(token);
4444 if (wtoken == null || wtoken.appToken == null) {
4445 return;
4446 }
4447 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004448 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
Craig Mautner59431632012-04-04 11:56:44 -07004449 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.mAppAnimator.freezingScreen);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004450 unsetAppFreezingScreenLocked(wtoken, true, force);
4451 Binder.restoreCallingIdentity(origId);
4452 }
4453 }
Romain Guy06882f82009-06-10 13:36:04 -07004454
Craig Mautnerae446592012-12-06 19:05:05 -08004455 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004456 public void removeAppToken(IBinder token) {
4457 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4458 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004459 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004460 }
4461
4462 AppWindowToken wtoken = null;
4463 AppWindowToken startingToken = null;
4464 boolean delayed = false;
4465
4466 final long origId = Binder.clearCallingIdentity();
4467 synchronized(mWindowMap) {
4468 WindowToken basewtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004469 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004470 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004471 delayed = setTokenVisibilityLocked(wtoken, null, false,
Craig Mautner4b71aa12012-12-27 17:20:01 -08004472 AppTransition.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004473 wtoken.inPendingTransaction = false;
4474 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004475 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004476 if (mClosingApps.contains(wtoken)) {
4477 delayed = true;
Craig Mautner164d4bb2012-11-26 13:51:23 -08004478 } else if (mAppTransition.isTransitionSet()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004479 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004480 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004481 delayed = true;
4482 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004483 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004484 TAG, "Removing app " + wtoken + " delayed=" + delayed
Craig Mautner59431632012-04-04 11:56:44 -07004485 + " animation=" + wtoken.mAppAnimator.animation
4486 + " animating=" + wtoken.mAppAnimator.animating);
Craig Mautnerc00204b2013-03-05 15:02:14 -08004487 final Task task = mTaskIdToTask.get(wtoken.groupId);
4488 DisplayContent displayContent = task.getDisplayContent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004489 if (delayed) {
4490 // set the token aside because it has an active animation to be finished
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004491 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4492 "removeAppToken make exiting: " + wtoken);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004493 displayContent.mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004494 } else {
4495 // Make sure there is no animation running on this token,
4496 // so any windows associated with it will be removed as
4497 // soon as their animations are complete
Craig Mautner59431632012-04-04 11:56:44 -07004498 wtoken.mAppAnimator.clearAnimation();
4499 wtoken.mAppAnimator.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004500 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004501 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4502 "removeAppToken: " + wtoken);
Craig Mautnerc00204b2013-03-05 15:02:14 -08004503
4504 if (task.removeAppToken(wtoken)) {
4505 mTaskIdToTask.delete(wtoken.groupId);
Craig Mautnerc00204b2013-03-05 15:02:14 -08004506 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004507 wtoken.removed = true;
4508 if (wtoken.startingData != null) {
4509 startingToken = wtoken;
4510 }
4511 unsetAppFreezingScreenLocked(wtoken, true, true);
4512 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004513 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004514 mFocusedApp = null;
Jeff Brown3a22cd92011-01-21 13:59:04 -08004515 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004516 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004517 }
4518 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004519 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004520 }
Romain Guy06882f82009-06-10 13:36:04 -07004521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004522 if (!delayed && wtoken != null) {
4523 wtoken.updateReportedVisibilityLocked();
4524 }
4525 }
4526 Binder.restoreCallingIdentity(origId);
4527
4528 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004529 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004530 + startingToken + ": app token removed");
4531 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
4532 mH.sendMessage(m);
4533 }
4534 }
4535
4536 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
4537 final int NW = token.windows.size();
Craig Mautneref25d7a2012-05-15 23:01:47 -07004538 if (NW > 0) {
4539 mWindowsChanged = true;
4540 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004541 for (int i=0; i<NW; i++) {
4542 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004543 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
Craig Mautner59c00972012-07-30 12:10:24 -07004544 win.getWindowList().remove(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004545 int j = win.mChildWindows.size();
4546 while (j > 0) {
4547 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004548 WindowState cwin = win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004549 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004550 "Tmp removing child window " + cwin);
Craig Mautner59c00972012-07-30 12:10:24 -07004551 cwin.getWindowList().remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004552 }
4553 }
4554 return NW > 0;
4555 }
4556
4557 void dumpAppTokensLocked() {
Craig Mautnerf8924152013-07-16 09:10:55 -07004558 final int numDisplays = mDisplayContents.size();
4559 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
4560 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08004561 Slog.v(TAG, " Display " + displayContent.getDisplayId());
Craig Mautnerd9a22882013-03-16 15:00:36 -07004562 final ArrayList<Task> tasks = displayContent.getTasks();
Craig Mautnerf81b90872013-02-26 13:02:43 -08004563 int i = displayContent.numTokens();
4564 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
4565 AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
4566 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
4567 final AppWindowToken wtoken = tokens.get(tokenNdx);
4568 Slog.v(TAG, " #" + --i + ": " + wtoken.token);
4569 }
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08004570 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004571 }
4572 }
Romain Guy06882f82009-06-10 13:36:04 -07004573
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004574 void dumpWindowsLocked() {
Craig Mautner59c00972012-07-30 12:10:24 -07004575 int i = 0;
Craig Mautnerf8924152013-07-16 09:10:55 -07004576 final int numDisplays = mDisplayContents.size();
4577 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
4578 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
4579 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
4580 Slog.v(TAG, " #" + i++ + ": " + windows.get(winNdx));
4581 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004582 }
4583 }
Romain Guy06882f82009-06-10 13:36:04 -07004584
Craig Mautner926f3832013-02-13 11:56:07 -08004585 private int findAppWindowInsertionPointLocked(AppWindowToken target) {
4586 final int taskId = target.groupId;
Craig Mautnerc00204b2013-03-05 15:02:14 -08004587 Task targetTask = mTaskIdToTask.get(taskId);
4588 if (targetTask == null) {
4589 Slog.w(TAG, "findAppWindowInsertionPointLocked: no Task for " + target + " taskId="
4590 + taskId);
4591 return 0;
4592 }
4593 DisplayContent displayContent = targetTask.getDisplayContent();
Craig Mautner926f3832013-02-13 11:56:07 -08004594 if (displayContent == null) {
Craig Mautnerc00204b2013-03-05 15:02:14 -08004595 Slog.w(TAG, "findAppWindowInsertionPointLocked: no DisplayContent for " + target);
Craig Mautner926f3832013-02-13 11:56:07 -08004596 return 0;
4597 }
4598 final WindowList windows = displayContent.getWindowList();
4599 final int NW = windows.size();
4600
Craig Mautnerf81b90872013-02-26 13:02:43 -08004601 boolean found = false;
Craig Mautnerc00204b2013-03-05 15:02:14 -08004602 final ArrayList<Task> tasks = displayContent.getTasks();
Craig Mautnerf81b90872013-02-26 13:02:43 -08004603 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
Craig Mautnerc00204b2013-03-05 15:02:14 -08004604 final Task task = tasks.get(taskNdx);
Craig Mautnerf81b90872013-02-26 13:02:43 -08004605 if (!found && task.taskId != taskId) {
Craig Mautner926f3832013-02-13 11:56:07 -08004606 continue;
4607 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08004608 AppTokenList tokens = task.mAppTokens;
4609 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
4610 final AppWindowToken wtoken = tokens.get(tokenNdx);
4611 if (!found && wtoken == target) {
4612 found = true;
4613 }
4614 if (found) {
4615 // Find the first app token below the new position that has
4616 // a window displayed.
4617 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows in " + wtoken.token);
4618 if (wtoken.sendingToBottom) {
4619 if (DEBUG_REORDER) Slog.v(TAG, "Skipping token -- currently sending to bottom");
4620 continue;
4621 }
4622 for (int i = wtoken.windows.size() - 1; i >= 0; --i) {
4623 WindowState win = wtoken.windows.get(i);
4624 for (int j = win.mChildWindows.size() - 1; j >= 0; --j) {
4625 WindowState cwin = win.mChildWindows.get(j);
4626 if (cwin.mSubLayer >= 0) {
4627 for (int pos = NW - 1; pos >= 0; pos--) {
4628 if (windows.get(pos) == cwin) {
4629 if (DEBUG_REORDER) Slog.v(TAG,
4630 "Found child win @" + (pos + 1));
4631 return pos + 1;
4632 }
4633 }
4634 }
4635 }
Craig Mautner926f3832013-02-13 11:56:07 -08004636 for (int pos = NW - 1; pos >= 0; pos--) {
Craig Mautnerf81b90872013-02-26 13:02:43 -08004637 if (windows.get(pos) == win) {
4638 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos + 1));
Craig Mautner926f3832013-02-13 11:56:07 -08004639 return pos + 1;
4640 }
4641 }
4642 }
4643 }
Craig Mautner926f3832013-02-13 11:56:07 -08004644 }
4645 }
Craig Mautner5457e612013-05-10 16:25:02 -07004646 // Never put an app window underneath wallpaper.
4647 for (int pos = NW - 1; pos >= 0; pos--) {
4648 if (windows.get(pos).mIsWallpaper) {
4649 if (DEBUG_REORDER) Slog.v(TAG, "Found wallpaper @" + pos);
4650 return pos + 1;
4651 }
4652 }
Craig Mautner926f3832013-02-13 11:56:07 -08004653 return 0;
4654 }
4655
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004656 private final int reAddWindowLocked(int index, WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -07004657 final WindowList windows = win.getWindowList();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004658 final int NCW = win.mChildWindows.size();
4659 boolean added = false;
4660 for (int j=0; j<NCW; j++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004661 WindowState cwin = win.mChildWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004662 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004663 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004664 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004665 win.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004666 windows.add(index, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004667 index++;
4668 added = true;
4669 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004670 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004671 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004672 cwin.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004673 windows.add(index, cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004674 index++;
4675 }
4676 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004677 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004678 + index + ": " + win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004679 win.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004680 windows.add(index, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004681 index++;
4682 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004683 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004684 return index;
4685 }
Romain Guy06882f82009-06-10 13:36:04 -07004686
Craig Mautner59c00972012-07-30 12:10:24 -07004687 private final int reAddAppWindowsLocked(final DisplayContent displayContent, int index,
4688 WindowToken token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004689 final int NW = token.windows.size();
4690 for (int i=0; i<NW; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07004691 final WindowState win = token.windows.get(i);
4692 if (win.mDisplayContent == displayContent) {
Craig Mautner69b08182012-09-05 13:07:13 -07004693 index = reAddWindowLocked(index, win);
Craig Mautner59c00972012-07-30 12:10:24 -07004694 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004695 }
4696 return index;
4697 }
4698
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -07004699 private void moveHomeTasksLocked(boolean toTop) {
4700 final DisplayContent displayContent = getDefaultDisplayContentLocked();
4701 if (toTop ^ displayContent.homeOnTop()) {
4702 final ArrayList<Task> tasks = displayContent.getHomeStack().getTasks();
4703 final int numTasks = tasks.size();
4704 for (int i = 0; i < numTasks; ++i) {
4705 if (toTop) {
4706 // Keep pulling the bottom task off and moving it to the top.
4707 moveTaskToTop(tasks.get(0).taskId);
4708 } else {
4709 // Keep pulling the top task off and moving it to the bottom.
4710 moveTaskToBottom(tasks.get(numTasks - 1).taskId);
4711 }
4712 }
4713 }
4714 }
4715
Craig Mautner5457e612013-05-10 16:25:02 -07004716 private void moveStackWindowsLocked(TaskStack stack) {
4717 DisplayContent displayContent = stack.getDisplayContent();
Craig Mautnerd9a22882013-03-16 15:00:36 -07004718
Craig Mautner926f3832013-02-13 11:56:07 -08004719 // First remove all of the windows from the list.
Craig Mautner5457e612013-05-10 16:25:02 -07004720 final ArrayList<Task> tasks = stack.getTasks();
4721 final int numTasks = tasks.size();
4722 for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
4723 AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
4724 final int numTokens = tokens.size();
4725 for (int tokenNdx = numTokens - 1; tokenNdx >= 0; --tokenNdx) {
4726 tmpRemoveAppWindowsLocked(tokens.get(tokenNdx));
4727 }
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004728 }
Craig Mautner926f3832013-02-13 11:56:07 -08004729
4730 // And now add them back at the correct place.
4731 // Where to start adding?
Craig Mautner5457e612013-05-10 16:25:02 -07004732 for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
4733 AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
4734 int pos = findAppWindowInsertionPointLocked(tokens.get(0));
4735 final int numTokens = tokens.size();
4736 for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
4737 final AppWindowToken wtoken = tokens.get(tokenNdx);
4738 if (wtoken != null) {
4739 final int newPos = reAddAppWindowsLocked(displayContent, pos, wtoken);
4740 if (newPos != pos) {
4741 displayContent.layoutNeeded = true;
4742 }
4743 pos = newPos;
Craig Mautner926f3832013-02-13 11:56:07 -08004744 }
Craig Mautner926f3832013-02-13 11:56:07 -08004745 }
4746 }
Craig Mautner5457e612013-05-10 16:25:02 -07004747
Craig Mautner926f3832013-02-13 11:56:07 -08004748 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
Craig Mautnercf910b02013-04-23 11:23:27 -07004749 false /*updateInputWindows*/)) {
Craig Mautner926f3832013-02-13 11:56:07 -08004750 assignLayersLocked(displayContent.getWindowList());
4751 }
4752
Craig Mautner926f3832013-02-13 11:56:07 -08004753 mInputMonitor.setUpdateInputWindowsNeededLw();
4754 performLayoutAndPlaceSurfacesLocked();
4755 mInputMonitor.updateInputWindowsLw(false /*force*/);
4756
4757 //dump();
4758 }
4759
4760 public void moveTaskToTop(int taskId) {
4761 final long origId = Binder.clearCallingIdentity();
4762 try {
4763 synchronized(mWindowMap) {
Craig Mautnerc00204b2013-03-05 15:02:14 -08004764 Task task = mTaskIdToTask.get(taskId);
4765 if (task == null) {
4766 Slog.e(TAG, "moveTaskToTop: taskId=" + taskId + " not found in mTaskIdToTask");
4767 return;
4768 }
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -07004769 final TaskStack stack = task.mStack;
4770 final DisplayContent displayContent = task.getDisplayContent();
4771 final boolean isHomeStackTask = stack.isHomeStack();
4772 final boolean homeIsOnTop = displayContent.homeOnTop();
4773 if (!isHomeStackTask && homeIsOnTop) {
4774 // First move move the home tasks all to the bottom to rearrange the windows.
4775 moveHomeTasksLocked(false);
4776 // Now move the stack itself.
4777 displayContent.moveHomeStackBox(false);
4778 } else if (isHomeStackTask && !homeIsOnTop) {
4779 // Move the stack to the top.
4780 displayContent.moveHomeStackBox(true);
4781 }
4782 stack.moveTaskToTop(task);
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07004783 displayContent.moveStack(stack, true);
Craig Mautner5457e612013-05-10 16:25:02 -07004784 moveStackWindowsLocked(stack);
Craig Mautner926f3832013-02-13 11:56:07 -08004785 }
4786 } finally {
4787 Binder.restoreCallingIdentity(origId);
4788 }
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004789 }
4790
4791 public void moveTaskToBottom(int taskId) {
Craig Mautner926f3832013-02-13 11:56:07 -08004792 final long origId = Binder.clearCallingIdentity();
4793 try {
4794 synchronized(mWindowMap) {
Craig Mautnerc00204b2013-03-05 15:02:14 -08004795 Task task = mTaskIdToTask.get(taskId);
4796 if (task == null) {
Craig Mautner926f3832013-02-13 11:56:07 -08004797 Slog.e(TAG, "moveTaskToBottom: taskId=" + taskId
Craig Mautnerc00204b2013-03-05 15:02:14 -08004798 + " not found in mTaskIdToTask");
Craig Mautner926f3832013-02-13 11:56:07 -08004799 return;
4800 }
Craig Mautner5457e612013-05-10 16:25:02 -07004801 final TaskStack stack = task.mStack;
4802 stack.moveTaskToBottom(task);
4803 task.getDisplayContent().moveStack(stack, false);
4804 moveStackWindowsLocked(stack);
Craig Mautner926f3832013-02-13 11:56:07 -08004805 }
4806 } finally {
4807 Binder.restoreCallingIdentity(origId);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004808 }
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004809 }
4810
Craig Mautnerc00204b2013-03-05 15:02:14 -08004811 /**
4812 * Create a new TaskStack and place it next to an existing stack.
4813 * @param stackId The unique identifier of the new stack.
Craig Mautner5a449152013-05-24 15:49:29 -07004814 * @param relativeStackBoxId The existing stack that this stack goes before or after.
Craig Mautnerc00204b2013-03-05 15:02:14 -08004815 * @param position One of:
Craig Mautnera5eed0b2013-03-16 12:41:54 -07004816 * {@link StackBox#TASK_STACK_GOES_BEFORE}
4817 * {@link StackBox#TASK_STACK_GOES_AFTER}
4818 * {@link StackBox#TASK_STACK_GOES_ABOVE}
4819 * {@link StackBox#TASK_STACK_GOES_BELOW}
4820 * {@link StackBox#TASK_STACK_GOES_UNDER}
4821 * {@link StackBox#TASK_STACK_GOES_OVER}
Craig Mautnerc00204b2013-03-05 15:02:14 -08004822 * @param weight Relative weight for determining how big to make the new TaskStack.
4823 */
Craig Mautner5a449152013-05-24 15:49:29 -07004824 public void createStack(int stackId, int relativeStackBoxId, int position, float weight) {
Craig Mautnerc00204b2013-03-05 15:02:14 -08004825 synchronized (mWindowMap) {
Craig Mautner967212c2013-04-13 21:10:58 -07004826 if (position <= StackBox.TASK_STACK_GOES_BELOW &&
4827 (weight < STACK_WEIGHT_MIN || weight > STACK_WEIGHT_MAX)) {
4828 throw new IllegalArgumentException(
4829 "createStack: weight must be between " + STACK_WEIGHT_MIN + " and " +
4830 STACK_WEIGHT_MAX + ", weight=" + weight);
4831 }
Craig Mautnerf8924152013-07-16 09:10:55 -07004832 final int numDisplays = mDisplayContents.size();
4833 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
4834 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautner5a449152013-05-24 15:49:29 -07004835 TaskStack stack = displayContent.createStack(this, stackId, relativeStackBoxId,
4836 position, weight);
4837 if (stack != null) {
4838 mStackIdToStack.put(stackId, stack);
4839 displayContent.moveStack(stack, true);
4840 performLayoutAndPlaceSurfacesLocked();
4841 return;
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07004842 }
Craig Mautner967212c2013-04-13 21:10:58 -07004843 }
Craig Mautner5a449152013-05-24 15:49:29 -07004844 Slog.e(TAG, "createStack: Unable to find relativeStackBoxId=" + relativeStackBoxId);
Craig Mautnerc00204b2013-03-05 15:02:14 -08004845 }
4846 }
4847
Craig Mautner00af9fe2013-03-25 09:13:41 -07004848 public int removeStack(int stackId) {
Craig Mautnera9a3fb12013-04-18 10:01:00 -07004849 synchronized (mWindowMap) {
4850 final TaskStack stack = mStackIdToStack.get(stackId);
4851 if (stack != null) {
4852 mStackIdToStack.delete(stackId);
4853 int nextStackId = stack.remove();
4854 stack.getDisplayContent().layoutNeeded = true;
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07004855 requestTraversalLocked();
Craig Mautnera9a3fb12013-04-18 10:01:00 -07004856 return nextStackId;
4857 }
4858 if (DEBUG_STACK) Slog.i(TAG, "removeStack: could not find stackId=" + stackId);
Craig Mautner00af9fe2013-03-25 09:13:41 -07004859 }
Craig Mautner9e4f28c2013-04-03 10:53:23 -07004860 return HOME_STACK_ID;
Craig Mautner00af9fe2013-03-25 09:13:41 -07004861 }
4862
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07004863 public void removeTask(int taskId) {
Craig Mautnerc00204b2013-03-05 15:02:14 -08004864 synchronized (mWindowMap) {
4865 Task task = mTaskIdToTask.get(taskId);
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07004866 if (task == null) {
Craig Mautner1d001b62013-06-18 16:52:43 -07004867 if (DEBUG_STACK) Slog.i(TAG, "removeTask: could not find taskId=" + taskId);
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07004868 return;
4869 }
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07004870 final TaskStack stack = task.mStack;
4871 stack.removeTask(task);
4872 stack.getDisplayContent().layoutNeeded = true;
4873 }
4874 }
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07004875
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07004876 public void addTask(int taskId, int stackId, boolean toTop) {
4877 synchronized (mWindowMap) {
4878 Task task = mTaskIdToTask.get(taskId);
4879 if (task == null) {
4880 return;
4881 }
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07004882 TaskStack stack = mStackIdToStack.get(stackId);
4883 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07004884 final DisplayContent displayContent = stack.getDisplayContent();
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07004885 displayContent.layoutNeeded = true;
Craig Mautnerc00204b2013-03-05 15:02:14 -08004886 performLayoutAndPlaceSurfacesLocked();
4887 }
4888 }
4889
Craig Mautner5a449152013-05-24 15:49:29 -07004890 public void resizeStackBox(int stackBoxId, float weight) {
Craig Mautner967212c2013-04-13 21:10:58 -07004891 if (weight < STACK_WEIGHT_MIN || weight > STACK_WEIGHT_MAX) {
4892 throw new IllegalArgumentException(
4893 "resizeStack: weight must be between " + STACK_WEIGHT_MIN + " and " +
4894 STACK_WEIGHT_MAX + ", weight=" + weight);
4895 }
Craig Mautnerc00204b2013-03-05 15:02:14 -08004896 synchronized (mWindowMap) {
Craig Mautnerf8924152013-07-16 09:10:55 -07004897 final int numDisplays = mDisplayContents.size();
4898 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
4899 if (mDisplayContents.valueAt(displayNdx).resizeStack(stackBoxId, weight)) {
Craig Mautner5a449152013-05-24 15:49:29 -07004900 performLayoutAndPlaceSurfacesLocked();
4901 return;
Craig Mautnerc00204b2013-03-05 15:02:14 -08004902 }
4903 }
4904 }
Craig Mautner5a449152013-05-24 15:49:29 -07004905 throw new IllegalArgumentException("resizeStack: stackBoxId " + stackBoxId
4906 + " not found.");
Craig Mautnerc00204b2013-03-05 15:02:14 -08004907 }
4908
Craig Mautner5ff12102013-05-24 12:50:15 -07004909 public ArrayList<StackBoxInfo> getStackBoxInfos() {
4910 synchronized(mWindowMap) {
4911 return getDefaultDisplayContentLocked().getStackBoxInfos();
4912 }
4913 }
4914
Craig Mautner967212c2013-04-13 21:10:58 -07004915 public Rect getStackBounds(int stackId) {
Craig Mautnerf8924152013-07-16 09:10:55 -07004916 final int numDisplays = mDisplayContents.size();
4917 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
4918 Rect bounds = mDisplayContents.valueAt(displayNdx).getStackBounds(stackId);
Craig Mautner967212c2013-04-13 21:10:58 -07004919 if (bounds != null) {
4920 return bounds;
4921 }
4922 }
4923 return null;
4924 }
4925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004926 // -------------------------------------------------------------
4927 // Misc IWindowSession methods
4928 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004929
Craig Mautner5642a482012-08-23 12:16:53 -07004930 @Override
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07004931 public void startFreezingScreen(int exitAnim, int enterAnim) {
4932 if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
4933 "startFreezingScreen()")) {
4934 throw new SecurityException("Requires FREEZE_SCREEN permission");
4935 }
4936
4937 synchronized(mWindowMap) {
4938 if (!mClientFreezingScreen) {
4939 mClientFreezingScreen = true;
4940 final long origId = Binder.clearCallingIdentity();
4941 try {
4942 startFreezingDisplayLocked(false, exitAnim, enterAnim);
4943 mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
You Kimcb6291c2012-12-04 23:22:28 +09004944 mH.sendEmptyMessageDelayed(H.CLIENT_FREEZE_TIMEOUT, 5000);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07004945 } finally {
4946 Binder.restoreCallingIdentity(origId);
4947 }
4948 }
4949 }
4950 }
4951
4952 @Override
4953 public void stopFreezingScreen() {
4954 if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
4955 "stopFreezingScreen()")) {
4956 throw new SecurityException("Requires FREEZE_SCREEN permission");
4957 }
4958
4959 synchronized(mWindowMap) {
4960 if (mClientFreezingScreen) {
4961 mClientFreezingScreen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07004962 mLastFinishedFreezeSource = "client";
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07004963 final long origId = Binder.clearCallingIdentity();
4964 try {
4965 stopFreezingDisplayLocked();
4966 } finally {
4967 Binder.restoreCallingIdentity(origId);
4968 }
4969 }
4970 }
4971 }
4972
4973 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004974 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004975 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004976 != PackageManager.PERMISSION_GRANTED) {
4977 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4978 }
Jim Millerd6b57052010-06-07 17:52:42 -07004979
Craig Mautner5642a482012-08-23 12:16:53 -07004980 mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage(
4981 KeyguardDisableHandler.KEYGUARD_DISABLE, new Pair<IBinder, String>(token, tag)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004982 }
4983
Craig Mautner5642a482012-08-23 12:16:53 -07004984 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004985 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004986 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004987 != PackageManager.PERMISSION_GRANTED) {
4988 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4989 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004990
Craig Mautner5642a482012-08-23 12:16:53 -07004991 mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage(
4992 KeyguardDisableHandler.KEYGUARD_REENABLE, token));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004993 }
4994
4995 /**
4996 * @see android.app.KeyguardManager#exitKeyguardSecurely
4997 */
Craig Mautner2268e7e2012-12-13 15:40:00 -08004998 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004999 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04005000 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005001 != PackageManager.PERMISSION_GRANTED) {
5002 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5003 }
5004 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
Craig Mautner2268e7e2012-12-13 15:40:00 -08005005 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005006 public void onKeyguardExitResult(boolean success) {
5007 try {
5008 callback.onKeyguardExitResult(success);
5009 } catch (RemoteException e) {
5010 // Client has died, we don't care.
5011 }
5012 }
5013 });
5014 }
5015
Craig Mautner2268e7e2012-12-13 15:40:00 -08005016 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005017 public boolean inKeyguardRestrictedInputMode() {
5018 return mPolicy.inKeyguardRestrictedKeyInputMode();
5019 }
Romain Guy06882f82009-06-10 13:36:04 -07005020
Craig Mautner2268e7e2012-12-13 15:40:00 -08005021 @Override
Mike Lockwood520d8bc2011-02-18 13:23:13 -05005022 public boolean isKeyguardLocked() {
5023 return mPolicy.isKeyguardLocked();
5024 }
5025
Craig Mautner2268e7e2012-12-13 15:40:00 -08005026 @Override
Mike Lockwood520d8bc2011-02-18 13:23:13 -05005027 public boolean isKeyguardSecure() {
5028 return mPolicy.isKeyguardSecure();
5029 }
5030
Craig Mautner2268e7e2012-12-13 15:40:00 -08005031 @Override
Dianne Hackborn90c52de2011-09-23 12:57:44 -07005032 public void dismissKeyguard() {
5033 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
5034 != PackageManager.PERMISSION_GRANTED) {
5035 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5036 }
5037 synchronized(mWindowMap) {
5038 mPolicy.dismissKeyguardLw();
5039 }
5040 }
5041
Craig Mautner0bf6ec92012-12-18 08:33:27 -08005042 @Override
Dianne Hackbornffa42482009-09-23 22:20:11 -07005043 public void closeSystemDialogs(String reason) {
5044 synchronized(mWindowMap) {
Craig Mautnerf8924152013-07-16 09:10:55 -07005045 final int numDisplays = mDisplayContents.size();
5046 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
5047 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
5048 final int numWindows = windows.size();
5049 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
5050 final WindowState w = windows.get(winNdx);
5051 if (w.mHasSurface) {
5052 try {
5053 w.mClient.closeSystemDialogs(reason);
5054 } catch (RemoteException e) {
5055 }
Dianne Hackbornffa42482009-09-23 22:20:11 -07005056 }
5057 }
5058 }
5059 }
5060 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005061
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005062 static float fixScale(float scale) {
5063 if (scale < 0) scale = 0;
5064 else if (scale > 20) scale = 20;
5065 return Math.abs(scale);
5066 }
Romain Guy06882f82009-06-10 13:36:04 -07005067
Craig Mautner0bf6ec92012-12-18 08:33:27 -08005068 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005069 public void setAnimationScale(int which, float scale) {
5070 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
5071 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005072 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005073 }
5074
5075 if (scale < 0) scale = 0;
5076 else if (scale > 20) scale = 20;
5077 scale = Math.abs(scale);
5078 switch (which) {
5079 case 0: mWindowAnimationScale = fixScale(scale); break;
5080 case 1: mTransitionAnimationScale = fixScale(scale); break;
Chet Haasec38fa1f2012-02-01 16:37:46 -08005081 case 2: mAnimatorDurationScale = fixScale(scale); break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005082 }
Romain Guy06882f82009-06-10 13:36:04 -07005083
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005084 // Persist setting
You Kimcb6291c2012-12-04 23:22:28 +09005085 mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005086 }
Romain Guy06882f82009-06-10 13:36:04 -07005087
Craig Mautner4b71aa12012-12-27 17:20:01 -08005088 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005089 public void setAnimationScales(float[] scales) {
5090 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
5091 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005092 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005093 }
5094
5095 if (scales != null) {
5096 if (scales.length >= 1) {
5097 mWindowAnimationScale = fixScale(scales[0]);
5098 }
5099 if (scales.length >= 2) {
5100 mTransitionAnimationScale = fixScale(scales[1]);
5101 }
Chet Haasec38fa1f2012-02-01 16:37:46 -08005102 if (scales.length >= 3) {
Jeff Brownff7e6ef2012-08-15 02:05:18 -07005103 setAnimatorDurationScale(fixScale(scales[2]));
Chet Haasec38fa1f2012-02-01 16:37:46 -08005104 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005105 }
Romain Guy06882f82009-06-10 13:36:04 -07005106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005107 // Persist setting
You Kimcb6291c2012-12-04 23:22:28 +09005108 mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005109 }
Romain Guy06882f82009-06-10 13:36:04 -07005110
Jeff Brownff7e6ef2012-08-15 02:05:18 -07005111 private void setAnimatorDurationScale(float scale) {
5112 mAnimatorDurationScale = scale;
5113 ValueAnimator.setDurationScale(scale);
5114 }
5115
Craig Mautner4b71aa12012-12-27 17:20:01 -08005116 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005117 public float getAnimationScale(int which) {
5118 switch (which) {
5119 case 0: return mWindowAnimationScale;
5120 case 1: return mTransitionAnimationScale;
Chet Haasec38fa1f2012-02-01 16:37:46 -08005121 case 2: return mAnimatorDurationScale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005122 }
5123 return 0;
5124 }
Romain Guy06882f82009-06-10 13:36:04 -07005125
Craig Mautner4b71aa12012-12-27 17:20:01 -08005126 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005127 public float[] getAnimationScales() {
Chet Haasec38fa1f2012-02-01 16:37:46 -08005128 return new float[] { mWindowAnimationScale, mTransitionAnimationScale,
5129 mAnimatorDurationScale };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005130 }
Romain Guy06882f82009-06-10 13:36:04 -07005131
Craig Mautner037aa8d2013-06-07 10:35:44 -07005132 @Override
5133 public void registerPointerEventListener(PointerEventListener listener) {
5134 mPointerEventDispatcher.registerInputEventListener(listener);
5135 }
5136
5137 @Override
5138 public void unregisterPointerEventListener(PointerEventListener listener) {
5139 mPointerEventDispatcher.unregisterInputEventListener(listener);
5140 }
5141
Jeff Brownac143512012-04-05 18:57:33 -07005142 // Called by window manager policy. Not exposed externally.
5143 @Override
5144 public int getLidState() {
Jeff Brownc458ce92012-04-30 14:58:40 -07005145 int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY,
5146 InputManagerService.SW_LID);
Jeff Brownac143512012-04-05 18:57:33 -07005147 if (sw > 0) {
Jeff Brown27fd3422012-04-09 11:05:16 -07005148 // Switch state: AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL.
Jeff Brownac143512012-04-05 18:57:33 -07005149 return LID_CLOSED;
Jeff Brown27fd3422012-04-09 11:05:16 -07005150 } else if (sw == 0) {
5151 // Switch state: AKEY_STATE_UP.
5152 return LID_OPEN;
Jeff Brownac143512012-04-05 18:57:33 -07005153 } else {
Jeff Brown27fd3422012-04-09 11:05:16 -07005154 // Switch state: AKEY_STATE_UNKNOWN.
Jeff Brownac143512012-04-05 18:57:33 -07005155 return LID_ABSENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005156 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005157 }
Romain Guy06882f82009-06-10 13:36:04 -07005158
Jeff Brownac143512012-04-05 18:57:33 -07005159 // Called by window manager policy. Not exposed externally.
5160 @Override
Jeff Browncf39bdf2012-05-18 14:41:19 -07005161 public void switchKeyboardLayout(int deviceId, int direction) {
5162 mInputManager.switchKeyboardLayout(deviceId, direction);
5163 }
5164
5165 // Called by window manager policy. Not exposed externally.
5166 @Override
Jeff Brown9a538ee2012-08-20 14:56:57 -07005167 public void shutdown(boolean confirm) {
5168 ShutdownThread.shutdown(mContext, confirm);
Jeff Brown7304c342012-05-11 18:42:42 -07005169 }
5170
5171 // Called by window manager policy. Not exposed externally.
5172 @Override
Jeff Brown9a538ee2012-08-20 14:56:57 -07005173 public void rebootSafeMode(boolean confirm) {
5174 ShutdownThread.rebootSafeMode(mContext, confirm);
Jeff Brown7304c342012-05-11 18:42:42 -07005175 }
5176
Craig Mautner6cfa7292013-01-15 09:05:42 -08005177 @Override
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07005178 public void setInputFilter(IInputFilter filter) {
5179 if (!checkCallingPermission(android.Manifest.permission.FILTER_EVENTS, "setInputFilter()")) {
5180 throw new SecurityException("Requires FILTER_EVENTS permission");
5181 }
Jeff Brown0029c662011-03-30 02:25:18 -07005182 mInputManager.setInputFilter(filter);
5183 }
5184
Craig Mautnerf1b67412012-09-19 13:18:29 -07005185 public void setCurrentUser(final int newUserId) {
5186 synchronized (mWindowMap) {
Craig Mautner858d8a62013-04-23 17:08:34 -07005187 int oldUserId = mCurrentUserId;
Craig Mautnerf1b67412012-09-19 13:18:29 -07005188 mCurrentUserId = newUserId;
Amith Yamasani4befbec2013-07-10 16:18:01 -07005189 mAppTransition.setCurrentUser(newUserId);
Craig Mautnerf1b67412012-09-19 13:18:29 -07005190 mPolicy.setCurrentUserLw(newUserId);
Craig Mautner88400d32012-09-30 12:35:45 -07005191
5192 // Hide windows that should not be seen by the new user.
Craig Mautnerf8924152013-07-16 09:10:55 -07005193 final int numDisplays = mDisplayContents.size();
5194 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
5195 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautner858d8a62013-04-23 17:08:34 -07005196 displayContent.switchUserStacks(oldUserId, newUserId);
5197 rebuildAppWindowListLocked(displayContent);
Craig Mautner88400d32012-09-30 12:35:45 -07005198 }
5199 performLayoutAndPlaceSurfacesLocked();
Craig Mautnerf1b67412012-09-19 13:18:29 -07005200 }
5201 }
5202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005203 public void enableScreenAfterBoot() {
5204 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005205 if (DEBUG_BOOT) {
5206 RuntimeException here = new RuntimeException("here");
5207 here.fillInStackTrace();
5208 Slog.i(TAG, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled
5209 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5210 + " mShowingBootMessages=" + mShowingBootMessages
5211 + " mSystemBooted=" + mSystemBooted, here);
5212 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005213 if (mSystemBooted) {
5214 return;
5215 }
5216 mSystemBooted = true;
Dianne Hackborn661cd522011-08-22 00:26:20 -07005217 hideBootMessagesLocked();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005218 // If the screen still doesn't come up after 30 seconds, give
5219 // up and turn it on.
You Kimcb6291c2012-12-04 23:22:28 +09005220 mH.sendEmptyMessageDelayed(H.BOOT_TIMEOUT, 30*1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005221 }
Romain Guy06882f82009-06-10 13:36:04 -07005222
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07005223 mPolicy.systemBooted();
5224
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005225 performEnableScreen();
5226 }
Romain Guy06882f82009-06-10 13:36:04 -07005227
Dianne Hackborn661cd522011-08-22 00:26:20 -07005228 void enableScreenIfNeededLocked() {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005229 if (DEBUG_BOOT) {
5230 RuntimeException here = new RuntimeException("here");
5231 here.fillInStackTrace();
5232 Slog.i(TAG, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled
5233 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5234 + " mShowingBootMessages=" + mShowingBootMessages
5235 + " mSystemBooted=" + mSystemBooted, here);
5236 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005237 if (mDisplayEnabled) {
5238 return;
5239 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005240 if (!mSystemBooted && !mShowingBootMessages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005241 return;
5242 }
You Kimcb6291c2012-12-04 23:22:28 +09005243 mH.sendEmptyMessage(H.ENABLE_SCREEN);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005244 }
Romain Guy06882f82009-06-10 13:36:04 -07005245
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005246 public void performBootTimeout() {
5247 synchronized(mWindowMap) {
Mike Lockwoodd747dc82011-09-13 16:28:22 -04005248 if (mDisplayEnabled || mHeadless) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005249 return;
5250 }
5251 Slog.w(TAG, "***** BOOT TIMEOUT: forcing display enabled");
5252 mForceDisplayEnabled = true;
5253 }
5254 performEnableScreen();
5255 }
5256
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005257 public void performEnableScreen() {
5258 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005259 if (DEBUG_BOOT) {
5260 RuntimeException here = new RuntimeException("here");
5261 here.fillInStackTrace();
5262 Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
5263 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5264 + " mShowingBootMessages=" + mShowingBootMessages
Jeff Brown780c46f2012-06-24 12:15:38 -07005265 + " mSystemBooted=" + mSystemBooted
5266 + " mOnlyCore=" + mOnlyCore, here);
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005267 }
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 }
Romain Guy06882f82009-06-10 13:36:04 -07005274
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005275 if (!mForceDisplayEnabled) {
5276 // Don't enable the screen until all existing windows
5277 // have been drawn.
5278 boolean haveBootMsg = false;
5279 boolean haveApp = false;
Justin Mattson4233f262012-04-09 18:23:16 -07005280 // if the wallpaper service is disabled on the device, we're never going to have
5281 // wallpaper, don't bother waiting for it
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005282 boolean haveWallpaper = false;
Justin Mattson4233f262012-04-09 18:23:16 -07005283 boolean wallpaperEnabled = mContext.getResources().getBoolean(
Jeff Brown780c46f2012-06-24 12:15:38 -07005284 com.android.internal.R.bool.config_enableWallpaperService)
5285 && !mOnlyCore;
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005286 boolean haveKeyguard = true;
Craig Mautner59c00972012-07-30 12:10:24 -07005287 // TODO(multidisplay): Expand to all displays?
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005288 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07005289 final int N = windows.size();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005290 for (int i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07005291 WindowState w = windows.get(i);
Craig Mautner65d11b32012-10-01 13:59:52 -07005292 if (w.mAttrs.type == TYPE_KEYGUARD) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005293 // Only if there is a keyguard attached to the window manager
5294 // will we consider ourselves as having a keyguard. If it
5295 // isn't attached, we don't know if it wants to be shown or
5296 // hidden. If it is attached, we will say we have a keyguard
5297 // if the window doesn't want to be visible, because in that
5298 // case it explicitly doesn't want to be shown so we should
5299 // not delay turning the screen on for it.
5300 boolean vis = w.mViewVisibility == View.VISIBLE
5301 && w.mPolicyVisibility;
5302 haveKeyguard = !vis;
5303 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005304 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
5305 return;
5306 }
5307 if (w.isDrawnLw()) {
Craig Mautner65d11b32012-10-01 13:59:52 -07005308 if (w.mAttrs.type == TYPE_BOOT_PROGRESS) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005309 haveBootMsg = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005310 } else if (w.mAttrs.type == TYPE_APPLICATION) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005311 haveApp = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005312 } else if (w.mAttrs.type == TYPE_WALLPAPER) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005313 haveWallpaper = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005314 } else if (w.mAttrs.type == TYPE_KEYGUARD) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005315 haveKeyguard = true;
5316 }
5317 }
5318 }
5319
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005320 if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005321 Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
5322 + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
Justin Mattson4233f262012-04-09 18:23:16 -07005323 + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled
5324 + " haveKeyguard=" + haveKeyguard);
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005325 }
5326
5327 // If we are turning on the screen to show the boot message,
5328 // don't do it until the boot message is actually displayed.
5329 if (!mSystemBooted && !haveBootMsg) {
5330 return;
5331 }
Craig Mautner312eac42012-11-13 10:56:22 -08005332
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005333 // If we are turning on the screen after the boot is completed
5334 // normally, don't do so until we have the application and
5335 // wallpaper.
Justin Mattson4233f262012-04-09 18:23:16 -07005336 if (mSystemBooted && ((!haveApp && !haveKeyguard) ||
5337 (wallpaperEnabled && !haveWallpaper))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005338 return;
5339 }
5340 }
Romain Guy06882f82009-06-10 13:36:04 -07005341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005342 mDisplayEnabled = true;
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005343 if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005344 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005345 StringWriter sw = new StringWriter();
Dianne Hackborn8c841092013-06-24 13:46:13 -07005346 PrintWriter pw = new FastPrintWriter(sw, false, 1024);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005347 this.dump(null, pw, null);
Dianne Hackborn8c841092013-06-24 13:46:13 -07005348 pw.flush();
Joe Onorato8a9b2202010-02-26 18:56:32 -08005349 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005350 }
5351 try {
5352 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
5353 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005354 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005355 Parcel data = Parcel.obtain();
5356 data.writeInterfaceToken("android.ui.ISurfaceComposer");
Jeff Brownc042ee22012-05-08 13:03:42 -07005357 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005358 data, null, 0);
5359 data.recycle();
5360 }
5361 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005362 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005363 }
Jeff Brown08a746a2012-06-24 12:14:49 -07005364
5365 // Enable input dispatch.
5366 mInputMonitor.setEventDispatchingLw(mEventDispatchingEnabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005367 }
Romain Guy06882f82009-06-10 13:36:04 -07005368
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005369 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07005370
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005371 // Make sure the last requested orientation has been applied.
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005372 updateRotationUnchecked(false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005373 }
Romain Guy06882f82009-06-10 13:36:04 -07005374
Dianne Hackborn661cd522011-08-22 00:26:20 -07005375 public void showBootMessage(final CharSequence msg, final boolean always) {
5376 boolean first = false;
5377 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005378 if (DEBUG_BOOT) {
5379 RuntimeException here = new RuntimeException("here");
5380 here.fillInStackTrace();
5381 Slog.i(TAG, "showBootMessage: msg=" + msg + " always=" + always
5382 + " mAllowBootMessages=" + mAllowBootMessages
5383 + " mShowingBootMessages=" + mShowingBootMessages
5384 + " mSystemBooted=" + mSystemBooted, here);
5385 }
Dianne Hackborn58f42a52011-10-10 13:46:34 -07005386 if (!mAllowBootMessages) {
5387 return;
5388 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005389 if (!mShowingBootMessages) {
5390 if (!always) {
5391 return;
5392 }
5393 first = true;
5394 }
5395 if (mSystemBooted) {
5396 return;
5397 }
5398 mShowingBootMessages = true;
5399 mPolicy.showBootMessage(msg, always);
5400 }
5401 if (first) {
5402 performEnableScreen();
5403 }
5404 }
5405
5406 public void hideBootMessagesLocked() {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005407 if (DEBUG_BOOT) {
5408 RuntimeException here = new RuntimeException("here");
5409 here.fillInStackTrace();
5410 Slog.i(TAG, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled
5411 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5412 + " mShowingBootMessages=" + mShowingBootMessages
5413 + " mSystemBooted=" + mSystemBooted, here);
5414 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005415 if (mShowingBootMessages) {
5416 mShowingBootMessages = false;
5417 mPolicy.hideBootMessages();
5418 }
5419 }
5420
Craig Mautner6cfa7292013-01-15 09:05:42 -08005421 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005422 public void setInTouchMode(boolean mode) {
5423 synchronized(mWindowMap) {
5424 mInTouchMode = mode;
5425 }
5426 }
5427
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005428 // TODO: more accounting of which pid(s) turned it on, keep count,
5429 // only allow disables from pids which have count on, etc.
Craig Mautner0447a812012-05-22 16:01:31 -07005430 @Override
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005431 public void showStrictModeViolation(boolean on) {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07005432 if (mHeadless) return;
Chris Craik3198ef32012-10-10 14:52:30 -07005433 int pid = Binder.getCallingPid();
5434 mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, on ? 1 : 0, pid));
Craig Mautner0447a812012-05-22 16:01:31 -07005435 }
Mike Lockwood3a74bd32011-08-12 13:55:22 -07005436
Chris Craik3198ef32012-10-10 14:52:30 -07005437 private void showStrictModeViolation(int arg, int pid) {
Craig Mautner0447a812012-05-22 16:01:31 -07005438 final boolean on = arg != 0;
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005439 synchronized(mWindowMap) {
5440 // Ignoring requests to enable the red border from clients
5441 // which aren't on screen. (e.g. Broadcast Receivers in
5442 // the background..)
5443 if (on) {
5444 boolean isVisible = false;
Craig Mautnerf8924152013-07-16 09:10:55 -07005445 final int numDisplays = mDisplayContents.size();
5446 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
5447 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
5448 final int numWindows = windows.size();
5449 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
5450 final WindowState ws = windows.get(winNdx);
5451 if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
5452 isVisible = true;
5453 break;
5454 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005455 }
5456 }
5457 if (!isVisible) {
5458 return;
5459 }
5460 }
5461
Dianne Hackborn36991742011-10-11 21:35:26 -07005462 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
5463 ">>> OPEN TRANSACTION showStrictModeViolation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -08005464 SurfaceControl.openTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005465 try {
Jeff Browne215f262012-09-10 16:01:14 -07005466 // TODO(multi-display): support multiple displays
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005467 if (mStrictModeFlash == null) {
Jeff Browne215f262012-09-10 16:01:14 -07005468 mStrictModeFlash = new StrictModeFlash(
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005469 getDefaultDisplayContentLocked().getDisplay(), mFxSession);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005470 }
5471 mStrictModeFlash.setVisibility(on);
5472 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -08005473 SurfaceControl.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -07005474 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
5475 "<<< CLOSE TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005476 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005477 }
5478 }
5479
Craig Mautner6cfa7292013-01-15 09:05:42 -08005480 @Override
Brad Fitzpatrickc1a968a2010-11-24 08:56:40 -08005481 public void setStrictModeVisualIndicatorPreference(String value) {
5482 SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
5483 }
5484
Jim Millere70d5062011-03-08 21:38:39 -08005485 /**
5486 * Takes a snapshot of the screen. In landscape mode this grabs the whole screen.
5487 * In portrait mode, it grabs the upper region of the screen based on the vertical dimension
5488 * of the target image.
Craig Mautner312eac42012-11-13 10:56:22 -08005489 *
Craig Mautner59c00972012-07-30 12:10:24 -07005490 * @param displayId the Display to take a screenshot of.
Jim Millere70d5062011-03-08 21:38:39 -08005491 * @param width the width of the target bitmap
5492 * @param height the height of the target bitmap
5493 */
Craig Mautner2d5618c2012-10-18 13:55:47 -07005494 @Override
Craig Mautner59c00972012-07-30 12:10:24 -07005495 public Bitmap screenshotApplications(IBinder appToken, int displayId, int width, int height) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005496 if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5497 "screenshotApplications()")) {
5498 throw new SecurityException("Requires READ_FRAME_BUFFER permission");
5499 }
5500
Craig Mautner24d887472013-03-20 15:40:36 -07005501 Bitmap rawss = null;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005502
Dianne Hackbornd2835932010-12-13 16:28:46 -08005503 int maxLayer = 0;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005504 final Rect frame = new Rect();
5505
Craig Mautner24d887472013-03-20 15:40:36 -07005506 float scale = 0;
Jim Millere70d5062011-03-08 21:38:39 -08005507 int dw, dh;
Craig Mautner24d887472013-03-20 15:40:36 -07005508 int rot = Surface.ROTATION_0;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005509
Craig Mautner24d887472013-03-20 15:40:36 -07005510 boolean screenshotReady;
5511 int minLayer;
5512 if (appToken == null) {
5513 screenshotReady = true;
5514 minLayer = 0;
5515 } else {
5516 screenshotReady = false;
5517 minLayer = Integer.MAX_VALUE;
5518 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005519
Craig Mautner24d887472013-03-20 15:40:36 -07005520 int retryCount = 0;
5521 WindowState appWin = null;
5522
5523 do {
5524 if (retryCount++ > 0) {
5525 try {
5526 Thread.sleep(100);
5527 } catch (InterruptedException e) {
5528 }
Craig Mautner2d5618c2012-10-18 13:55:47 -07005529 }
Craig Mautner24d887472013-03-20 15:40:36 -07005530 synchronized(mWindowMap) {
5531 final DisplayContent displayContent = getDisplayContentLocked(displayId);
5532 if (displayContent == null) {
5533 return null;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005534 }
Craig Mautner24d887472013-03-20 15:40:36 -07005535 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
5536 dw = displayInfo.logicalWidth;
5537 dh = displayInfo.logicalHeight;
5538
5539 int aboveAppLayer = mPolicy.windowTypeToLayerLw(TYPE_APPLICATION)
5540 * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
5541 aboveAppLayer += TYPE_LAYER_MULTIPLIER;
5542
5543 boolean isImeTarget = mInputMethodTarget != null
5544 && mInputMethodTarget.mAppToken != null
5545 && mInputMethodTarget.mAppToken.appToken != null
5546 && mInputMethodTarget.mAppToken.appToken.asBinder() == appToken;
5547
5548 // Figure out the part of the screen that is actually the app.
5549 boolean including = false;
5550 appWin = null;
5551 final WindowList windows = displayContent.getWindowList();
Craig Mautner76ea2242013-05-15 11:40:05 -07005552 final Rect stackBounds = new Rect();
Craig Mautner24d887472013-03-20 15:40:36 -07005553 for (int i = windows.size() - 1; i >= 0; i--) {
5554 WindowState ws = windows.get(i);
5555 if (!ws.mHasSurface) {
5556 continue;
5557 }
5558 if (ws.mLayer >= aboveAppLayer) {
5559 continue;
5560 }
5561 // When we will skip windows: when we are not including
5562 // ones behind a window we didn't skip, and we are actually
5563 // taking a screenshot of a specific app.
5564 if (!including && appToken != null) {
5565 // Also, we can possibly skip this window if it is not
5566 // an IME target or the application for the screenshot
5567 // is not the current IME target.
5568 if (!ws.mIsImWindow || !isImeTarget) {
5569 // And finally, this window is of no interest if it
5570 // is not associated with the screenshot app.
5571 if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
5572 continue;
5573 }
5574 appWin = ws;
Craig Mautner76ea2242013-05-15 11:40:05 -07005575 stackBounds.set(ws.getStackBounds());
Craig Mautner24d887472013-03-20 15:40:36 -07005576 }
5577 }
5578
5579 // We keep on including windows until we go past a full-screen
5580 // window.
5581 boolean fullscreen = ws.isFullscreen(dw, dh);
5582 including = !ws.mIsImWindow && !fullscreen;
5583
5584 final WindowStateAnimator winAnim = ws.mWinAnimator;
5585 if (maxLayer < winAnim.mSurfaceLayer) {
5586 maxLayer = winAnim.mSurfaceLayer;
5587 }
Craig Mautner4238e3e2013-03-28 15:28:55 -07005588 if (minLayer > winAnim.mSurfaceLayer) {
5589 minLayer = winAnim.mSurfaceLayer;
5590 }
Craig Mautner24d887472013-03-20 15:40:36 -07005591
5592 // Don't include wallpaper in bounds calculation
5593 if (!ws.mIsWallpaper) {
5594 final Rect wf = ws.mFrame;
5595 final Rect cr = ws.mContentInsets;
5596 int left = wf.left + cr.left;
5597 int top = wf.top + cr.top;
5598 int right = wf.right - cr.right;
5599 int bottom = wf.bottom - cr.bottom;
5600 frame.union(left, top, right, bottom);
Craig Mautner76ea2242013-05-15 11:40:05 -07005601 frame.intersect(stackBounds);
Craig Mautner24d887472013-03-20 15:40:36 -07005602 }
5603
Craig Mautner4238e3e2013-03-28 15:28:55 -07005604 if (ws.mAppToken != null && ws.mAppToken.token == appToken &&
5605 ws.isDisplayedLw()) {
5606 screenshotReady = true;
5607 }
5608
5609 if (fullscreen) {
5610 // No point in continuing down through windows.
5611 break;
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005612 }
5613 }
5614
Craig Mautner24d887472013-03-20 15:40:36 -07005615 if (appToken != null && appWin == null) {
5616 // Can't find a window to snapshot.
5617 if (DEBUG_SCREENSHOT) Slog.i(TAG,
5618 "Screenshot: Couldn't find a surface matching " + appToken);
5619 return null;
5620 }
5621 if (!screenshotReady) {
5622 // Delay and hope that window gets drawn.
5623 if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot: No image ready for " + appToken
5624 + ", " + appWin + " drawState=" + appWin.mWinAnimator.mDrawState);
5625 continue;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005626 }
Craig Mautner312eac42012-11-13 10:56:22 -08005627
Craig Mautner24d887472013-03-20 15:40:36 -07005628 // Constrain frame to the screen size.
5629 frame.intersect(0, 0, dw, dh);
5630
5631 if (frame.isEmpty() || maxLayer == 0) {
5632 if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot of " + appToken
5633 + ": returning null frame=" + frame.toShortString() + " maxLayer="
5634 + maxLayer);
5635 return null;
Jim Miller2aded182011-03-08 15:32:42 -08005636 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005637
Craig Mautner24d887472013-03-20 15:40:36 -07005638 // The screenshot API does not apply the current screen rotation.
5639 rot = getDefaultDisplayContentLocked().getDisplay().getRotation();
5640 int fw = frame.width();
5641 int fh = frame.height();
Jim Millere70d5062011-03-08 21:38:39 -08005642
Craig Mautner24d887472013-03-20 15:40:36 -07005643 // Constrain thumbnail to smaller of screen width or height. Assumes aspect
5644 // of thumbnail is the same as the screen (in landscape) or square.
Craig Mautner76ea2242013-05-15 11:40:05 -07005645 scale = Math.max(width / (float) fw, height / (float) fh);
5646 /*
Craig Mautner24d887472013-03-20 15:40:36 -07005647 float targetWidthScale = width / (float) fw;
5648 float targetHeightScale = height / (float) fh;
Craig Mautner76ea2242013-05-15 11:40:05 -07005649 if (fw <= fh) {
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005650 scale = targetWidthScale;
Craig Mautner24d887472013-03-20 15:40:36 -07005651 // If aspect of thumbnail is the same as the screen (in landscape),
5652 // select the slightly larger value so we fill the entire bitmap
5653 if (targetHeightScale > scale && (int) (targetHeightScale * fw) == width) {
5654 scale = targetHeightScale;
5655 }
5656 } else {
5657 scale = targetHeightScale;
5658 // If aspect of thumbnail is the same as the screen (in landscape),
5659 // select the slightly larger value so we fill the entire bitmap
5660 if (targetWidthScale > scale && (int) (targetWidthScale * fh) == height) {
5661 scale = targetWidthScale;
5662 }
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005663 }
Craig Mautner76ea2242013-05-15 11:40:05 -07005664 */
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005665
Craig Mautner24d887472013-03-20 15:40:36 -07005666 // The screen shot will contain the entire screen.
5667 dw = (int)(dw*scale);
5668 dh = (int)(dh*scale);
5669 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
5670 int tmp = dw;
5671 dw = dh;
5672 dh = tmp;
5673 rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -07005674 }
Craig Mautner24d887472013-03-20 15:40:36 -07005675 if (DEBUG_SCREENSHOT) {
5676 Slog.i(TAG, "Screenshot: " + dw + "x" + dh + " from " + minLayer + " to "
5677 + maxLayer + " appToken=" + appToken);
5678 for (int i = 0; i < windows.size(); i++) {
5679 WindowState win = windows.get(i);
5680 Slog.i(TAG, win + ": " + win.mLayer
5681 + " animLayer=" + win.mWinAnimator.mAnimLayer
5682 + " surfaceLayer=" + win.mWinAnimator.mSurfaceLayer);
5683 }
5684 }
5685 rawss = SurfaceControl.screenshot(dw, dh, minLayer, maxLayer);
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -07005686 }
Craig Mautner24d887472013-03-20 15:40:36 -07005687 } while (!screenshotReady && retryCount <= MAX_SCREENSHOT_RETRIES);
Craig Mautner4238e3e2013-03-28 15:28:55 -07005688 if (retryCount > MAX_SCREENSHOT_RETRIES) Slog.i(TAG, "Screenshot max retries " +
5689 retryCount + " of " + appToken + " appWin=" + (appWin == null ?
5690 "null" : (appWin + " drawState=" + appWin.mWinAnimator.mDrawState)));
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005691
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005692 if (rawss == null) {
Craig Mautner4238e3e2013-03-28 15:28:55 -07005693 Slog.w(TAG, "Screenshot failure taking screenshot for (" + dw + "x" + dh
Dianne Hackborn88b03bd2010-12-16 11:15:18 -08005694 + ") to layer " + maxLayer);
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005695 return null;
5696 }
Jim Millere70d5062011-03-08 21:38:39 -08005697
5698 Bitmap bm = Bitmap.createBitmap(width, height, rawss.getConfig());
Craig Mautner76ea2242013-05-15 11:40:05 -07005699 frame.scale(scale);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005700 Matrix matrix = new Matrix();
5701 ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07005702 // TODO: Test for RTL vs. LTR and use frame.right-width instead of -frame.left
Craig Mautner76ea2242013-05-15 11:40:05 -07005703 matrix.postTranslate(-FloatMath.ceil(frame.left), -FloatMath.ceil(frame.top));
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005704 Canvas canvas = new Canvas(bm);
Dianne Hackbornca46b872013-04-17 18:06:22 -07005705 canvas.drawColor(0xFF000000);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005706 canvas.drawBitmap(rawss, matrix, null);
Dianne Hackborn6311d0a2011-08-02 16:37:58 -07005707 canvas.setBitmap(null);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005708
Craig Mautner4238e3e2013-03-28 15:28:55 -07005709 if (true || DEBUG_SCREENSHOT) {
Craig Mautner24d887472013-03-20 15:40:36 -07005710 // TEST IF IT's ALL BLACK
5711 int[] buffer = new int[bm.getWidth() * bm.getHeight()];
5712 bm.getPixels(buffer, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm.getHeight());
5713 boolean allBlack = true;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07005714 final int firstColor = buffer[0];
Craig Mautner24d887472013-03-20 15:40:36 -07005715 for (int i = 0; i < buffer.length; i++) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07005716 if (buffer[i] != firstColor) {
Craig Mautner24d887472013-03-20 15:40:36 -07005717 allBlack = false;
5718 break;
5719 }
5720 }
5721 if (allBlack) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07005722 Slog.i(TAG, "Screenshot " + appWin + " was monochrome(" +
5723 Integer.toHexString(firstColor) + ")! mSurfaceLayer=" +
Craig Mautner4238e3e2013-03-28 15:28:55 -07005724 (appWin != null ? appWin.mWinAnimator.mSurfaceLayer : "null") +
5725 " minLayer=" + minLayer + " maxLayer=" + maxLayer);
Craig Mautner24d887472013-03-20 15:40:36 -07005726 }
5727 }
5728
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005729 rawss.recycle();
5730 return bm;
5731 }
5732
Jeff Brown01a98dd2011-09-20 15:08:29 -07005733 /**
5734 * Freeze rotation changes. (Enable "rotation lock".)
5735 * Persists across reboots.
Jeff Brown4dfce202011-10-05 12:00:10 -07005736 * @param rotation The desired rotation to freeze to, or -1 to use the
5737 * current rotation.
Jeff Brown01a98dd2011-09-20 15:08:29 -07005738 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005739 @Override
Jeff Brown4dfce202011-10-05 12:00:10 -07005740 public void freezeRotation(int rotation) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005741 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005742 "freezeRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005743 throw new SecurityException("Requires SET_ORIENTATION permission");
5744 }
Jeff Brown4dfce202011-10-05 12:00:10 -07005745 if (rotation < -1 || rotation > Surface.ROTATION_270) {
5746 throw new IllegalArgumentException("Rotation argument must be -1 or a valid "
5747 + "rotation constant.");
5748 }
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005749
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005750 if (DEBUG_ORIENTATION) Slog.v(TAG, "freezeRotation: mRotation=" + mRotation);
5751
Daniel Sandler3de830b2013-02-20 15:23:52 -05005752 long origId = Binder.clearCallingIdentity();
5753 try {
5754 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED,
5755 rotation == -1 ? mRotation : rotation);
5756 } finally {
5757 Binder.restoreCallingIdentity(origId);
5758 }
5759
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005760 updateRotationUnchecked(false, false);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005761 }
5762
Jeff Brown01a98dd2011-09-20 15:08:29 -07005763 /**
5764 * Thaw rotation changes. (Disable "rotation lock".)
5765 * Persists across reboots.
5766 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005767 @Override
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005768 public void thawRotation() {
5769 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005770 "thawRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005771 throw new SecurityException("Requires SET_ORIENTATION permission");
5772 }
5773
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005774 if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation);
5775
Daniel Sandler3de830b2013-02-20 15:23:52 -05005776 long origId = Binder.clearCallingIdentity();
5777 try {
5778 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE,
5779 777); // rot not used
5780 } finally {
5781 Binder.restoreCallingIdentity(origId);
5782 }
5783
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005784 updateRotationUnchecked(false, false);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005785 }
5786
Jeff Brown01a98dd2011-09-20 15:08:29 -07005787 /**
5788 * Recalculate the current rotation.
5789 *
5790 * Called by the window manager policy whenever the state of the system changes
5791 * such that the current rotation might need to be updated, such as when the
5792 * device is docked or rotated into a new posture.
5793 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005794 @Override
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005795 public void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
5796 updateRotationUnchecked(alwaysSendConfiguration, forceRelayout);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005797 }
5798
5799 /**
5800 * Temporarily pauses rotation changes until resumed.
5801 *
5802 * This can be used to prevent rotation changes from occurring while the user is
5803 * performing certain operations, such as drag and drop.
5804 *
Craig Mautner6cfa7292013-01-15 09:05:42 -08005805 * This call nests and must be matched by an equal number of calls to
5806 * {@link #resumeRotationLocked}.
Jeff Brown01a98dd2011-09-20 15:08:29 -07005807 */
5808 void pauseRotationLocked() {
5809 mDeferredRotationPauseCount += 1;
5810 }
5811
5812 /**
5813 * Resumes normal rotation changes after being paused.
5814 */
5815 void resumeRotationLocked() {
5816 if (mDeferredRotationPauseCount > 0) {
5817 mDeferredRotationPauseCount -= 1;
5818 if (mDeferredRotationPauseCount == 0) {
5819 boolean changed = updateRotationUncheckedLocked(false);
5820 if (changed) {
5821 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
5822 }
5823 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005824 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005825 }
Romain Guy06882f82009-06-10 13:36:04 -07005826
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005827 public void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005828 if(DEBUG_ORIENTATION) Slog.v(TAG, "updateRotationUnchecked("
5829 + "alwaysSendConfiguration=" + alwaysSendConfiguration + ")");
Romain Guy06882f82009-06-10 13:36:04 -07005830
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005831 long origId = Binder.clearCallingIdentity();
5832 boolean changed;
5833 synchronized(mWindowMap) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005834 changed = updateRotationUncheckedLocked(false);
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005835 if (!changed || forceRelayout) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005836 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005837 performLayoutAndPlaceSurfacesLocked();
5838 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005839 }
Romain Guy06882f82009-06-10 13:36:04 -07005840
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005841 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005842 sendNewConfiguration();
5843 }
Romain Guy06882f82009-06-10 13:36:04 -07005844
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005845 Binder.restoreCallingIdentity(origId);
5846 }
Romain Guy06882f82009-06-10 13:36:04 -07005847
Craig Mautner59c00972012-07-30 12:10:24 -07005848 // TODO(multidisplay): Rotate any display?
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005849 /**
Jeff Brown01a98dd2011-09-20 15:08:29 -07005850 * Updates the current rotation.
5851 *
5852 * Returns true if the rotation has been changed. In this case YOU
5853 * MUST CALL sendNewConfiguration() TO UNFREEZE THE SCREEN.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005854 */
Jeff Brown01a98dd2011-09-20 15:08:29 -07005855 public boolean updateRotationUncheckedLocked(boolean inTransaction) {
5856 if (mDeferredRotationPauseCount > 0) {
5857 // Rotation updates have been paused temporarily. Defer the update until
5858 // updates have been resumed.
5859 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, rotation is paused.");
Christopher Tateccd24de2011-01-12 15:02:55 -08005860 return false;
5861 }
5862
Craig Mautnera91f9e22012-09-14 16:22:08 -07005863 ScreenRotationAnimation screenRotationAnimation =
5864 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
5865 if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005866 // Rotation updates cannot be performed while the previous rotation change
5867 // animation is still in progress. Skip this update. We will try updating
5868 // again after the animation is finished and the display is unfrozen.
5869 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, animation in progress.");
5870 return false;
5871 }
5872
5873 if (!mDisplayEnabled) {
5874 // No point choosing a rotation if the display is not enabled.
5875 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, display is not enabled.");
5876 return false;
5877 }
5878
5879 // TODO: Implement forced rotation changes.
5880 // Set mAltOrientation to indicate that the application is receiving
5881 // an orientation that has different metrics than it expected.
5882 // eg. Portrait instead of Landscape.
5883
5884 int rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, mRotation);
5885 boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
5886 mForcedAppOrientation, rotation);
5887
5888 if (DEBUG_ORIENTATION) {
5889 Slog.v(TAG, "Application requested orientation "
5890 + mForcedAppOrientation + ", got rotation " + rotation
5891 + " which has " + (altOrientation ? "incompatible" : "compatible")
5892 + " metrics");
5893 }
5894
5895 if (mRotation == rotation && mAltOrientation == altOrientation) {
5896 // No change.
5897 return false;
5898 }
5899
5900 if (DEBUG_ORIENTATION) {
5901 Slog.v(TAG,
5902 "Rotation changed to " + rotation + (altOrientation ? " (alt)" : "")
5903 + " from " + mRotation + (mAltOrientation ? " (alt)" : "")
5904 + ", forceApp=" + mForcedAppOrientation);
5905 }
5906
5907 mRotation = rotation;
5908 mAltOrientation = altOrientation;
Jeff Brownc0347aa2011-09-23 17:26:09 -07005909 mPolicy.setRotationLw(mRotation);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005910
5911 mWindowsFreezingScreen = true;
5912 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
Craig Mautner0bf6ec92012-12-18 08:33:27 -08005913 mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT, WINDOW_FREEZE_TIMEOUT_DURATION);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005914 mWaitingForConfig = true;
Craig Mautner05d29032013-05-03 13:40:13 -07005915 final DisplayContent displayContent = getDefaultDisplayContentLocked();
5916 displayContent.layoutNeeded = true;
Craig Mautner3c174372013-02-21 17:54:37 -08005917 final int[] anim = new int[2];
Craig Mautner05d29032013-05-03 13:40:13 -07005918 if (displayContent.isDimming()) {
Craig Mautner3c174372013-02-21 17:54:37 -08005919 anim[0] = anim[1] = 0;
5920 } else {
5921 mPolicy.selectRotationAnimationLw(anim);
5922 }
5923 startFreezingDisplayLocked(inTransaction, anim[0], anim[1]);
Craig Mautnera91f9e22012-09-14 16:22:08 -07005924 // startFreezingDisplayLocked can reset the ScreenRotationAnimation.
5925 screenRotationAnimation =
5926 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005927
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08005928 // We need to update our screen size information to match the new
5929 // rotation. Note that this is redundant with the later call to
5930 // sendNewConfiguration() that must be called after this function
5931 // returns... however we need to do the screen size part of that
Jeff Brown4ed8fe72012-08-30 18:18:29 -07005932 // before then so we have the correct size to use when initializing
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08005933 // the rotation animation for the new rotation.
5934 computeScreenConfigurationLocked(null);
5935
Craig Mautner59c00972012-07-30 12:10:24 -07005936 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07005937 if (!inTransaction) {
5938 if (SHOW_TRANSACTIONS) {
5939 Slog.i(TAG, ">>> OPEN TRANSACTION setRotationUnchecked");
5940 }
Mathias Agopian3866f0d2013-02-11 22:08:48 -08005941 SurfaceControl.openTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07005942 }
Jamie Gennise2909e12011-10-10 15:48:06 -07005943 try {
5944 // NOTE: We disable the rotation in the emulator because
5945 // it doesn't support hardware OpenGL emulation yet.
Craig Mautnera91f9e22012-09-14 16:22:08 -07005946 if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
5947 && screenRotationAnimation.hasScreenshot()) {
5948 if (screenRotationAnimation.setRotationInTransaction(
Jeff Brown4ed8fe72012-08-30 18:18:29 -07005949 rotation, mFxSession,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08005950 MAX_ANIMATION_DURATION, mTransitionAnimationScale,
Craig Mautner59c00972012-07-30 12:10:24 -07005951 displayInfo.logicalWidth, displayInfo.logicalHeight)) {
Craig Mautner96868332012-12-04 14:29:11 -08005952 scheduleAnimationLocked();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08005953 }
Jamie Gennise2909e12011-10-10 15:48:06 -07005954 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07005955
5956 mDisplayManagerService.performTraversalInTransactionFromWindowManager();
Jamie Gennise2909e12011-10-10 15:48:06 -07005957 } finally {
5958 if (!inTransaction) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -08005959 SurfaceControl.closeTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07005960 if (SHOW_LIGHT_TRANSACTIONS) {
5961 Slog.i(TAG, "<<< CLOSE TRANSACTION setRotationUnchecked");
5962 }
Jamie Gennise2909e12011-10-10 15:48:06 -07005963 }
5964 }
5965
Craig Mautner59c00972012-07-30 12:10:24 -07005966 final WindowList windows = displayContent.getWindowList();
5967 for (int i = windows.size() - 1; i >= 0; i--) {
5968 WindowState w = windows.get(i);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07005969 if (w.mHasSurface) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07005970 if (DEBUG_ORIENTATION) Slog.v(TAG, "Set mOrientationChanging of " + w);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005971 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07005972 mInnerFields.mOrientationChangeComplete = false;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005973 }
Dianne Hackborna57c6952013-03-29 14:46:40 -07005974 w.mLastFreezeDuration = 0;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005975 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07005976
Jeff Brown01a98dd2011-09-20 15:08:29 -07005977 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
5978 try {
5979 mRotationWatchers.get(i).onRotationChanged(rotation);
5980 } catch (RemoteException e) {
5981 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005982 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07005983
Svetoslav Ganov545252f2012-12-10 18:29:24 -08005984 //TODO (multidisplay): Magnification is supported only for the default display.
5985 if (mDisplayMagnifier != null
5986 && displayContent.getDisplayId() == Display.DEFAULT_DISPLAY) {
5987 mDisplayMagnifier.onRotationChangedLocked(getDefaultDisplayContentLocked(), rotation);
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07005988 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07005989
Jeff Brown01a98dd2011-09-20 15:08:29 -07005990 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005991 }
Romain Guy06882f82009-06-10 13:36:04 -07005992
Craig Mautner0bf6ec92012-12-18 08:33:27 -08005993 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005994 public int getRotation() {
5995 return mRotation;
5996 }
5997
Craig Mautner0bf6ec92012-12-18 08:33:27 -08005998 @Override
Svetoslav Ganov80943d82013-01-02 10:25:37 -08005999 public boolean isRotationFrozen() {
6000 return mPolicy.getUserRotationMode() == WindowManagerPolicy.USER_ROTATION_LOCKED;
6001 }
6002
6003 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006004 public int watchRotation(IRotationWatcher watcher) {
6005 final IBinder watcherBinder = watcher.asBinder();
6006 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
Craig Mautner0bf6ec92012-12-18 08:33:27 -08006007 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006008 public void binderDied() {
6009 synchronized (mWindowMap) {
6010 for (int i=0; i<mRotationWatchers.size(); i++) {
6011 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07006012 IRotationWatcher removed = mRotationWatchers.remove(i);
6013 if (removed != null) {
6014 removed.asBinder().unlinkToDeath(this, 0);
6015 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006016 i--;
6017 }
6018 }
6019 }
6020 }
6021 };
Romain Guy06882f82009-06-10 13:36:04 -07006022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006023 synchronized (mWindowMap) {
6024 try {
6025 watcher.asBinder().linkToDeath(dr, 0);
6026 mRotationWatchers.add(watcher);
6027 } catch (RemoteException e) {
6028 // Client died, no cleanup needed.
6029 }
Romain Guy06882f82009-06-10 13:36:04 -07006030
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006031 return mRotation;
6032 }
6033 }
6034
Brian Colonnab1b9a8a2013-03-29 11:52:42 -04006035 @Override
6036 public void removeRotationWatcher(IRotationWatcher watcher) {
6037 final IBinder watcherBinder = watcher.asBinder();
6038 synchronized (mWindowMap) {
6039 for (int i=0; i<mRotationWatchers.size(); i++) {
6040 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
6041 mRotationWatchers.remove(i);
6042 i--;
6043 }
6044 }
6045 }
6046 }
6047
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006048 /**
Adam Powelldfee59a2011-08-05 20:48:30 -07006049 * Apps that use the compact menu panel (as controlled by the panelMenuIsCompact
6050 * theme attribute) on devices that feature a physical options menu key attempt to position
6051 * their menu panel window along the edge of the screen nearest the physical menu key.
6052 * This lowers the travel distance between invoking the menu panel and selecting
6053 * a menu option.
6054 *
6055 * This method helps control where that menu is placed. Its current implementation makes
6056 * assumptions about the menu key and its relationship to the screen based on whether
6057 * the device's natural orientation is portrait (width < height) or landscape.
6058 *
6059 * The menu key is assumed to be located along the bottom edge of natural-portrait
6060 * devices and along the right edge of natural-landscape devices. If these assumptions
6061 * do not hold for the target device, this method should be changed to reflect that.
6062 *
6063 * @return A {@link Gravity} value for placing the options menu window
6064 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08006065 @Override
Adam Powelldfee59a2011-08-05 20:48:30 -07006066 public int getPreferredOptionsPanelGravity() {
6067 synchronized (mWindowMap) {
6068 final int rotation = getRotation();
6069
Craig Mautner59c00972012-07-30 12:10:24 -07006070 // TODO(multidisplay): Assume that such devices physical keys are on the main screen.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006071 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07006072 if (displayContent.mInitialDisplayWidth < displayContent.mInitialDisplayHeight) {
Adam Powelldfee59a2011-08-05 20:48:30 -07006073 // On devices with a natural orientation of portrait
6074 switch (rotation) {
6075 default:
6076 case Surface.ROTATION_0:
6077 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
6078 case Surface.ROTATION_90:
Adam Powell67ed6c72011-08-28 13:21:56 -07006079 return Gravity.RIGHT | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006080 case Surface.ROTATION_180:
Adam Powell67ed6c72011-08-28 13:21:56 -07006081 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006082 case Surface.ROTATION_270:
Fabrice Di Meglioaac0d4e2012-07-19 19:21:26 -07006083 return Gravity.START | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006084 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08006085 }
6086
6087 // On devices with a natural orientation of landscape
6088 switch (rotation) {
6089 default:
6090 case Surface.ROTATION_0:
6091 return Gravity.RIGHT | Gravity.BOTTOM;
6092 case Surface.ROTATION_90:
6093 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
6094 case Surface.ROTATION_180:
6095 return Gravity.START | Gravity.BOTTOM;
6096 case Surface.ROTATION_270:
6097 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006098 }
6099 }
6100 }
6101
6102 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006103 * Starts the view server on the specified port.
6104 *
6105 * @param port The port to listener to.
6106 *
6107 * @return True if the server was successfully started, false otherwise.
6108 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08006109 * @see com.android.server.wm.ViewServer
6110 * @see com.android.server.wm.ViewServer#VIEW_SERVER_DEFAULT_PORT
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006111 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08006112 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006113 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07006114 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006115 return false;
6116 }
6117
6118 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
6119 return false;
6120 }
6121
6122 if (port < 1024) {
6123 return false;
6124 }
6125
6126 if (mViewServer != null) {
6127 if (!mViewServer.isRunning()) {
6128 try {
6129 return mViewServer.start();
6130 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006131 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006132 }
6133 }
6134 return false;
6135 }
6136
6137 try {
6138 mViewServer = new ViewServer(this, port);
6139 return mViewServer.start();
6140 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006141 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006142 }
6143 return false;
6144 }
6145
Romain Guy06882f82009-06-10 13:36:04 -07006146 private boolean isSystemSecure() {
6147 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
6148 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6149 }
6150
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006151 /**
6152 * Stops the view server if it exists.
6153 *
6154 * @return True if the server stopped, false if it wasn't started or
6155 * couldn't be stopped.
6156 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08006157 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006158 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08006159 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006160 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07006161 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006162 return false;
6163 }
6164
6165 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
6166 return false;
6167 }
6168
6169 if (mViewServer != null) {
6170 return mViewServer.stop();
6171 }
6172 return false;
6173 }
6174
6175 /**
6176 * Indicates whether the view server is running.
6177 *
6178 * @return True if the server is running, false otherwise.
6179 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08006180 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006181 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08006182 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006183 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07006184 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006185 return false;
6186 }
6187
6188 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
6189 return false;
6190 }
6191
6192 return mViewServer != null && mViewServer.isRunning();
6193 }
6194
6195 /**
6196 * Lists all availble windows in the system. The listing is written in the
6197 * specified Socket's output stream with the following syntax:
6198 * windowHashCodeInHexadecimal windowName
6199 * Each line of the ouput represents a different window.
6200 *
6201 * @param client The remote client to send the listing to.
6202 * @return False if an error occured, true otherwise.
6203 */
6204 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07006205 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006206 return false;
6207 }
6208
6209 boolean result = true;
6210
Craig Mautner59c00972012-07-30 12:10:24 -07006211 WindowList windows = new WindowList();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006212 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006213 //noinspection unchecked
Craig Mautnerf8924152013-07-16 09:10:55 -07006214 final int numDisplays = mDisplayContents.size();
6215 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
6216 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
6217 windows.addAll(displayContent.getWindowList());
Craig Mautner59c00972012-07-30 12:10:24 -07006218 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006219 }
6220
6221 BufferedWriter out = null;
6222
6223 // Any uncaught exception will crash the system process
6224 try {
6225 OutputStream clientStream = client.getOutputStream();
6226 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
6227
Craig Mautner59c00972012-07-30 12:10:24 -07006228 final int count = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006229 for (int i = 0; i < count; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07006230 final WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006231 out.write(Integer.toHexString(System.identityHashCode(w)));
6232 out.write(' ');
6233 out.append(w.mAttrs.getTitle());
6234 out.write('\n');
6235 }
6236
6237 out.write("DONE.\n");
6238 out.flush();
6239 } catch (Exception e) {
6240 result = false;
6241 } finally {
6242 if (out != null) {
6243 try {
6244 out.close();
6245 } catch (IOException e) {
6246 result = false;
6247 }
6248 }
6249 }
6250
6251 return result;
6252 }
6253
Craig Mautner59c00972012-07-30 12:10:24 -07006254 // TODO(multidisplay): Extend to multiple displays.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006255 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07006256 * Returns the focused window in the following format:
6257 * windowHashCodeInHexadecimal windowName
6258 *
6259 * @param client The remote client to send the listing to.
6260 * @return False if an error occurred, true otherwise.
6261 */
6262 boolean viewServerGetFocusedWindow(Socket client) {
6263 if (isSystemSecure()) {
6264 return false;
6265 }
6266
6267 boolean result = true;
6268
6269 WindowState focusedWindow = getFocusedWindow();
6270
6271 BufferedWriter out = null;
6272
6273 // Any uncaught exception will crash the system process
6274 try {
6275 OutputStream clientStream = client.getOutputStream();
6276 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
6277
6278 if(focusedWindow != null) {
6279 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
6280 out.write(' ');
6281 out.append(focusedWindow.mAttrs.getTitle());
6282 }
6283 out.write('\n');
6284 out.flush();
6285 } catch (Exception e) {
6286 result = false;
6287 } finally {
6288 if (out != null) {
6289 try {
6290 out.close();
6291 } catch (IOException e) {
6292 result = false;
6293 }
6294 }
6295 }
6296
6297 return result;
6298 }
6299
6300 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006301 * Sends a command to a target window. The result of the command, if any, will be
6302 * written in the output stream of the specified socket.
6303 *
6304 * The parameters must follow this syntax:
6305 * windowHashcode extra
6306 *
6307 * Where XX is the length in characeters of the windowTitle.
6308 *
6309 * The first parameter is the target window. The window with the specified hashcode
6310 * will be the target. If no target can be found, nothing happens. The extra parameters
6311 * will be delivered to the target window and as parameters to the command itself.
6312 *
6313 * @param client The remote client to sent the result, if any, to.
6314 * @param command The command to execute.
6315 * @param parameters The command parameters.
6316 *
6317 * @return True if the command was successfully delivered, false otherwise. This does
6318 * not indicate whether the command itself was successful.
6319 */
6320 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07006321 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006322 return false;
6323 }
6324
6325 boolean success = true;
6326 Parcel data = null;
6327 Parcel reply = null;
6328
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006329 BufferedWriter out = null;
6330
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006331 // Any uncaught exception will crash the system process
6332 try {
6333 // Find the hashcode of the window
6334 int index = parameters.indexOf(' ');
6335 if (index == -1) {
6336 index = parameters.length();
6337 }
6338 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08006339 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006340
6341 // Extract the command's parameter after the window description
6342 if (index < parameters.length()) {
6343 parameters = parameters.substring(index + 1);
6344 } else {
6345 parameters = "";
6346 }
6347
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006348 final WindowState window = findWindow(hashCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006349 if (window == null) {
6350 return false;
6351 }
6352
6353 data = Parcel.obtain();
6354 data.writeInterfaceToken("android.view.IWindow");
6355 data.writeString(command);
6356 data.writeString(parameters);
6357 data.writeInt(1);
6358 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
6359
6360 reply = Parcel.obtain();
6361
6362 final IBinder binder = window.mClient.asBinder();
6363 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
6364 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
6365
6366 reply.readException();
6367
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006368 if (!client.isOutputShutdown()) {
6369 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
6370 out.write("DONE\n");
6371 out.flush();
6372 }
6373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006374 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006375 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006376 success = false;
6377 } finally {
6378 if (data != null) {
6379 data.recycle();
6380 }
6381 if (reply != null) {
6382 reply.recycle();
6383 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006384 if (out != null) {
6385 try {
6386 out.close();
6387 } catch (IOException e) {
6388
6389 }
6390 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006391 }
6392
6393 return success;
6394 }
6395
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07006396 public void addWindowChangeListener(WindowChangeListener listener) {
6397 synchronized(mWindowMap) {
6398 mWindowChangeListeners.add(listener);
6399 }
6400 }
6401
6402 public void removeWindowChangeListener(WindowChangeListener listener) {
6403 synchronized(mWindowMap) {
6404 mWindowChangeListeners.remove(listener);
6405 }
6406 }
6407
6408 private void notifyWindowsChanged() {
6409 WindowChangeListener[] windowChangeListeners;
6410 synchronized(mWindowMap) {
6411 if(mWindowChangeListeners.isEmpty()) {
6412 return;
6413 }
6414 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
6415 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
6416 }
6417 int N = windowChangeListeners.length;
6418 for(int i = 0; i < N; i++) {
6419 windowChangeListeners[i].windowsChanged();
6420 }
6421 }
6422
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07006423 private void notifyFocusChanged() {
6424 WindowChangeListener[] windowChangeListeners;
6425 synchronized(mWindowMap) {
6426 if(mWindowChangeListeners.isEmpty()) {
6427 return;
6428 }
6429 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
6430 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
6431 }
6432 int N = windowChangeListeners.length;
6433 for(int i = 0; i < N; i++) {
6434 windowChangeListeners[i].focusChanged();
6435 }
6436 }
6437
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006438 private WindowState findWindow(int hashCode) {
6439 if (hashCode == -1) {
Craig Mautner59c00972012-07-30 12:10:24 -07006440 // TODO(multidisplay): Extend to multiple displays.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006441 return getFocusedWindow();
6442 }
6443
6444 synchronized (mWindowMap) {
Craig Mautnerf8924152013-07-16 09:10:55 -07006445 final int numDisplays = mDisplayContents.size();
6446 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
6447 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
6448 final int numWindows = windows.size();
6449 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
6450 final WindowState w = windows.get(winNdx);
6451 if (System.identityHashCode(w) == hashCode) {
6452 return w;
6453 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006454 }
6455 }
6456 }
6457
6458 return null;
6459 }
6460
6461 /*
6462 * Instruct the Activity Manager to fetch the current configuration and broadcast
6463 * that to config-changed listeners if appropriate.
6464 */
6465 void sendNewConfiguration() {
6466 try {
6467 mActivityManager.updateConfiguration(null);
6468 } catch (RemoteException e) {
6469 }
6470 }
Romain Guy06882f82009-06-10 13:36:04 -07006471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006472 public Configuration computeNewConfiguration() {
6473 synchronized (mWindowMap) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006474 Configuration config = computeNewConfigurationLocked();
6475 if (config == null && mWaitingForConfig) {
6476 // Nothing changed but we are waiting for something... stop that!
6477 mWaitingForConfig = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07006478 mLastFinishedFreezeSource = "new-config";
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006479 performLayoutAndPlaceSurfacesLocked();
6480 }
6481 return config;
Dianne Hackbornc485a602009-03-24 22:39:49 -07006482 }
6483 }
Romain Guy06882f82009-06-10 13:36:04 -07006484
Dianne Hackbornc485a602009-03-24 22:39:49 -07006485 Configuration computeNewConfigurationLocked() {
6486 Configuration config = new Configuration();
Dianne Hackborn09e5b9d2011-10-04 16:32:01 -07006487 config.fontScale = 0;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006488 if (!computeScreenConfigurationLocked(config)) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07006489 return null;
6490 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07006491 return config;
6492 }
Romain Guy06882f82009-06-10 13:36:04 -07006493
Craig Mautner59c00972012-07-30 12:10:24 -07006494 private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation, int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006495 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006496 final int width = mPolicy.getConfigDisplayWidth(dw, dh, rotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006497 if (width < displayInfo.smallestNominalAppWidth) {
6498 displayInfo.smallestNominalAppWidth = width;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006499 }
Craig Mautner59c00972012-07-30 12:10:24 -07006500 if (width > displayInfo.largestNominalAppWidth) {
6501 displayInfo.largestNominalAppWidth = width;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006502 }
6503 final int height = mPolicy.getConfigDisplayHeight(dw, dh, rotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006504 if (height < displayInfo.smallestNominalAppHeight) {
6505 displayInfo.smallestNominalAppHeight = height;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006506 }
Craig Mautner59c00972012-07-30 12:10:24 -07006507 if (height > displayInfo.largestNominalAppHeight) {
6508 displayInfo.largestNominalAppHeight = height;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006509 }
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006510 }
6511
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006512 private int reduceConfigLayout(int curLayout, int rotation, float density,
6513 int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006514 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006515 // Get the app screen size at this rotation.
6516 int w = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
6517 int h = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
6518
6519 // Compute the screen layout size class for this rotation.
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006520 int longSize = w;
6521 int shortSize = h;
6522 if (longSize < shortSize) {
6523 int tmp = longSize;
6524 longSize = shortSize;
6525 shortSize = tmp;
6526 }
6527 longSize = (int)(longSize/density);
6528 shortSize = (int)(shortSize/density);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006529 return Configuration.reduceScreenLayout(curLayout, longSize, shortSize);
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006530 }
6531
Craig Mautner59c00972012-07-30 12:10:24 -07006532 private void computeSizeRangesAndScreenLayout(DisplayInfo displayInfo, boolean rotated,
6533 int dw, int dh, float density, Configuration outConfig) {
Craig Mautner69b08182012-09-05 13:07:13 -07006534 // TODO: Multidisplay: for now only use with default display.
6535
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006536 // We need to determine the smallest width that will occur under normal
6537 // operation. To this, start with the base screen size and compute the
6538 // width under the different possible rotations. We need to un-rotate
6539 // the current screen dimensions before doing this.
6540 int unrotDw, unrotDh;
6541 if (rotated) {
6542 unrotDw = dh;
6543 unrotDh = dw;
6544 } else {
6545 unrotDw = dw;
6546 unrotDh = dh;
6547 }
Craig Mautner59c00972012-07-30 12:10:24 -07006548 displayInfo.smallestNominalAppWidth = 1<<30;
6549 displayInfo.smallestNominalAppHeight = 1<<30;
6550 displayInfo.largestNominalAppWidth = 0;
6551 displayInfo.largestNominalAppHeight = 0;
6552 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, unrotDw, unrotDh);
6553 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, unrotDh, unrotDw);
6554 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, unrotDw, unrotDh);
6555 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, unrotDh, unrotDw);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006556 int sl = Configuration.resetScreenLayout(outConfig.screenLayout);
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006557 sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh);
6558 sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw);
6559 sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh);
6560 sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw);
Craig Mautner59c00972012-07-30 12:10:24 -07006561 outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006562 outConfig.screenLayout = sl;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006563 }
6564
Dianne Hackborn48a76512011-06-08 21:51:44 -07006565 private int reduceCompatConfigWidthSize(int curSize, int rotation, DisplayMetrics dm,
6566 int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006567 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn1f903c32011-09-13 19:18:06 -07006568 dm.noncompatWidthPixels = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
6569 dm.noncompatHeightPixels = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006570 float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
Dianne Hackborn2b31d532011-06-23 11:58:50 -07006571 int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006572 if (curSize == 0 || size < curSize) {
6573 curSize = size;
6574 }
6575 return curSize;
6576 }
6577
6578 private int computeCompatSmallestWidth(boolean rotated, DisplayMetrics dm, int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006579 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn48a76512011-06-08 21:51:44 -07006580 mTmpDisplayMetrics.setTo(dm);
Craig Mautner69b08182012-09-05 13:07:13 -07006581 final DisplayMetrics tmpDm = mTmpDisplayMetrics;
6582 final int unrotDw, unrotDh;
Dianne Hackborn48a76512011-06-08 21:51:44 -07006583 if (rotated) {
6584 unrotDw = dh;
6585 unrotDh = dw;
6586 } else {
6587 unrotDw = dw;
6588 unrotDh = dh;
6589 }
Craig Mautner69b08182012-09-05 13:07:13 -07006590 int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, tmpDm, unrotDw, unrotDh);
6591 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, tmpDm, unrotDh, unrotDw);
6592 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, tmpDm, unrotDw, unrotDh);
6593 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, tmpDm, unrotDh, unrotDw);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006594 return sw;
6595 }
6596
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006597 boolean computeScreenConfigurationLocked(Configuration config) {
Jeff Browne215f262012-09-10 16:01:14 -07006598 if (!mDisplayReady) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07006599 return false;
6600 }
Christopher Tateb696aee2010-04-02 19:08:30 -07006601
Craig Mautner59c00972012-07-30 12:10:24 -07006602 // TODO(multidisplay): For now, apply Configuration to main screen only.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006603 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07006604
Christopher Tateb696aee2010-04-02 19:08:30 -07006605 // Use the effective "visual" dimensions based on current rotation
6606 final boolean rotated = (mRotation == Surface.ROTATION_90
6607 || mRotation == Surface.ROTATION_270);
Craig Mautner59c00972012-07-30 12:10:24 -07006608 final int realdw = rotated ?
6609 displayContent.mBaseDisplayHeight : displayContent.mBaseDisplayWidth;
6610 final int realdh = rotated ?
6611 displayContent.mBaseDisplayWidth : displayContent.mBaseDisplayHeight;
Jeff Brownfa25bf52012-07-23 19:26:30 -07006612 int dw = realdw;
6613 int dh = realdh;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006614
Jeff Brownfa25bf52012-07-23 19:26:30 -07006615 if (mAltOrientation) {
6616 if (realdw > realdh) {
6617 // Turn landscape into portrait.
6618 int maxw = (int)(realdh/1.3f);
6619 if (maxw < realdw) {
6620 dw = maxw;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006621 }
6622 } else {
Jeff Brownfa25bf52012-07-23 19:26:30 -07006623 // Turn portrait into landscape.
6624 int maxh = (int)(realdw/1.3f);
6625 if (maxh < realdh) {
6626 dh = maxh;
6627 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006628 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006629 }
6630
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006631 if (config != null) {
Jeff Browne215f262012-09-10 16:01:14 -07006632 config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
6633 Configuration.ORIENTATION_LANDSCAPE;
Dianne Hackbornc485a602009-03-24 22:39:49 -07006634 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006635
Jeff Brownbc68a592011-07-25 12:58:12 -07006636 // Update application display metrics.
Dianne Hackborn1fbee792011-11-30 11:29:58 -08006637 final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation);
6638 final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006639 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
6640 synchronized(displayContent.mDisplaySizeLock) {
6641 displayInfo.rotation = mRotation;
6642 displayInfo.logicalWidth = dw;
6643 displayInfo.logicalHeight = dh;
Dianne Hackborndde331c2012-08-03 14:01:57 -07006644 displayInfo.logicalDensityDpi = displayContent.mBaseDisplayDensity;
Craig Mautner59c00972012-07-30 12:10:24 -07006645 displayInfo.appWidth = appWidth;
6646 displayInfo.appHeight = appHeight;
Craig Mautner48d0d182013-06-11 07:53:06 -07006647 displayInfo.getLogicalMetrics(mRealDisplayMetrics,
6648 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
6649 displayInfo.getAppMetrics(mDisplayMetrics);
Jeff Brownbd6e1502012-08-28 03:27:37 -07006650 mDisplayManagerService.setDisplayInfoOverrideFromWindowManager(
6651 displayContent.getDisplayId(), displayInfo);
Dianne Hackborn1fbee792011-11-30 11:29:58 -08006652 }
Dianne Hackborn36991742011-10-11 21:35:26 -07006653 if (false) {
Jeff Brownfa25bf52012-07-23 19:26:30 -07006654 Slog.i(TAG, "Set app display size: " + appWidth + " x " + appHeight);
Dianne Hackborn36991742011-10-11 21:35:26 -07006655 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006656
Jeff Brownfa25bf52012-07-23 19:26:30 -07006657 final DisplayMetrics dm = mDisplayMetrics;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006658 mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm,
6659 mCompatDisplayMetrics);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006660
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006661 if (config != null) {
6662 config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation)
6663 / dm.density);
6664 config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation)
6665 / dm.density);
Craig Mautner59c00972012-07-30 12:10:24 -07006666 computeSizeRangesAndScreenLayout(displayInfo, rotated, dw, dh, dm.density, config);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006667
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006668 config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
6669 config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
6670 config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dm, dw, dh);
Dianne Hackborndde331c2012-08-03 14:01:57 -07006671 config.densityDpi = displayContent.mBaseDisplayDensity;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006672
Jeff Browndaa37532012-05-01 15:54:03 -07006673 // Update the configuration based on available input devices, lid switch,
6674 // and platform configuration.
6675 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
6676 config.keyboard = Configuration.KEYBOARD_NOKEYS;
6677 config.navigation = Configuration.NAVIGATION_NONAV;
6678
6679 int keyboardPresence = 0;
6680 int navigationPresence = 0;
Craig Mautner1d961d42012-05-27 12:02:11 -07006681 final InputDevice[] devices = mInputManager.getInputDevices();
6682 final int len = devices.length;
6683 for (int i = 0; i < len; i++) {
6684 InputDevice device = devices[i];
Jeff Browndaa37532012-05-01 15:54:03 -07006685 if (!device.isVirtual()) {
6686 final int sources = device.getSources();
6687 final int presenceFlag = device.isExternal() ?
6688 WindowManagerPolicy.PRESENCE_EXTERNAL :
6689 WindowManagerPolicy.PRESENCE_INTERNAL;
6690
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -07006691 if (mIsTouchDevice) {
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006692 if ((sources & InputDevice.SOURCE_TOUCHSCREEN) ==
6693 InputDevice.SOURCE_TOUCHSCREEN) {
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -07006694 config.touchscreen = Configuration.TOUCHSCREEN_FINGER;
6695 }
6696 } else {
6697 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
Jeff Browndaa37532012-05-01 15:54:03 -07006698 }
6699
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006700 if ((sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) {
Jeff Browndaa37532012-05-01 15:54:03 -07006701 config.navigation = Configuration.NAVIGATION_TRACKBALL;
6702 navigationPresence |= presenceFlag;
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006703 } else if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD
Jeff Browndaa37532012-05-01 15:54:03 -07006704 && config.navigation == Configuration.NAVIGATION_NONAV) {
6705 config.navigation = Configuration.NAVIGATION_DPAD;
6706 navigationPresence |= presenceFlag;
6707 }
6708
6709 if (device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) {
6710 config.keyboard = Configuration.KEYBOARD_QWERTY;
6711 keyboardPresence |= presenceFlag;
6712 }
6713 }
6714 }
6715
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006716 // Determine whether a hard keyboard is available and enabled.
6717 boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
6718 if (hardKeyboardAvailable != mHardKeyboardAvailable) {
6719 mHardKeyboardAvailable = hardKeyboardAvailable;
6720 mHardKeyboardEnabled = hardKeyboardAvailable;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006721 mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
6722 mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
6723 }
6724 if (!mHardKeyboardEnabled) {
6725 config.keyboard = Configuration.KEYBOARD_NOKEYS;
6726 }
6727
Jeff Browndaa37532012-05-01 15:54:03 -07006728 // Let the policy update hidden states.
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006729 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
6730 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
6731 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO;
Jeff Browndaa37532012-05-01 15:54:03 -07006732 mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence);
Jeff Brown2992ea72011-01-28 22:04:14 -08006733 }
Jeff Brown597eec82011-01-31 17:12:25 -08006734
Dianne Hackbornc485a602009-03-24 22:39:49 -07006735 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006736 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006737
Jeff Brown2992ea72011-01-28 22:04:14 -08006738 public boolean isHardKeyboardAvailable() {
6739 synchronized (mWindowMap) {
6740 return mHardKeyboardAvailable;
6741 }
6742 }
6743
6744 public boolean isHardKeyboardEnabled() {
6745 synchronized (mWindowMap) {
6746 return mHardKeyboardEnabled;
6747 }
6748 }
6749
6750 public void setHardKeyboardEnabled(boolean enabled) {
6751 synchronized (mWindowMap) {
6752 if (mHardKeyboardEnabled != enabled) {
6753 mHardKeyboardEnabled = enabled;
6754 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
6755 }
6756 }
6757 }
6758
6759 public void setOnHardKeyboardStatusChangeListener(
6760 OnHardKeyboardStatusChangeListener listener) {
6761 synchronized (mWindowMap) {
6762 mHardKeyboardStatusChangeListener = listener;
6763 }
6764 }
6765
6766 void notifyHardKeyboardStatusChange() {
6767 final boolean available, enabled;
6768 final OnHardKeyboardStatusChangeListener listener;
6769 synchronized (mWindowMap) {
6770 listener = mHardKeyboardStatusChangeListener;
6771 available = mHardKeyboardAvailable;
6772 enabled = mHardKeyboardEnabled;
6773 }
6774 if (listener != null) {
6775 listener.onHardKeyboardStatusChange(available, enabled);
6776 }
6777 }
6778
Christopher Tatea53146c2010-09-07 11:57:52 -07006779 // -------------------------------------------------------------
6780 // Drag and drop
6781 // -------------------------------------------------------------
6782
6783 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006784 int flags, int width, int height, Surface outSurface) {
Christopher Tatea53146c2010-09-07 11:57:52 -07006785 if (DEBUG_DRAG) {
6786 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006787 + " flags=" + Integer.toHexString(flags) + " win=" + window
Christopher Tatea53146c2010-09-07 11:57:52 -07006788 + " asbinder=" + window.asBinder());
6789 }
6790
6791 final int callerPid = Binder.getCallingPid();
6792 final long origId = Binder.clearCallingIdentity();
6793 IBinder token = null;
6794
6795 try {
6796 synchronized (mWindowMap) {
6797 try {
Christopher Tatea53146c2010-09-07 11:57:52 -07006798 if (mDragState == null) {
Jeff Browne215f262012-09-10 16:01:14 -07006799 // TODO(multi-display): support other displays
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006800 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07006801 final Display display = displayContent.getDisplay();
Mathias Agopian3866f0d2013-02-11 22:08:48 -08006802 SurfaceControl surface = new SurfaceControl(session, "drag surface",
6803 width, height, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
Jeff Browne215f262012-09-10 16:01:14 -07006804 surface.setLayerStack(display.getLayerStack());
Dianne Hackbornac1471a2011-02-03 13:46:06 -08006805 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DRAG "
6806 + surface + ": CREATE");
Christopher Tatea53146c2010-09-07 11:57:52 -07006807 outSurface.copyFrom(surface);
Chris Tate7b362e42010-11-04 16:02:52 -07006808 final IBinder winBinder = window.asBinder();
Christopher Tatea53146c2010-09-07 11:57:52 -07006809 token = new Binder();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006810 mDragState = new DragState(this, token, surface, /*flags*/ 0, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07006811 token = mDragState.mToken = new Binder();
6812
6813 // 5 second timeout for this window to actually begin the drag
Chris Tate7b362e42010-11-04 16:02:52 -07006814 mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
6815 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07006816 mH.sendMessageDelayed(msg, 5000);
6817 } else {
6818 Slog.w(TAG, "Drag already in progress");
6819 }
Mathias Agopian3866f0d2013-02-11 22:08:48 -08006820 } catch (SurfaceControl.OutOfResourcesException e) {
Christopher Tatea53146c2010-09-07 11:57:52 -07006821 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
6822 if (mDragState != null) {
6823 mDragState.reset();
6824 mDragState = null;
6825 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006826 }
6827 }
6828 } finally {
6829 Binder.restoreCallingIdentity(origId);
6830 }
6831
6832 return token;
6833 }
6834
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006835 // -------------------------------------------------------------
6836 // Input Events and Focus Management
6837 // -------------------------------------------------------------
Craig Mautner6cfa7292013-01-15 09:05:42 -08006838
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006839 final InputMonitor mInputMonitor = new InputMonitor(this);
Jeff Brown08a746a2012-06-24 12:14:49 -07006840 private boolean mEventDispatchingEnabled;
6841
Craig Mautner6cfa7292013-01-15 09:05:42 -08006842 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006843 public void pauseKeyDispatching(IBinder _token) {
6844 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6845 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006846 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006847 }
6848
6849 synchronized (mWindowMap) {
6850 WindowToken token = mTokenMap.get(_token);
6851 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006852 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006853 }
6854 }
6855 }
6856
Craig Mautner6cfa7292013-01-15 09:05:42 -08006857 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006858 public void resumeKeyDispatching(IBinder _token) {
6859 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6860 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006861 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006862 }
6863
6864 synchronized (mWindowMap) {
6865 WindowToken token = mTokenMap.get(_token);
6866 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006867 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006868 }
6869 }
6870 }
6871
Craig Mautner6cfa7292013-01-15 09:05:42 -08006872 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006873 public void setEventDispatching(boolean enabled) {
6874 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner3d7b7d52012-05-24 11:28:26 -07006875 "setEventDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006876 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006877 }
6878
6879 synchronized (mWindowMap) {
Jeff Brown08a746a2012-06-24 12:14:49 -07006880 mEventDispatchingEnabled = enabled;
6881 if (mDisplayEnabled) {
6882 mInputMonitor.setEventDispatchingLw(enabled);
6883 }
Craig Mautner3d7b7d52012-05-24 11:28:26 -07006884 sendScreenStatusToClientsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006885 }
6886 }
Romain Guy06882f82009-06-10 13:36:04 -07006887
Craig Mautner6cfa7292013-01-15 09:05:42 -08006888 @Override
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07006889 public IBinder getFocusedWindowToken() {
6890 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
6891 "getFocusedWindowToken()")) {
6892 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
6893 }
Svetoslav Ganove15ccb92012-05-16 15:48:55 -07006894 synchronized (mWindowMap) {
6895 WindowState windowState = getFocusedWindowLocked();
6896 if (windowState != null) {
6897 return windowState.mClient.asBinder();
6898 }
6899 return null;
6900 }
6901 }
6902
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006903 private WindowState getFocusedWindow() {
6904 synchronized (mWindowMap) {
6905 return getFocusedWindowLocked();
6906 }
6907 }
6908
6909 private WindowState getFocusedWindowLocked() {
6910 return mCurrentFocus;
6911 }
Romain Guy06882f82009-06-10 13:36:04 -07006912
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006913 public boolean detectSafeMode() {
Jeff Brownb09abc12011-01-13 21:08:27 -08006914 if (!mInputMonitor.waitForInputDevicesReady(
6915 INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
6916 Slog.w(TAG, "Devices still not ready after waiting "
Jeff Brownac143512012-04-05 18:57:33 -07006917 + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
6918 + " milliseconds before attempting to detect safe mode.");
Jeff Brownb09abc12011-01-13 21:08:27 -08006919 }
6920
Jeff Brownac143512012-04-05 18:57:33 -07006921 int menuState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
6922 KeyEvent.KEYCODE_MENU);
6923 int sState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, KeyEvent.KEYCODE_S);
6924 int dpadState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD,
6925 KeyEvent.KEYCODE_DPAD_CENTER);
6926 int trackballState = mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL,
Jeff Brownc458ce92012-04-30 14:58:40 -07006927 InputManagerService.BTN_MOUSE);
Jeff Brownac143512012-04-05 18:57:33 -07006928 int volumeDownState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
6929 KeyEvent.KEYCODE_VOLUME_DOWN);
6930 mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
6931 || volumeDownState > 0;
Dianne Hackborn19caadc2012-04-20 17:49:10 -07006932 try {
6933 if (SystemProperties.getInt(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, 0) != 0) {
6934 mSafeMode = true;
6935 SystemProperties.set(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, "");
6936 }
6937 } catch (IllegalArgumentException e) {
6938 }
Jeff Brownac143512012-04-05 18:57:33 -07006939 if (mSafeMode) {
6940 Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
6941 + " dpad=" + dpadState + " trackball=" + trackballState + ")");
6942 } else {
6943 Log.i(TAG, "SAFE MODE not enabled");
6944 }
6945 mPolicy.setSafeMode(mSafeMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006946 return mSafeMode;
6947 }
Romain Guy06882f82009-06-10 13:36:04 -07006948
Dianne Hackborn661cd522011-08-22 00:26:20 -07006949 public void displayReady() {
Jeff Browne215f262012-09-10 16:01:14 -07006950 displayReady(Display.DEFAULT_DISPLAY);
Craig Mautner4f67ba62012-08-02 11:23:00 -07006951
6952 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006953 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07006954 readForcedDisplaySizeAndDensityLocked(displayContent);
Dianne Hackborn5a052a42012-08-15 18:49:23 -07006955
Jeff Browne215f262012-09-10 16:01:14 -07006956 mDisplayReady = true;
Craig Mautner4f67ba62012-08-02 11:23:00 -07006957 mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
Jeff Browne215f262012-09-10 16:01:14 -07006958 PackageManager.FEATURE_TOUCHSCREEN);
Craig Mautner4f67ba62012-08-02 11:23:00 -07006959
Jeff Browne215f262012-09-10 16:01:14 -07006960 mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
6961 displayContent.mInitialDisplayWidth,
6962 displayContent.mInitialDisplayHeight,
6963 displayContent.mInitialDisplayDensity);
Craig Mautner4f67ba62012-08-02 11:23:00 -07006964 }
Dianne Hackborn5a052a42012-08-15 18:49:23 -07006965
6966 try {
6967 mActivityManager.updateConfiguration(null);
6968 } catch (RemoteException e) {
6969 }
Craig Mautner59c00972012-07-30 12:10:24 -07006970 }
6971
Craig Mautner2d5618c2012-10-18 13:55:47 -07006972 private void displayReady(int displayId) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07006973 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006974 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07006975 if (displayContent != null) {
6976 mAnimator.addDisplayLocked(displayId);
6977 synchronized(displayContent.mDisplaySizeLock) {
6978 // Bootstrap the default logical display from the display manager.
6979 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
6980 DisplayInfo newDisplayInfo = mDisplayManagerService.getDisplayInfo(displayId);
6981 if (newDisplayInfo != null) {
6982 displayInfo.copyFrom(newDisplayInfo);
6983 }
6984 displayContent.mInitialDisplayWidth = displayInfo.logicalWidth;
6985 displayContent.mInitialDisplayHeight = displayInfo.logicalHeight;
6986 displayContent.mInitialDisplayDensity = displayInfo.logicalDensityDpi;
6987 displayContent.mBaseDisplayWidth = displayContent.mInitialDisplayWidth;
6988 displayContent.mBaseDisplayHeight = displayContent.mInitialDisplayHeight;
6989 displayContent.mBaseDisplayDensity = displayContent.mInitialDisplayDensity;
Craig Mautner6601b7b2013-04-29 10:29:11 -07006990 displayContent.mBaseDisplayRect.set(0, 0,
6991 displayContent.mBaseDisplayWidth, displayContent.mBaseDisplayHeight);
Jeff Brownbd6e1502012-08-28 03:27:37 -07006992 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07006993 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07006994 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07006995 }
6996
Dianne Hackborn661cd522011-08-22 00:26:20 -07006997 public void systemReady() {
6998 mPolicy.systemReady();
6999 }
7000
Craig Mautner59c00972012-07-30 12:10:24 -07007001 // TODO(multidisplay): Call isScreenOn for each display.
Craig Mautner3d7b7d52012-05-24 11:28:26 -07007002 private void sendScreenStatusToClientsLocked() {
Craig Mautner59c00972012-07-30 12:10:24 -07007003 final boolean on = mPowerManager.isScreenOn();
Craig Mautnerf8924152013-07-16 09:10:55 -07007004 final int numDisplays = mDisplayContents.size();
7005 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
7006 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
7007 final int numWindows = windows.size();
7008 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
7009 try {
7010 windows.get(winNdx).mClient.dispatchScreenState(on);
7011 } catch (RemoteException e) {
7012 // Ignored
7013 }
Romain Guy7e4e5612012-03-05 14:37:29 -08007014 }
7015 }
7016 }
7017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007018 // -------------------------------------------------------------
7019 // Async Handler
7020 // -------------------------------------------------------------
7021
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08007022 final class H extends Handler {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007023 public static final int REPORT_FOCUS_CHANGE = 2;
7024 public static final int REPORT_LOSING_FOCUS = 3;
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08007025 public static final int DO_TRAVERSAL = 4;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007026 public static final int ADD_STARTING = 5;
7027 public static final int REMOVE_STARTING = 6;
7028 public static final int FINISHED_STARTING = 7;
7029 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07007030 public static final int REPORT_APPLICATION_TOKEN_DRAWN = 9;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007031 public static final int WINDOW_FREEZE_TIMEOUT = 11;
Craig Mautner259328c2012-08-21 19:30:58 -07007032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007033 public static final int APP_TRANSITION_TIMEOUT = 13;
7034 public static final int PERSIST_ANIMATION_SCALE = 14;
7035 public static final int FORCE_GC = 15;
7036 public static final int ENABLE_SCREEN = 16;
7037 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007038 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07007039 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07007040 public static final int DRAG_START_TIMEOUT = 20;
Chris Tated4533f12010-10-19 15:15:08 -07007041 public static final int DRAG_END_TIMEOUT = 21;
Jeff Brown2992ea72011-01-28 22:04:14 -08007042 public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07007043 public static final int BOOT_TIMEOUT = 23;
Dianne Hackborn38e29a62011-09-18 14:43:08 -07007044 public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
Craig Mautner96868332012-12-04 14:29:11 -08007045 public static final int SHOW_STRICT_MODE_VIOLATION = 25;
7046 public static final int DO_ANIMATION_CALLBACK = 26;
Romain Guy06882f82009-06-10 13:36:04 -07007047
Craig Mautner96868332012-12-04 14:29:11 -08007048 public static final int DO_DISPLAY_ADDED = 27;
7049 public static final int DO_DISPLAY_REMOVED = 28;
7050 public static final int DO_DISPLAY_CHANGED = 29;
Craig Mautner722285e2012-09-07 13:55:58 -07007051
Craig Mautner96868332012-12-04 14:29:11 -08007052 public static final int CLIENT_FREEZE_TIMEOUT = 30;
Craig Mautnerd3c93382013-04-24 14:23:39 -07007053 public static final int TAP_OUTSIDE_STACK = 31;
Craig Mautner5eda9b32013-07-02 11:58:16 -07007054 public static final int NOTIFY_ACTIVITY_DRAWN = 32;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007055
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007056 @Override
7057 public void handleMessage(Message msg) {
Craig Mautner7d8df392012-04-06 15:26:23 -07007058 if (DEBUG_WINDOW_TRACE) {
7059 Slog.v(TAG, "handleMessage: entry what=" + msg.what);
7060 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007061 switch (msg.what) {
7062 case REPORT_FOCUS_CHANGE: {
7063 WindowState lastFocus;
7064 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07007065
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007066 synchronized(mWindowMap) {
7067 lastFocus = mLastFocus;
7068 newFocus = mCurrentFocus;
7069 if (lastFocus == newFocus) {
7070 // Focus is not changing, so nothing to do.
7071 return;
7072 }
7073 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007074 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007075 // + " to " + newFocus);
7076 if (newFocus != null && lastFocus != null
7077 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007078 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007079 mLosingFocus.add(lastFocus);
7080 lastFocus = null;
7081 }
7082 }
7083
7084 if (lastFocus != newFocus) {
7085 //System.out.println("Changing focus from " + lastFocus
7086 // + " to " + newFocus);
7087 if (newFocus != null) {
Dianne Hackborne3f23a32013-03-01 13:25:35 -08007088 //Slog.i(TAG, "Gaining focus: " + newFocus);
7089 newFocus.reportFocusChangedSerialized(true, mInTouchMode);
Konstantin Lopyrev5e7833a2010-08-09 17:01:11 -07007090 notifyFocusChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007091 }
7092
7093 if (lastFocus != null) {
Dianne Hackborne3f23a32013-03-01 13:25:35 -08007094 //Slog.i(TAG, "Losing focus: " + lastFocus);
7095 lastFocus.reportFocusChangedSerialized(false, mInTouchMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007096 }
7097 }
7098 } break;
7099
7100 case REPORT_LOSING_FOCUS: {
7101 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07007102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007103 synchronized(mWindowMap) {
7104 losers = mLosingFocus;
7105 mLosingFocus = new ArrayList<WindowState>();
7106 }
7107
7108 final int N = losers.size();
7109 for (int i=0; i<N; i++) {
Dianne Hackborne3f23a32013-03-01 13:25:35 -08007110 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
7111 losers.get(i).reportFocusChangedSerialized(false, mInTouchMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007112 }
7113 } break;
7114
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08007115 case DO_TRAVERSAL: {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007116 synchronized(mWindowMap) {
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08007117 mTraversalScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007118 performLayoutAndPlaceSurfacesLocked();
7119 }
7120 } break;
7121
7122 case ADD_STARTING: {
7123 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7124 final StartingData sd = wtoken.startingData;
7125
7126 if (sd == null) {
7127 // Animation has been canceled... do nothing.
7128 return;
7129 }
Romain Guy06882f82009-06-10 13:36:04 -07007130
Joe Onorato8a9b2202010-02-26 18:56:32 -08007131 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007132 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07007133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007134 View view = null;
7135 try {
7136 view = mPolicy.addStartingWindow(
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07007137 wtoken.token, sd.pkg, sd.theme, sd.compatInfo,
Adam Powell04fe6eb2013-05-31 14:39:48 -07007138 sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.logo, sd.windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007139 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007140 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007141 }
7142
7143 if (view != null) {
7144 boolean abort = false;
7145
7146 synchronized(mWindowMap) {
7147 if (wtoken.removed || wtoken.startingData == null) {
7148 // If the window was successfully added, then
7149 // we need to remove it.
7150 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007151 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007152 "Aborted starting " + wtoken
7153 + ": removed=" + wtoken.removed
7154 + " startingData=" + wtoken.startingData);
7155 wtoken.startingWindow = null;
7156 wtoken.startingData = null;
7157 abort = true;
7158 }
7159 } else {
7160 wtoken.startingView = view;
7161 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007162 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007163 "Added starting " + wtoken
7164 + ": startingWindow="
7165 + wtoken.startingWindow + " startingView="
7166 + wtoken.startingView);
7167 }
7168
7169 if (abort) {
7170 try {
7171 mPolicy.removeStartingWindow(wtoken.token, view);
7172 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007173 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007174 }
7175 }
7176 }
7177 } break;
7178
7179 case REMOVE_STARTING: {
7180 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7181 IBinder token = null;
7182 View view = null;
7183 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007184 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007185 + wtoken + ": startingWindow="
7186 + wtoken.startingWindow + " startingView="
7187 + wtoken.startingView);
7188 if (wtoken.startingWindow != null) {
7189 view = wtoken.startingView;
7190 token = wtoken.token;
7191 wtoken.startingData = null;
7192 wtoken.startingView = null;
7193 wtoken.startingWindow = null;
Craig Mautner38b24782012-07-02 16:21:28 -07007194 wtoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007195 }
7196 }
7197 if (view != null) {
7198 try {
7199 mPolicy.removeStartingWindow(token, view);
7200 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007201 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007202 }
7203 }
7204 } break;
7205
7206 case FINISHED_STARTING: {
7207 IBinder token = null;
7208 View view = null;
7209 while (true) {
7210 synchronized (mWindowMap) {
7211 final int N = mFinishedStarting.size();
7212 if (N <= 0) {
7213 break;
7214 }
7215 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
7216
Joe Onorato8a9b2202010-02-26 18:56:32 -08007217 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007218 "Finished starting " + wtoken
7219 + ": startingWindow=" + wtoken.startingWindow
7220 + " startingView=" + wtoken.startingView);
7221
7222 if (wtoken.startingWindow == null) {
7223 continue;
7224 }
7225
7226 view = wtoken.startingView;
7227 token = wtoken.token;
7228 wtoken.startingData = null;
7229 wtoken.startingView = null;
7230 wtoken.startingWindow = null;
Craig Mautner38b24782012-07-02 16:21:28 -07007231 wtoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007232 }
7233
7234 try {
7235 mPolicy.removeStartingWindow(token, view);
7236 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007237 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007238 }
7239 }
7240 } break;
7241
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07007242 case REPORT_APPLICATION_TOKEN_DRAWN: {
7243 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7244
7245 try {
7246 if (DEBUG_VISIBILITY) Slog.v(
7247 TAG, "Reporting drawn in " + wtoken);
7248 wtoken.appToken.windowsDrawn();
7249 } catch (RemoteException ex) {
7250 }
7251 } break;
7252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007253 case REPORT_APPLICATION_TOKEN_WINDOWS: {
7254 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7255
7256 boolean nowVisible = msg.arg1 != 0;
7257 boolean nowGone = msg.arg2 != 0;
7258
7259 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007260 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007261 TAG, "Reporting visible in " + wtoken
7262 + " visible=" + nowVisible
7263 + " gone=" + nowGone);
7264 if (nowVisible) {
7265 wtoken.appToken.windowsVisible();
7266 } else {
7267 wtoken.appToken.windowsGone();
7268 }
7269 } catch (RemoteException ex) {
7270 }
7271 } break;
Romain Guy06882f82009-06-10 13:36:04 -07007272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007273 case WINDOW_FREEZE_TIMEOUT: {
Craig Mautner59c00972012-07-30 12:10:24 -07007274 // TODO(multidisplay): Can non-default displays rotate?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007275 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007276 Slog.w(TAG, "Window freeze timeout expired.");
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007277 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07007278 int i = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007279 while (i > 0) {
7280 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07007281 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007282 if (w.mOrientationChanging) {
7283 w.mOrientationChanging = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07007284 w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
7285 - mDisplayFreezeTime);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007286 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007287 }
7288 }
7289 performLayoutAndPlaceSurfacesLocked();
7290 }
7291 break;
7292 }
Romain Guy06882f82009-06-10 13:36:04 -07007293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007294 case APP_TRANSITION_TIMEOUT: {
7295 synchronized (mWindowMap) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08007296 if (mAppTransition.isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08007297 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** APP TRANSITION TIMEOUT");
7298 mAppTransition.setTimeout();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007299 performLayoutAndPlaceSurfacesLocked();
7300 }
7301 }
7302 break;
7303 }
Romain Guy06882f82009-06-10 13:36:04 -07007304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007305 case PERSIST_ANIMATION_SCALE: {
Jeff Sharkey6e2bee72012-10-01 13:39:08 -07007306 Settings.Global.putFloat(mContext.getContentResolver(),
7307 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
7308 Settings.Global.putFloat(mContext.getContentResolver(),
7309 Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
7310 Settings.Global.putFloat(mContext.getContentResolver(),
7311 Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007312 break;
7313 }
Romain Guy06882f82009-06-10 13:36:04 -07007314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007315 case FORCE_GC: {
Craig Mautner1caa3992012-06-22 09:46:48 -07007316 synchronized (mWindowMap) {
Craig Mautner96868332012-12-04 14:29:11 -08007317 // Since we're holding both mWindowMap and mAnimator we don't need to
7318 // hold mAnimator.mLayoutToAnim.
7319 if (mAnimator.mAnimating || mAnimationScheduled) {
7320 // If we are animating, don't do the gc now but
7321 // delay a bit so we don't interrupt the animation.
7322 sendEmptyMessageDelayed(H.FORCE_GC, 2000);
7323 return;
7324 }
7325 // If we are currently rotating the display, it will
7326 // schedule a new message when done.
7327 if (mDisplayFrozen) {
7328 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007329 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007330 }
7331 Runtime.getRuntime().gc();
7332 break;
7333 }
Romain Guy06882f82009-06-10 13:36:04 -07007334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007335 case ENABLE_SCREEN: {
7336 performEnableScreen();
7337 break;
7338 }
Romain Guy06882f82009-06-10 13:36:04 -07007339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007340 case APP_FREEZE_TIMEOUT: {
7341 synchronized (mWindowMap) {
Craig Mautner96868332012-12-04 14:29:11 -08007342 Slog.w(TAG, "App freeze timeout expired.");
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08007343 DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautnerd9a22882013-03-16 15:00:36 -07007344 final ArrayList<Task> tasks = displayContent.getTasks();
Craig Mautnerf81b90872013-02-26 13:02:43 -08007345 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
7346 AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
7347 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
7348 AppWindowToken tok = tokens.get(tokenNdx);
7349 if (tok.mAppAnimator.freezingScreen) {
7350 Slog.w(TAG, "Force clearing freeze: " + tok);
7351 unsetAppFreezingScreenLocked(tok, true, true);
7352 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007353 }
7354 }
7355 }
7356 break;
7357 }
Romain Guy06882f82009-06-10 13:36:04 -07007358
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007359 case CLIENT_FREEZE_TIMEOUT: {
7360 synchronized (mWindowMap) {
7361 if (mClientFreezingScreen) {
7362 mClientFreezingScreen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07007363 mLastFinishedFreezeSource = "client-timeout";
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007364 stopFreezingDisplayLocked();
7365 }
7366 }
7367 break;
7368 }
7369
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007370 case SEND_NEW_CONFIGURATION: {
7371 removeMessages(SEND_NEW_CONFIGURATION);
7372 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07007373 break;
7374 }
Romain Guy06882f82009-06-10 13:36:04 -07007375
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07007376 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007377 if (mWindowsChanged) {
7378 synchronized (mWindowMap) {
7379 mWindowsChanged = false;
7380 }
7381 notifyWindowsChanged();
7382 }
7383 break;
7384 }
7385
Christopher Tatea53146c2010-09-07 11:57:52 -07007386 case DRAG_START_TIMEOUT: {
7387 IBinder win = (IBinder)msg.obj;
7388 if (DEBUG_DRAG) {
7389 Slog.w(TAG, "Timeout starting drag by win " + win);
7390 }
7391 synchronized (mWindowMap) {
7392 // !!! TODO: ANR the app that has failed to start the drag in time
7393 if (mDragState != null) {
Chris Tated4533f12010-10-19 15:15:08 -07007394 mDragState.unregister();
Jeff Brown2e44b072011-01-24 15:21:56 -08007395 mInputMonitor.updateInputWindowsLw(true /*force*/);
Christopher Tatea53146c2010-09-07 11:57:52 -07007396 mDragState.reset();
7397 mDragState = null;
7398 }
7399 }
Chris Tated4533f12010-10-19 15:15:08 -07007400 break;
Christopher Tatea53146c2010-09-07 11:57:52 -07007401 }
7402
Chris Tated4533f12010-10-19 15:15:08 -07007403 case DRAG_END_TIMEOUT: {
7404 IBinder win = (IBinder)msg.obj;
7405 if (DEBUG_DRAG) {
7406 Slog.w(TAG, "Timeout ending drag to win " + win);
7407 }
7408 synchronized (mWindowMap) {
7409 // !!! TODO: ANR the drag-receiving app
Christopher Tated9be36c2011-08-16 16:09:33 -07007410 if (mDragState != null) {
7411 mDragState.mDragResult = false;
7412 mDragState.endDragLw();
7413 }
Chris Tated4533f12010-10-19 15:15:08 -07007414 }
7415 break;
7416 }
Jeff Brown2992ea72011-01-28 22:04:14 -08007417
7418 case REPORT_HARD_KEYBOARD_STATUS_CHANGE: {
7419 notifyHardKeyboardStatusChange();
7420 break;
7421 }
Dianne Hackborn38e29a62011-09-18 14:43:08 -07007422
7423 case BOOT_TIMEOUT: {
7424 performBootTimeout();
7425 break;
7426 }
7427
7428 case WAITING_FOR_DRAWN_TIMEOUT: {
7429 Pair<WindowState, IRemoteCallback> pair;
7430 synchronized (mWindowMap) {
7431 pair = (Pair<WindowState, IRemoteCallback>)msg.obj;
7432 Slog.w(TAG, "Timeout waiting for drawn: " + pair.first);
7433 if (!mWaitingForDrawn.remove(pair)) {
7434 return;
7435 }
7436 }
7437 try {
7438 pair.second.sendResult(null);
7439 } catch (RemoteException e) {
7440 }
7441 break;
7442 }
Craig Mautnera608b882012-03-30 13:03:49 -07007443
Craig Mautner0447a812012-05-22 16:01:31 -07007444 case SHOW_STRICT_MODE_VIOLATION: {
Chris Craik3198ef32012-10-10 14:52:30 -07007445 showStrictModeViolation(msg.arg1, msg.arg2);
Craig Mautner0447a812012-05-22 16:01:31 -07007446 break;
7447 }
7448
Dianne Hackborn84375872012-06-01 19:03:50 -07007449 case DO_ANIMATION_CALLBACK: {
7450 try {
7451 ((IRemoteCallback)msg.obj).sendResult(null);
7452 } catch (RemoteException e) {
7453 }
7454 break;
7455 }
Craig Mautner722285e2012-09-07 13:55:58 -07007456
Craig Mautner722285e2012-09-07 13:55:58 -07007457 case DO_DISPLAY_ADDED:
7458 synchronized (mWindowMap) {
7459 handleDisplayAddedLocked(msg.arg1);
7460 }
7461 break;
7462
7463 case DO_DISPLAY_REMOVED:
7464 synchronized (mWindowMap) {
7465 handleDisplayRemovedLocked(msg.arg1);
7466 }
7467 break;
7468
7469 case DO_DISPLAY_CHANGED:
7470 synchronized (mWindowMap) {
7471 handleDisplayChangedLocked(msg.arg1);
7472 }
7473 break;
Craig Mautnerd3c93382013-04-24 14:23:39 -07007474
Craig Mautnereb957862013-04-24 15:34:32 -07007475 case TAP_OUTSIDE_STACK: {
7476 int stackId;
Craig Mautnerd3c93382013-04-24 14:23:39 -07007477 synchronized (mWindowMap) {
Craig Mautnereb957862013-04-24 15:34:32 -07007478 stackId = ((DisplayContent)msg.obj).stackIdFromPoint(msg.arg1, msg.arg2);
7479 }
7480 if (stackId >= 0) {
7481 try {
7482 mActivityManager.setFocusedStack(stackId);
7483 } catch (RemoteException e) {
Craig Mautnerd3c93382013-04-24 14:23:39 -07007484 }
7485 }
Craig Mautnereb957862013-04-24 15:34:32 -07007486 }
Craig Mautner5eda9b32013-07-02 11:58:16 -07007487 break;
7488 case NOTIFY_ACTIVITY_DRAWN:
7489 try {
7490 mActivityManager.notifyActivityDrawn((IBinder) msg.obj);
7491 } catch (RemoteException e) {
7492 }
7493 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007494 }
Craig Mautner7d8df392012-04-06 15:26:23 -07007495 if (DEBUG_WINDOW_TRACE) {
7496 Slog.v(TAG, "handleMessage: exit");
7497 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007498 }
7499 }
7500
7501 // -------------------------------------------------------------
7502 // IWindowManager API
7503 // -------------------------------------------------------------
7504
Craig Mautner7d8df392012-04-06 15:26:23 -07007505 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007506 public IWindowSession openSession(IInputMethodClient client,
7507 IInputContext inputContext) {
7508 if (client == null) throw new IllegalArgumentException("null client");
7509 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08007510 Session session = new Session(this, client, inputContext);
Jeff Brown46b9ac02010-04-22 18:58:52 -07007511 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007512 }
7513
Craig Mautner7d8df392012-04-06 15:26:23 -07007514 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007515 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
7516 synchronized (mWindowMap) {
7517 // The focus for the client is the window immediately below
7518 // where we would place the input method window.
7519 int idx = findDesiredInputMethodWindowIndexLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007520 if (idx > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07007521 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007522 WindowState imFocus = getDefaultWindowListLocked().get(idx-1);
Dianne Hackbornac920872012-05-22 11:49:49 -07007523 if (DEBUG_INPUT_METHOD) {
7524 Slog.i(TAG, "Desired input method target: " + imFocus);
Craig Mautner59c00972012-07-30 12:10:24 -07007525 Slog.i(TAG, "Current focus: " + mCurrentFocus);
7526 Slog.i(TAG, "Last focus: " + mLastFocus);
Dianne Hackbornac920872012-05-22 11:49:49 -07007527 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007528 if (imFocus != null) {
Dianne Hackborne75d8722011-01-27 19:37:40 -08007529 // This may be a starting window, in which case we still want
7530 // to count it as okay.
7531 if (imFocus.mAttrs.type == LayoutParams.TYPE_APPLICATION_STARTING
7532 && imFocus.mAppToken != null) {
7533 // The client has definitely started, so it really should
7534 // have a window in this app token. Let's look for it.
7535 for (int i=0; i<imFocus.mAppToken.windows.size(); i++) {
7536 WindowState w = imFocus.mAppToken.windows.get(i);
7537 if (w != imFocus) {
Dianne Hackbornac920872012-05-22 11:49:49 -07007538 Log.i(TAG, "Switching to real app window: " + w);
Dianne Hackborne75d8722011-01-27 19:37:40 -08007539 imFocus = w;
7540 break;
7541 }
7542 }
7543 }
Dianne Hackbornac920872012-05-22 11:49:49 -07007544 if (DEBUG_INPUT_METHOD) {
7545 Slog.i(TAG, "IM target client: " + imFocus.mSession.mClient);
7546 if (imFocus.mSession.mClient != null) {
7547 Slog.i(TAG, "IM target client binder: "
7548 + imFocus.mSession.mClient.asBinder());
7549 Slog.i(TAG, "Requesting client binder: " + client.asBinder());
7550 }
7551 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007552 if (imFocus.mSession.mClient != null &&
7553 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
7554 return true;
7555 }
7556 }
7557 }
Craig Mautner59c00972012-07-30 12:10:24 -07007558
7559 // Okay, how about this... what is the current focus?
7560 // It seems in some cases we may not have moved the IM
7561 // target window, such as when it was in a pop-up window,
7562 // so let's also look at the current focus. (An example:
7563 // go to Gmail, start searching so the keyboard goes up,
7564 // press home. Sometimes the IME won't go down.)
7565 // Would be nice to fix this more correctly, but it's
7566 // way at the end of a release, and this should be good enough.
7567 if (mCurrentFocus != null && mCurrentFocus.mSession.mClient != null
7568 && mCurrentFocus.mSession.mClient.asBinder() == client.asBinder()) {
7569 return true;
7570 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007571 }
7572 return false;
7573 }
Romain Guy06882f82009-06-10 13:36:04 -07007574
Dianne Hackborn672cf452013-03-26 15:24:24 -07007575 @Override
Craig Mautner59c00972012-07-30 12:10:24 -07007576 public void getInitialDisplaySize(int displayId, Point size) {
Craig Mautner58106812012-12-28 12:27:40 -08007577 synchronized (mWindowMap) {
7578 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Jeff Browna506a6e2013-06-04 00:02:38 -07007579 if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
Craig Mautner58106812012-12-28 12:27:40 -08007580 synchronized(displayContent.mDisplaySizeLock) {
7581 size.x = displayContent.mInitialDisplayWidth;
7582 size.y = displayContent.mInitialDisplayHeight;
7583 }
Craig Mautner2d5618c2012-10-18 13:55:47 -07007584 }
Dianne Hackborn7d608422011-08-07 16:24:18 -07007585 }
7586 }
7587
Craig Mautner2d5618c2012-10-18 13:55:47 -07007588 @Override
Dianne Hackborn672cf452013-03-26 15:24:24 -07007589 public void getBaseDisplaySize(int displayId, Point size) {
7590 synchronized (mWindowMap) {
7591 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Jeff Browna506a6e2013-06-04 00:02:38 -07007592 if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
Dianne Hackborn672cf452013-03-26 15:24:24 -07007593 synchronized(displayContent.mDisplaySizeLock) {
7594 size.x = displayContent.mBaseDisplayWidth;
7595 size.y = displayContent.mBaseDisplayHeight;
7596 }
7597 }
7598 }
7599 }
7600
7601 @Override
Jeff Brown43aa1592012-09-10 17:36:31 -07007602 public void setForcedDisplaySize(int displayId, int width, int height) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08007603 if (mContext.checkCallingOrSelfPermission(
7604 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7605 PackageManager.PERMISSION_GRANTED) {
7606 throw new SecurityException("Must hold permission " +
7607 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7608 }
7609 if (displayId != Display.DEFAULT_DISPLAY) {
7610 throw new IllegalArgumentException("Can only set the default display");
7611 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007612 synchronized(mWindowMap) {
Jeff Brown43aa1592012-09-10 17:36:31 -07007613 // Set some sort of reasonable bounds on the size of the display that we
7614 // will try to emulate.
7615 final int MIN_WIDTH = 200;
7616 final int MIN_HEIGHT = 200;
7617 final int MAX_SCALE = 2;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007618 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007619 if (displayContent != null) {
7620 width = Math.min(Math.max(width, MIN_WIDTH),
7621 displayContent.mInitialDisplayWidth * MAX_SCALE);
7622 height = Math.min(Math.max(height, MIN_HEIGHT),
7623 displayContent.mInitialDisplayHeight * MAX_SCALE);
7624 setForcedDisplaySizeLocked(displayContent, width, height);
7625 Settings.Global.putString(mContext.getContentResolver(),
7626 Settings.Global.DISPLAY_SIZE_FORCED, width + "," + height);
7627 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007628 }
7629 }
7630
Dianne Hackborndde331c2012-08-03 14:01:57 -07007631 private void readForcedDisplaySizeAndDensityLocked(final DisplayContent displayContent) {
Colin Crossef96fd92013-07-18 17:09:56 -07007632 String sizeStr = Settings.Global.getString(mContext.getContentResolver(),
Jeff Brown43aa1592012-09-10 17:36:31 -07007633 Settings.Global.DISPLAY_SIZE_FORCED);
Colin Crossef96fd92013-07-18 17:09:56 -07007634 if (sizeStr == null) {
7635 sizeStr = SystemProperties.get(SIZE_OVERRIDE, null);
7636 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007637 if (sizeStr != null && sizeStr.length() > 0) {
7638 final int pos = sizeStr.indexOf(',');
7639 if (pos > 0 && sizeStr.lastIndexOf(',') == pos) {
7640 int width, height;
7641 try {
7642 width = Integer.parseInt(sizeStr.substring(0, pos));
7643 height = Integer.parseInt(sizeStr.substring(pos+1));
7644 synchronized(displayContent.mDisplaySizeLock) {
7645 if (displayContent.mBaseDisplayWidth != width
7646 || displayContent.mBaseDisplayHeight != height) {
Dianne Hackborndde331c2012-08-03 14:01:57 -07007647 Slog.i(TAG, "FORCED DISPLAY SIZE: " + width + "x" + height);
7648 displayContent.mBaseDisplayWidth = width;
7649 displayContent.mBaseDisplayHeight = height;
7650 }
7651 }
7652 } catch (NumberFormatException ex) {
7653 }
7654 }
Joe Onorato571ae902011-05-24 13:48:43 -07007655 }
Colin Crossef96fd92013-07-18 17:09:56 -07007656 String densityStr = Settings.Global.getString(mContext.getContentResolver(),
Jeff Brown43aa1592012-09-10 17:36:31 -07007657 Settings.Global.DISPLAY_DENSITY_FORCED);
Colin Crossef96fd92013-07-18 17:09:56 -07007658 if (densityStr == null) {
7659 densityStr = SystemProperties.get(DENSITY_OVERRIDE, null);
7660 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007661 if (densityStr != null && densityStr.length() > 0) {
7662 int density;
7663 try {
7664 density = Integer.parseInt(densityStr);
7665 synchronized(displayContent.mDisplaySizeLock) {
7666 if (displayContent.mBaseDisplayDensity != density) {
Dianne Hackborndde331c2012-08-03 14:01:57 -07007667 Slog.i(TAG, "FORCED DISPLAY DENSITY: " + density);
7668 displayContent.mBaseDisplayDensity = density;
7669 }
7670 }
7671 } catch (NumberFormatException ex) {
7672 }
Joe Onorato571ae902011-05-24 13:48:43 -07007673 }
Joe Onorato571ae902011-05-24 13:48:43 -07007674 }
7675
Craig Mautner2d5618c2012-10-18 13:55:47 -07007676 // displayContent must not be null
Craig Mautner59c00972012-07-30 12:10:24 -07007677 private void setForcedDisplaySizeLocked(DisplayContent displayContent, int width, int height) {
Joe Onorato571ae902011-05-24 13:48:43 -07007678 Slog.i(TAG, "Using new display size: " + width + "x" + height);
7679
Craig Mautner59c00972012-07-30 12:10:24 -07007680 synchronized(displayContent.mDisplaySizeLock) {
7681 displayContent.mBaseDisplayWidth = width;
7682 displayContent.mBaseDisplayHeight = height;
Dianne Hackborn1fbee792011-11-30 11:29:58 -08007683 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007684 reconfigureDisplayLocked(displayContent);
7685 }
7686
Craig Mautner2d5618c2012-10-18 13:55:47 -07007687 @Override
Dianne Hackborndde331c2012-08-03 14:01:57 -07007688 public void clearForcedDisplaySize(int displayId) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08007689 if (mContext.checkCallingOrSelfPermission(
7690 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7691 PackageManager.PERMISSION_GRANTED) {
7692 throw new SecurityException("Must hold permission " +
7693 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7694 }
7695 if (displayId != Display.DEFAULT_DISPLAY) {
7696 throw new IllegalArgumentException("Can only set the default display");
7697 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007698 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007699 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007700 if (displayContent != null) {
7701 setForcedDisplaySizeLocked(displayContent, displayContent.mInitialDisplayWidth,
7702 displayContent.mInitialDisplayHeight);
7703 Settings.Global.putString(mContext.getContentResolver(),
7704 Settings.Global.DISPLAY_SIZE_FORCED, "");
7705 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007706 }
7707 }
7708
Craig Mautner2d5618c2012-10-18 13:55:47 -07007709 @Override
Dianne Hackborn672cf452013-03-26 15:24:24 -07007710 public int getInitialDisplayDensity(int displayId) {
7711 synchronized (mWindowMap) {
7712 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Jeff Browna506a6e2013-06-04 00:02:38 -07007713 if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
Dianne Hackborn672cf452013-03-26 15:24:24 -07007714 synchronized(displayContent.mDisplaySizeLock) {
7715 return displayContent.mInitialDisplayDensity;
7716 }
7717 }
7718 }
7719 return -1;
7720 }
7721
7722 @Override
7723 public int getBaseDisplayDensity(int displayId) {
7724 synchronized (mWindowMap) {
7725 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Jeff Browna506a6e2013-06-04 00:02:38 -07007726 if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
Dianne Hackborn672cf452013-03-26 15:24:24 -07007727 synchronized(displayContent.mDisplaySizeLock) {
7728 return displayContent.mBaseDisplayDensity;
7729 }
7730 }
7731 }
7732 return -1;
7733 }
7734
7735 @Override
Dianne Hackborndde331c2012-08-03 14:01:57 -07007736 public void setForcedDisplayDensity(int displayId, int density) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08007737 if (mContext.checkCallingOrSelfPermission(
7738 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7739 PackageManager.PERMISSION_GRANTED) {
7740 throw new SecurityException("Must hold permission " +
7741 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7742 }
7743 if (displayId != Display.DEFAULT_DISPLAY) {
7744 throw new IllegalArgumentException("Can only set the default display");
7745 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007746 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007747 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007748 if (displayContent != null) {
7749 setForcedDisplayDensityLocked(displayContent, density);
7750 Settings.Global.putString(mContext.getContentResolver(),
7751 Settings.Global.DISPLAY_DENSITY_FORCED, Integer.toString(density));
7752 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007753 }
7754 }
7755
Craig Mautner2d5618c2012-10-18 13:55:47 -07007756 // displayContent must not be null
Dianne Hackborndde331c2012-08-03 14:01:57 -07007757 private void setForcedDisplayDensityLocked(DisplayContent displayContent, int density) {
7758 Slog.i(TAG, "Using new display density: " + density);
7759
7760 synchronized(displayContent.mDisplaySizeLock) {
7761 displayContent.mBaseDisplayDensity = density;
7762 }
7763 reconfigureDisplayLocked(displayContent);
7764 }
7765
Craig Mautner2d5618c2012-10-18 13:55:47 -07007766 @Override
Dianne Hackborndde331c2012-08-03 14:01:57 -07007767 public void clearForcedDisplayDensity(int displayId) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08007768 if (mContext.checkCallingOrSelfPermission(
7769 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7770 PackageManager.PERMISSION_GRANTED) {
7771 throw new SecurityException("Must hold permission " +
7772 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7773 }
7774 if (displayId != Display.DEFAULT_DISPLAY) {
7775 throw new IllegalArgumentException("Can only set the default display");
7776 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007777 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007778 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007779 if (displayContent != null) {
7780 setForcedDisplayDensityLocked(displayContent, displayContent.mInitialDisplayDensity);
7781 Settings.Global.putString(mContext.getContentResolver(),
7782 Settings.Global.DISPLAY_DENSITY_FORCED, "");
7783 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007784 }
7785 }
7786
Craig Mautner2d5618c2012-10-18 13:55:47 -07007787 // displayContent must not be null
Dianne Hackborndde331c2012-08-03 14:01:57 -07007788 private void reconfigureDisplayLocked(DisplayContent displayContent) {
Craig Mautner69b08182012-09-05 13:07:13 -07007789 // TODO: Multidisplay: for now only use with default display.
Jeff Browne215f262012-09-10 16:01:14 -07007790 mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
7791 displayContent.mBaseDisplayWidth,
7792 displayContent.mBaseDisplayHeight,
7793 displayContent.mBaseDisplayDensity);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007794
Craig Mautner19d59bc2012-09-04 11:15:56 -07007795 displayContent.layoutNeeded = true;
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007796
7797 boolean configChanged = updateOrientationFromAppTokensLocked(false);
7798 mTempConfiguration.setToDefaults();
7799 mTempConfiguration.fontScale = mCurConfiguration.fontScale;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08007800 if (computeScreenConfigurationLocked(mTempConfiguration)) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007801 if (mCurConfiguration.diff(mTempConfiguration) != 0) {
7802 configChanged = true;
7803 }
7804 }
7805
7806 if (configChanged) {
7807 mWaitingForConfig = true;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007808 startFreezingDisplayLocked(false, 0, 0);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007809 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
7810 }
7811
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007812 performLayoutAndPlaceSurfacesLocked();
7813 }
7814
Craig Mautner11bf9a52013-02-19 14:08:51 -08007815 @Override
Dianne Hackbornc652de82013-02-15 16:32:56 -08007816 public void setOverscan(int displayId, int left, int top, int right, int bottom) {
7817 if (mContext.checkCallingOrSelfPermission(
7818 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7819 PackageManager.PERMISSION_GRANTED) {
7820 throw new SecurityException("Must hold permission " +
7821 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7822 }
7823 synchronized(mWindowMap) {
7824 DisplayContent displayContent = getDisplayContentLocked(displayId);
7825 if (displayContent != null) {
7826 mDisplayManagerService.setOverscan(displayId, left, top, right, bottom);
7827 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
7828 synchronized(displayContent.mDisplaySizeLock) {
7829 displayInfo.overscanLeft = left;
7830 displayInfo.overscanTop = top;
7831 displayInfo.overscanRight = right;
7832 displayInfo.overscanBottom = bottom;
7833 }
7834 mPolicy.setDisplayOverscan(displayContent.getDisplay(), left, top, right, bottom);
7835 displayContent.layoutNeeded = true;
7836 mDisplaySettings.setOverscanLocked(displayInfo.name, left, top, right, bottom);
7837 mDisplaySettings.writeSettingsLocked();
7838 performLayoutAndPlaceSurfacesLocked();
7839 }
7840 }
7841 }
7842
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007843 // -------------------------------------------------------------
7844 // Internals
7845 // -------------------------------------------------------------
7846
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007847 final WindowState windowForClientLocked(Session session, IWindow client,
7848 boolean throwOnError) {
7849 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007850 }
Romain Guy06882f82009-06-10 13:36:04 -07007851
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007852 final WindowState windowForClientLocked(Session session, IBinder client,
7853 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007854 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007855 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007856 TAG, "Looking up client " + client + ": " + win);
7857 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007858 RuntimeException ex = new IllegalArgumentException(
7859 "Requested window " + client + " does not exist");
7860 if (throwOnError) {
7861 throw ex;
7862 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007863 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007864 return null;
7865 }
7866 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007867 RuntimeException ex = new IllegalArgumentException(
7868 "Requested window " + client + " is in session " +
7869 win.mSession + ", not " + session);
7870 if (throwOnError) {
7871 throw ex;
7872 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007873 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007874 return null;
7875 }
7876
7877 return win;
7878 }
7879
Dianne Hackborna8f60182009-09-01 19:01:50 -07007880 final void rebuildAppWindowListLocked() {
Craig Mautnerf8924152013-07-16 09:10:55 -07007881 final int numDisplays = mDisplayContents.size();
7882 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
7883 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
7884 rebuildAppWindowListLocked(displayContent);
Craig Mautner59c00972012-07-30 12:10:24 -07007885 }
7886 }
7887
7888 private void rebuildAppWindowListLocked(final DisplayContent displayContent) {
7889 final WindowList windows = displayContent.getWindowList();
7890 int NW = windows.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07007891 int i;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007892 int lastBelow = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007893 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007894
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007895 if (mRebuildTmp.length < NW) {
7896 mRebuildTmp = new WindowState[NW+10];
7897 }
7898
Dianne Hackborna8f60182009-09-01 19:01:50 -07007899 // First remove all existing app windows.
7900 i=0;
7901 while (i < NW) {
Craig Mautner59c00972012-07-30 12:10:24 -07007902 WindowState w = windows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007903 if (w.mAppToken != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07007904 WindowState win = windows.remove(i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007905 win.mRebuilding = true;
7906 mRebuildTmp[numRemoved] = win;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007907 mWindowsChanged = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07007908 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07007909 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007910 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07007911 continue;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007912 } else if (lastBelow == i-1) {
Craig Mautner65d11b32012-10-01 13:59:52 -07007913 if (w.mAttrs.type == TYPE_WALLPAPER || w.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007914 lastBelow = i;
7915 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07007916 }
7917 i++;
7918 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007919
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007920 // Keep whatever windows were below the app windows still below,
7921 // by skipping them.
7922 lastBelow++;
7923 i = lastBelow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007924
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007925 // First add all of the exiting app tokens... these are no longer
7926 // in the main app list, but still have windows shown. We put them
7927 // in the back because now that the animation is over we no longer
7928 // will care about them.
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08007929 AppTokenList exitingAppTokens = displayContent.mExitingAppTokens;
7930 int NT = exitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07007931 for (int j=0; j<NT; j++) {
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08007932 i = reAddAppWindowsLocked(displayContent, i, exitingAppTokens.get(j));
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007933 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007934
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007935 // And add in the still active app tokens in Z order.
Craig Mautnerd9a22882013-03-16 15:00:36 -07007936 final ArrayList<Task> tasks = displayContent.getTasks();
Craig Mautnerf81b90872013-02-26 13:02:43 -08007937 final int numTasks = tasks.size();
7938 for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
7939 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
7940 final int numTokens = tokens.size();
7941 for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
7942 final AppWindowToken wtoken = tokens.get(tokenNdx);
7943 i = reAddAppWindowsLocked(displayContent, i, wtoken);
7944 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07007945 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007946
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007947 i -= lastBelow;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007948 if (i != numRemoved) {
Craig Mautner9e4f28c2013-04-03 10:53:23 -07007949 Slog.w(TAG, "Rebuild removed " + numRemoved + " windows but added " + i,
7950 new RuntimeException("here").fillInStackTrace());
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007951 for (i=0; i<numRemoved; i++) {
7952 WindowState ws = mRebuildTmp[i];
7953 if (ws.mRebuilding) {
7954 StringWriter sw = new StringWriter();
Dianne Hackborn8c841092013-06-24 13:46:13 -07007955 PrintWriter pw = new FastPrintWriter(sw, false, 1024);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07007956 ws.dump(pw, "", true);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007957 pw.flush();
7958 Slog.w(TAG, "This window was lost: " + ws);
7959 Slog.w(TAG, sw.toString());
Craig Mautner96868332012-12-04 14:29:11 -08007960 ws.mWinAnimator.destroySurfaceLocked();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007961 }
7962 }
7963 Slog.w(TAG, "Current app token list:");
Craig Mautner496bdbb2013-02-14 09:32:55 -08007964 dumpAppTokensLocked();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007965 Slog.w(TAG, "Final window list:");
7966 dumpWindowsLocked();
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007967 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07007968 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007969
Craig Mautner59c00972012-07-30 12:10:24 -07007970 private final void assignLayersLocked(WindowList windows) {
7971 int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007972 int curBaseLayer = 0;
7973 int curLayer = 0;
7974 int i;
Romain Guy06882f82009-06-10 13:36:04 -07007975
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007976 if (DEBUG_LAYERS) {
7977 RuntimeException here = new RuntimeException("here");
7978 here.fillInStackTrace();
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07007979 Slog.v(TAG, "Assigning layers", here);
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007980 }
7981
Svetoslav Ganov55468c62012-10-15 15:09:02 -07007982 boolean anyLayerChanged = false;
7983
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007984 for (i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07007985 final WindowState w = windows.get(i);
Craig Mautneracafd192012-05-10 10:41:02 -07007986 final WindowStateAnimator winAnimator = w.mWinAnimator;
7987 boolean layerChanged = false;
7988 int oldLayer = w.mLayer;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007989 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
7990 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007991 curLayer += WINDOW_LAYER_MULTIPLIER;
7992 w.mLayer = curLayer;
7993 } else {
7994 curBaseLayer = curLayer = w.mBaseLayer;
7995 w.mLayer = curLayer;
7996 }
Craig Mautneracafd192012-05-10 10:41:02 -07007997 if (w.mLayer != oldLayer) {
7998 layerChanged = true;
Svetoslav Ganov55468c62012-10-15 15:09:02 -07007999 anyLayerChanged = true;
Craig Mautneracafd192012-05-10 10:41:02 -07008000 }
Craig Mautnerf7666462013-04-28 08:58:21 -07008001 final AppWindowToken wtoken = w.mAppToken;
Craig Mautneracafd192012-05-10 10:41:02 -07008002 oldLayer = winAnimator.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008003 if (w.mTargetAppToken != null) {
Craig Mautneracafd192012-05-10 10:41:02 -07008004 winAnimator.mAnimLayer =
Craig Mautner59431632012-04-04 11:56:44 -07008005 w.mLayer + w.mTargetAppToken.mAppAnimator.animLayerAdjustment;
Craig Mautnerf7666462013-04-28 08:58:21 -07008006 } else if (wtoken != null) {
Craig Mautneracafd192012-05-10 10:41:02 -07008007 winAnimator.mAnimLayer =
Craig Mautnerf7666462013-04-28 08:58:21 -07008008 w.mLayer + wtoken.mAppAnimator.animLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008009 } else {
Craig Mautneracafd192012-05-10 10:41:02 -07008010 winAnimator.mAnimLayer = w.mLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008011 }
8012 if (w.mIsImWindow) {
Craig Mautneracafd192012-05-10 10:41:02 -07008013 winAnimator.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008014 } else if (w.mIsWallpaper) {
Craig Mautneracafd192012-05-10 10:41:02 -07008015 winAnimator.mAnimLayer += mWallpaperAnimLayerAdjustment;
8016 }
8017 if (winAnimator.mAnimLayer != oldLayer) {
8018 layerChanged = true;
Svetoslav Ganov55468c62012-10-15 15:09:02 -07008019 anyLayerChanged = true;
Craig Mautneracafd192012-05-10 10:41:02 -07008020 }
Craig Mautner05d29032013-05-03 13:40:13 -07008021 if (layerChanged && w.getStack().isDimming(winAnimator)) {
8022 // Force an animation pass just to update the mDimLayer layer.
Craig Mautner96868332012-12-04 14:29:11 -08008023 scheduleAnimationLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008024 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008025 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
Craig Mautner8863cca2012-09-18 15:04:34 -07008026 + "mBase=" + w.mBaseLayer
8027 + " mLayer=" + w.mLayer
Craig Mautnerf7666462013-04-28 08:58:21 -07008028 + (wtoken == null ?
8029 "" : " mAppLayer=" + wtoken.mAppAnimator.animLayerAdjustment)
Craig Mautner8863cca2012-09-18 15:04:34 -07008030 + " =mAnimLayer=" + winAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008031 //System.out.println(
8032 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
8033 }
Svetoslav Ganov55468c62012-10-15 15:09:02 -07008034
Svetoslav Ganov545252f2012-12-10 18:29:24 -08008035 //TODO (multidisplay): Magnification is supported only for the default display.
8036 if (mDisplayMagnifier != null && anyLayerChanged
8037 && windows.get(windows.size() - 1).getDisplayId() == Display.DEFAULT_DISPLAY) {
8038 mDisplayMagnifier.onWindowLayersChangedLocked();
Svetoslav Ganov55468c62012-10-15 15:09:02 -07008039 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008040 }
8041
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008042 private final void performLayoutAndPlaceSurfacesLocked() {
Dianne Hackborn7ad44382012-10-18 17:46:00 -07008043 int loopCount = 6;
Craig Mautnera13a41d2012-10-16 12:53:13 -07008044 do {
8045 mTraversalScheduled = false;
8046 performLayoutAndPlaceSurfacesLockedLoop();
8047 mH.removeMessages(H.DO_TRAVERSAL);
Dianne Hackborn7ad44382012-10-18 17:46:00 -07008048 loopCount--;
8049 } while (mTraversalScheduled && loopCount > 0);
Craig Mautner96868332012-12-04 14:29:11 -08008050 mInnerFields.mWallpaperActionPending = false;
Craig Mautnera13a41d2012-10-16 12:53:13 -07008051 }
8052
8053 private boolean mInLayout = false;
8054 private final void performLayoutAndPlaceSurfacesLockedLoop() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008055 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07008056 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008057 throw new RuntimeException("Recursive call!");
8058 }
Craig Mautneref25d7a2012-05-15 23:01:47 -07008059 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
8060 + Debug.getCallers(3));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008061 return;
8062 }
8063
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008064 if (mWaitingForConfig) {
8065 // Our configuration has changed (most likely rotation), but we
8066 // don't yet have the complete configuration to report to
8067 // applications. Don't do any window layout until we have it.
8068 return;
8069 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08008070
Jeff Browne215f262012-09-10 16:01:14 -07008071 if (!mDisplayReady) {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008072 // Not yet initialized, nothing to do.
8073 return;
8074 }
8075
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07008076 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008077 mInLayout = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008078 boolean recoveringMemory = false;
Craig Mautner6cfa7292013-01-15 09:05:42 -08008079
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008080 try {
8081 if (mForceRemoves != null) {
8082 recoveringMemory = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008083 // Wait a little bit for things to settle down, and off we go.
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008084 for (int i=0; i<mForceRemoves.size(); i++) {
8085 WindowState ws = mForceRemoves.get(i);
8086 Slog.i(TAG, "Force removing: " + ws);
8087 removeWindowInnerLocked(ws.mSession, ws);
8088 }
8089 mForceRemoves = null;
8090 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
8091 Object tmp = new Object();
8092 synchronized (tmp) {
8093 try {
8094 tmp.wait(250);
8095 } catch (InterruptedException e) {
8096 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008097 }
8098 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008099 } catch (RuntimeException e) {
Dianne Hackborn89620282011-09-11 12:47:45 -07008100 Log.wtf(TAG, "Unhandled exception while force removing for memory", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008101 }
Craig Mautner59c00972012-07-30 12:10:24 -07008102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008103 try {
Craig Mautner76a71652012-09-03 23:23:58 -07008104 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Craig Mautnerbb1449b2012-03-23 16:11:14 -07008105
Craig Mautner59c00972012-07-30 12:10:24 -07008106 mInLayout = false;
8107
Craig Mautner19d59bc2012-09-04 11:15:56 -07008108 if (needsLayout()) {
Craig Mautnerbb1449b2012-03-23 16:11:14 -07008109 if (++mLayoutRepeatCount < 6) {
8110 requestTraversalLocked();
8111 } else {
8112 Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
8113 mLayoutRepeatCount = 0;
8114 }
8115 } else {
8116 mLayoutRepeatCount = 0;
8117 }
Craig Mautnerbb1449b2012-03-23 16:11:14 -07008118
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008119 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008120 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
You Kimcb6291c2012-12-04 23:22:28 +09008121 mH.sendEmptyMessage(H.REPORT_WINDOWS_CHANGE);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008122 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008123 } catch (RuntimeException e) {
8124 mInLayout = false;
Dianne Hackborn89620282011-09-11 12:47:45 -07008125 Log.wtf(TAG, "Unhandled exception while laying out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008126 }
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07008127
8128 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008129 }
8130
Craig Mautner59c00972012-07-30 12:10:24 -07008131 private final void performLayoutLockedInner(final DisplayContent displayContent,
8132 boolean initial, boolean updateInputWindows) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07008133 if (!displayContent.layoutNeeded) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008134 return;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008135 }
Craig Mautner19d59bc2012-09-04 11:15:56 -07008136 displayContent.layoutNeeded = false;
Craig Mautner59c00972012-07-30 12:10:24 -07008137 WindowList windows = displayContent.getWindowList();
Craig Mautner69b08182012-09-05 13:07:13 -07008138 boolean isDefaultDisplay = displayContent.isDefaultDisplay;
Craig Mautner59c00972012-07-30 12:10:24 -07008139
8140 DisplayInfo displayInfo = displayContent.getDisplayInfo();
8141 final int dw = displayInfo.logicalWidth;
8142 final int dh = displayInfo.logicalHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008143
Dianne Hackborndf89e652011-10-06 22:35:11 -07008144 final int NFW = mFakeWindows.size();
8145 for (int i=0; i<NFW; i++) {
8146 mFakeWindows.get(i).layout(dw, dh);
8147 }
8148
Craig Mautner59c00972012-07-30 12:10:24 -07008149 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008150 int i;
8151
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008152 if (DEBUG_LAYOUT) {
8153 Slog.v(TAG, "-------------------------------------");
8154 Slog.v(TAG, "performLayout: needed="
Craig Mautner19d59bc2012-09-04 11:15:56 -07008155 + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008156 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008157
8158 WindowStateAnimator universeBackground = null;
8159
Craig Mautner69b08182012-09-05 13:07:13 -07008160 mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mRotation);
8161 if (isDefaultDisplay) {
8162 // Not needed on non-default displays.
8163 mSystemDecorLayer = mPolicy.getSystemDecorRectLw(mSystemDecorRect);
8164 mScreenRect.set(0, 0, dw, dh);
8165 }
Romain Guy06882f82009-06-10 13:36:04 -07008166
Craig Mautner967212c2013-04-13 21:10:58 -07008167 Rect contentRect = new Rect();
8168 mPolicy.getContentRectLw(contentRect);
8169 displayContent.setStackBoxSize(contentRect);
8170
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008171 int seq = mLayoutSeq+1;
8172 if (seq < 0) seq = 0;
8173 mLayoutSeq = seq;
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008174
8175 boolean behindDream = false;
8176
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008177 // First perform layout of any root windows (not attached
8178 // to another window).
8179 int topAttached = -1;
8180 for (i = N-1; i >= 0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07008181 final WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008182
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008183 // Don't do layout of a window if it is not visible, or
8184 // soon won't be visible, to avoid wasting time and funky
8185 // changes while a window is animating away.
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008186 final boolean gone = (behindDream && mPolicy.canBeForceHidden(win, win.mAttrs))
Craig Mautnerae446592012-12-06 19:05:05 -08008187 || win.isGoneForLayoutLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008188
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008189 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008190 Slog.v(TAG, "1ST PASS " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008191 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
Craig Mautner812d2ca2012-09-27 15:35:34 -07008192 + " mLayoutAttached=" + win.mLayoutAttached
Craig Mautnera3f4bf52012-10-10 20:37:48 -07008193 + " screen changed=" + win.isConfigChanged());
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008194 final AppWindowToken atoken = win.mAppToken;
8195 if (gone) Slog.v(TAG, " GONE: mViewVisibility="
8196 + win.mViewVisibility + " mRelayoutCalled="
8197 + win.mRelayoutCalled + " hidden="
8198 + win.mRootToken.hidden + " hiddenRequested="
8199 + (atoken != null && atoken.hiddenRequested)
8200 + " mAttachedHidden=" + win.mAttachedHidden);
8201 else Slog.v(TAG, " VIS: mViewVisibility="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008202 + win.mViewVisibility + " mRelayoutCalled="
8203 + win.mRelayoutCalled + " hidden="
8204 + win.mRootToken.hidden + " hiddenRequested="
8205 + (atoken != null && atoken.hiddenRequested)
8206 + " mAttachedHidden=" + win.mAttachedHidden);
8207 }
Craig Mautner69b08182012-09-05 13:07:13 -07008208
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008209 // If this view is GONE, then skip it -- keep the current
8210 // frame, and let the caller know so they can ignore it
8211 // if they want. (We do the normal layout for INVISIBLE
8212 // windows, since that means "perform layout as normal,
8213 // just don't display").
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008214 if (!gone || !win.mHaveFrame || win.mLayoutNeeded
Craig Mautnerf02296f2012-11-06 14:33:46 -08008215 || (win.mAttrs.type == TYPE_KEYGUARD && win.isConfigChanged())
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008216 || win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008217 if (!win.mLayoutAttached) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008218 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08008219 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008220 win.mContentChanged = false;
8221 }
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008222 if (win.mAttrs.type == TYPE_DREAM) {
8223 // Don't layout windows behind a dream, so that if it
8224 // does stuff like hide the status bar we won't get a
8225 // bad transition when it goes away.
8226 behindDream = true;
8227 }
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008228 win.mLayoutNeeded = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008229 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008230 mPolicy.layoutWindowLw(win, win.mAttrs, null);
8231 win.mLayoutSeq = seq;
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008232 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008233 + win.mFrame + " mContainingFrame="
8234 + win.mContainingFrame + " mDisplayFrame="
8235 + win.mDisplayFrame);
8236 } else {
8237 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008238 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07008239 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008240 if (win.mViewVisibility == View.VISIBLE
8241 && win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND
8242 && universeBackground == null) {
8243 universeBackground = win.mWinAnimator;
8244 }
8245 }
8246
8247 if (mAnimator.mUniverseBackground != universeBackground) {
8248 mFocusMayChange = true;
8249 mAnimator.mUniverseBackground = universeBackground;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008250 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008251
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008252 boolean attachedBehindDream = false;
8253
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008254 // Now perform layout of attached windows, which usually
8255 // depend on the position of the window they are attached to.
8256 // XXX does not deal with windows that are attached to windows
8257 // that are themselves attached.
8258 for (i = topAttached; i >= 0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07008259 final WindowState win = windows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008260
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008261 if (win.mLayoutAttached) {
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008262 if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008263 + " mHaveFrame=" + win.mHaveFrame
8264 + " mViewVisibility=" + win.mViewVisibility
8265 + " mRelayoutCalled=" + win.mRelayoutCalled);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008266 // If this view is GONE, then skip it -- keep the current
8267 // frame, and let the caller know so they can ignore it
8268 // if they want. (We do the normal layout for INVISIBLE
8269 // windows, since that means "perform layout as normal,
8270 // just don't display").
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008271 if (attachedBehindDream && mPolicy.canBeForceHidden(win, win.mAttrs)) {
8272 continue;
8273 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008274 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008275 || !win.mHaveFrame || win.mLayoutNeeded) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008276 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08008277 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008278 win.mContentChanged = false;
8279 }
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008280 win.mLayoutNeeded = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008281 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008282 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
8283 win.mLayoutSeq = seq;
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008284 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008285 + win.mFrame + " mContainingFrame="
8286 + win.mContainingFrame + " mDisplayFrame="
8287 + win.mDisplayFrame);
8288 }
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008289 } else if (win.mAttrs.type == TYPE_DREAM) {
8290 // Don't layout windows behind a dream, so that if it
8291 // does stuff like hide the status bar we won't get a
8292 // bad transition when it goes away.
8293 attachedBehindDream = behindDream;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008294 }
8295 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08008296
Jeff Brown349703e2010-06-22 01:27:15 -07008297 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown3a22cd92011-01-21 13:59:04 -08008298 mInputMonitor.setUpdateInputWindowsNeededLw();
8299 if (updateInputWindows) {
Jeff Brown2e44b072011-01-24 15:21:56 -08008300 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08008301 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008302
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008303 mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008304 }
Romain Guy06882f82009-06-10 13:36:04 -07008305
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008306 void makeWindowFreezingScreenIfNeededLocked(WindowState w) {
8307 // If the screen is currently frozen or off, then keep
8308 // it frozen/off until this window draws at its new
8309 // orientation.
Craig Mautner2fb98b12012-03-20 17:24:00 -07008310 if (!okToDisplay()) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008311 if (DEBUG_ORIENTATION) Slog.v(TAG,
8312 "Changing surface while display frozen: " + w);
8313 w.mOrientationChanging = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -07008314 w.mLastFreezeDuration = 0;
Craig Mautner3255a282012-04-16 15:42:47 -07008315 mInnerFields.mOrientationChangeComplete = false;
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008316 if (!mWindowsFreezingScreen) {
8317 mWindowsFreezingScreen = true;
8318 // XXX should probably keep timeout from
8319 // when we first froze the display.
8320 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
Craig Mautner6cfa7292013-01-15 09:05:42 -08008321 mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT,
You Kimcb6291c2012-12-04 23:22:28 +09008322 WINDOW_FREEZE_TIMEOUT_DURATION);
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008323 }
8324 }
8325 }
8326
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008327 /**
8328 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
Craig Mautner19d59bc2012-09-04 11:15:56 -07008329 * @param windows List of windows on default display.
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008330 * @return bitmap indicating if another pass through layout must be made.
8331 */
Craig Mautner59c00972012-07-30 12:10:24 -07008332 public int handleAppTransitionReadyLocked(WindowList windows) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008333 int changes = 0;
8334 int i;
8335 int NN = mOpeningApps.size();
8336 boolean goodToGo = true;
8337 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8338 "Checking " + NN + " opening apps (frozen="
8339 + mDisplayFrozen + " timeout="
Craig Mautner164d4bb2012-11-26 13:51:23 -08008340 + mAppTransition.isTimeout() + ")...");
8341 if (!mDisplayFrozen && !mAppTransition.isTimeout()) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008342 // If the display isn't frozen, wait to do anything until
8343 // all of the apps are ready. Otherwise just go because
8344 // we'll unfreeze the display when everyone is ready.
8345 for (i=0; i<NN && goodToGo; i++) {
8346 AppWindowToken wtoken = mOpeningApps.get(i);
8347 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Craig Mautner1d961d42012-05-27 12:02:11 -07008348 "Check opening app=" + wtoken + ": allDrawn="
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008349 + wtoken.allDrawn + " startingDisplayed="
Craig Mautner7358fbf2012-04-12 21:06:33 -07008350 + wtoken.startingDisplayed + " startingMoved="
8351 + wtoken.startingMoved);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008352 if (!wtoken.allDrawn && !wtoken.startingDisplayed
8353 && !wtoken.startingMoved) {
8354 goodToGo = false;
8355 }
8356 }
8357 }
8358 if (goodToGo) {
8359 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
Craig Mautner164d4bb2012-11-26 13:51:23 -08008360 int transit = mAppTransition.getAppTransition();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008361 if (mSkipAppTransitionAnimation) {
Craig Mautner4b71aa12012-12-27 17:20:01 -08008362 transit = AppTransition.TRANSIT_UNSET;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008363 }
Craig Mautner164d4bb2012-11-26 13:51:23 -08008364 mAppTransition.goodToGo();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008365 mStartingIconInTransition = false;
8366 mSkipAppTransitionAnimation = false;
8367
8368 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
8369
Craig Mautneref25d7a2012-05-15 23:01:47 -07008370 rebuildAppWindowListLocked();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008371
Craig Mautner0afddcb2012-05-08 15:38:00 -07008372 // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
Craig Mautner83339b42012-05-01 22:13:23 -07008373 WindowState oldWallpaper =
8374 mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
Craig Mautner0afddcb2012-05-08 15:38:00 -07008375 && !mWallpaperTarget.mWinAnimator.isDummyAnimation()
Craig Mautner83339b42012-05-01 22:13:23 -07008376 ? null : mWallpaperTarget;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008377
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008378 mInnerFields.mWallpaperMayChange = false;
8379
8380 // The top-most window will supply the layout params,
8381 // and we will determine it below.
8382 LayoutParams animLp = null;
8383 int bestAnimLayer = -1;
8384 boolean fullscreenAnim = false;
8385
8386 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8387 "New wallpaper target=" + mWallpaperTarget
Daniel Sandlerab886f52012-06-04 14:36:25 -04008388 + ", oldWallpaper=" + oldWallpaper
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008389 + ", lower target=" + mLowerWallpaperTarget
8390 + ", upper target=" + mUpperWallpaperTarget);
Craig Mautnerae446592012-12-06 19:05:05 -08008391
8392 boolean openingAppHasWallpaper = false;
8393 boolean closingAppHasWallpaper = false;
8394 final AppWindowToken lowerWallpaperAppToken;
8395 final AppWindowToken upperWallpaperAppToken;
8396 if (mLowerWallpaperTarget == null) {
8397 lowerWallpaperAppToken = upperWallpaperAppToken = null;
8398 } else {
8399 lowerWallpaperAppToken = mLowerWallpaperTarget.mAppToken;
8400 upperWallpaperAppToken = mUpperWallpaperTarget.mAppToken;
8401 }
8402
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008403 // Do a first pass through the tokens for two
8404 // things:
8405 // (1) Determine if both the closing and opening
8406 // app token sets are wallpaper targets, in which
8407 // case special animations are needed
8408 // (since the wallpaper needs to stay static
8409 // behind them).
8410 // (2) Find the layout params of the top-most
8411 // application window in the tokens, which is
8412 // what will control the animation theme.
8413 final int NC = mClosingApps.size();
8414 NN = NC + mOpeningApps.size();
8415 for (i=0; i<NN; i++) {
Craig Mautnerae446592012-12-06 19:05:05 -08008416 final AppWindowToken wtoken;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008417 if (i < NC) {
8418 wtoken = mClosingApps.get(i);
Craig Mautnerae446592012-12-06 19:05:05 -08008419 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
8420 closingAppHasWallpaper = true;
8421 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008422 } else {
Craig Mautnerae446592012-12-06 19:05:05 -08008423 wtoken = mOpeningApps.get(i - NC);
8424 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
8425 openingAppHasWallpaper = true;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008426 }
8427 }
Craig Mautnerae446592012-12-06 19:05:05 -08008428
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008429 if (wtoken.appFullscreen) {
8430 WindowState ws = wtoken.findMainWindow();
8431 if (ws != null) {
8432 animLp = ws.mAttrs;
8433 bestAnimLayer = ws.mLayer;
8434 fullscreenAnim = true;
8435 }
8436 } else if (!fullscreenAnim) {
8437 WindowState ws = wtoken.findMainWindow();
8438 if (ws != null) {
8439 if (ws.mLayer > bestAnimLayer) {
8440 animLp = ws.mAttrs;
8441 bestAnimLayer = ws.mLayer;
8442 }
8443 }
8444 }
8445 }
8446
Craig Mautnerae446592012-12-06 19:05:05 -08008447 if (closingAppHasWallpaper && openingAppHasWallpaper) {
8448 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Wallpaper animation!");
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008449 switch (transit) {
Craig Mautner4b71aa12012-12-27 17:20:01 -08008450 case AppTransition.TRANSIT_ACTIVITY_OPEN:
8451 case AppTransition.TRANSIT_TASK_OPEN:
8452 case AppTransition.TRANSIT_TASK_TO_FRONT:
8453 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008454 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08008455 case AppTransition.TRANSIT_ACTIVITY_CLOSE:
8456 case AppTransition.TRANSIT_TASK_CLOSE:
8457 case AppTransition.TRANSIT_TASK_TO_BACK:
8458 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008459 break;
8460 }
Craig Mautnerae446592012-12-06 19:05:05 -08008461 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "New transit: " + transit);
Daniel Sandlerab886f52012-06-04 14:36:25 -04008462 } else if ((oldWallpaper != null) && !mOpeningApps.contains(oldWallpaper.mAppToken)) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008463 // We are transitioning from an activity with
8464 // a wallpaper to one without.
Craig Mautner4b71aa12012-12-27 17:20:01 -08008465 transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008466 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8467 "New transit away from wallpaper: " + transit);
Craig Mautner8863cca2012-09-18 15:04:34 -07008468 } else if (mWallpaperTarget != null && mWallpaperTarget.isVisibleLw()) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008469 // We are transitioning from an activity without
8470 // a wallpaper to now showing the wallpaper
Craig Mautner4b71aa12012-12-27 17:20:01 -08008471 transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008472 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8473 "New transit into wallpaper: " + transit);
8474 }
8475
8476 // If all closing windows are obscured, then there is
8477 // no need to do an animation. This is the case, for
8478 // example, when this transition is being done behind
8479 // the lock screen.
8480 if (!mPolicy.allowAppAnimationsLw()) {
8481 animLp = null;
8482 }
8483
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008484 AppWindowToken topOpeningApp = null;
8485 int topOpeningLayer = 0;
8486
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008487 NN = mOpeningApps.size();
8488 for (i=0; i<NN; i++) {
8489 AppWindowToken wtoken = mOpeningApps.get(i);
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008490 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Craig Mautnerbec53f72012-04-05 11:49:05 -07008491 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008492 appAnimator.clearThumbnail();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008493 wtoken.inPendingTransaction = false;
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008494 appAnimator.animation = null;
Craig Mautnerbec53f72012-04-05 11:49:05 -07008495 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008496 wtoken.updateReportedVisibilityLocked();
8497 wtoken.waitingToShow = false;
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008498
8499 appAnimator.mAllAppWinAnimators.clear();
8500 final int N = wtoken.allAppWindows.size();
8501 for (int j = 0; j < N; j++) {
8502 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
8503 }
8504 mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
8505
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008506 if (animLp != null) {
8507 int layer = -1;
8508 for (int j=0; j<wtoken.windows.size(); j++) {
8509 WindowState win = wtoken.windows.get(j);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07008510 if (win.mWinAnimator.mAnimLayer > layer) {
8511 layer = win.mWinAnimator.mAnimLayer;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008512 }
8513 }
8514 if (topOpeningApp == null || layer > topOpeningLayer) {
8515 topOpeningApp = wtoken;
8516 topOpeningLayer = layer;
8517 }
8518 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008519 }
8520 NN = mClosingApps.size();
8521 for (i=0; i<NN; i++) {
8522 AppWindowToken wtoken = mClosingApps.get(i);
8523 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Craig Mautner8863cca2012-09-18 15:04:34 -07008524 "Now closing app " + wtoken);
Craig Mautner59431632012-04-04 11:56:44 -07008525 wtoken.mAppAnimator.clearThumbnail();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008526 wtoken.inPendingTransaction = false;
Craig Mautner59431632012-04-04 11:56:44 -07008527 wtoken.mAppAnimator.animation = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008528 setTokenVisibilityLocked(wtoken, animLp, false,
8529 transit, false);
8530 wtoken.updateReportedVisibilityLocked();
8531 wtoken.waitingToHide = false;
8532 // Force the allDrawn flag, because we want to start
8533 // this guy's animations regardless of whether it's
8534 // gotten drawn.
8535 wtoken.allDrawn = true;
Craig Mautner7636dfb2012-11-16 15:24:11 -08008536 wtoken.deferClearAllDrawn = false;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008537 }
8538
Craig Mautner164d4bb2012-11-26 13:51:23 -08008539 AppWindowAnimator appAnimator =
8540 topOpeningApp == null ? null : topOpeningApp.mAppAnimator;
8541 Bitmap nextAppTransitionThumbnail = mAppTransition.getNextAppTransitionThumbnail();
8542 if (nextAppTransitionThumbnail != null && appAnimator != null
8543 && appAnimator.animation != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008544 // This thumbnail animation is very special, we need to have
8545 // an extra surface with the thumbnail included with the animation.
Craig Mautner164d4bb2012-11-26 13:51:23 -08008546 Rect dirty = new Rect(0, 0, nextAppTransitionThumbnail.getWidth(),
8547 nextAppTransitionThumbnail.getHeight());
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008548 try {
Jeff Browne215f262012-09-10 16:01:14 -07008549 // TODO(multi-display): support other displays
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008550 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07008551 final Display display = displayContent.getDisplay();
Mathias Agopian29479eb2013-02-14 14:36:04 -08008552 SurfaceControl surfaceControl = new SurfaceControl(mFxSession,
Jeff Brown64a55af2012-08-26 02:47:39 -07008553 "thumbnail anim",
Craig Mautner6881a102012-07-27 13:04:51 -07008554 dirty.width(), dirty.height(),
Mathias Agopian3866f0d2013-02-11 22:08:48 -08008555 PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
Mathias Agopian29479eb2013-02-14 14:36:04 -08008556 surfaceControl.setLayerStack(display.getLayerStack());
8557 appAnimator.thumbnail = surfaceControl;
8558 if (SHOW_TRANSACTIONS) Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008559 Surface drawSurface = new Surface();
Mathias Agopian29479eb2013-02-14 14:36:04 -08008560 drawSurface.copyFrom(surfaceControl);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008561 Canvas c = drawSurface.lockCanvas(dirty);
Craig Mautner164d4bb2012-11-26 13:51:23 -08008562 c.drawBitmap(nextAppTransitionThumbnail, 0, 0, null);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008563 drawSurface.unlockCanvasAndPost(c);
8564 drawSurface.release();
Craig Mautner164d4bb2012-11-26 13:51:23 -08008565 appAnimator.thumbnailLayer = topOpeningLayer;
8566 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
8567 Animation anim = mAppTransition.createThumbnailAnimationLocked(
8568 transit, true, true, displayInfo.appWidth, displayInfo.appHeight);
8569 appAnimator.thumbnailAnimation = anim;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008570 anim.restrictDuration(MAX_ANIMATION_DURATION);
8571 anim.scaleCurrentDuration(mTransitionAnimationScale);
Craig Mautner164d4bb2012-11-26 13:51:23 -08008572 Point p = new Point();
8573 mAppTransition.getStartingPoint(p);
8574 appAnimator.thumbnailX = p.x;
8575 appAnimator.thumbnailY = p.y;
Mathias Agopian3866f0d2013-02-11 22:08:48 -08008576 } catch (SurfaceControl.OutOfResourcesException e) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008577 Slog.e(TAG, "Can't allocate thumbnail surface w=" + dirty.width()
8578 + " h=" + dirty.height(), e);
Craig Mautner164d4bb2012-11-26 13:51:23 -08008579 appAnimator.clearThumbnail();
Mathias Agopian3866f0d2013-02-11 22:08:48 -08008580 } catch (Surface.OutOfResourcesException e) {
8581 Slog.e(TAG, "Can't allocate Canvas surface w=" + dirty.width()
8582 + " h=" + dirty.height(), e);
8583 appAnimator.clearThumbnail();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008584 }
8585 }
8586
Craig Mautner164d4bb2012-11-26 13:51:23 -08008587 mAppTransition.postAnimationCallback();
8588 mAppTransition.clear();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008589
8590 mOpeningApps.clear();
8591 mClosingApps.clear();
8592
8593 // This has changed the visibility of windows, so perform
8594 // a new layout to get them all up-to-date.
Craig Mautner39834192012-09-02 07:47:24 -07008595 changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008596 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008597 getDefaultDisplayContentLocked().layoutNeeded = true;
Craig Mautner59c00972012-07-30 12:10:24 -07008598
8599 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008600 if (windows == getDefaultWindowListLocked()
8601 && !moveInputMethodWindowsIfNeededLocked(true)) {
Craig Mautner59c00972012-07-30 12:10:24 -07008602 assignLayersLocked(windows);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008603 }
Craig Mautner59c00972012-07-30 12:10:24 -07008604 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, false /*updateInputWindows*/);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008605 mFocusMayChange = false;
8606 }
8607
8608 return changes;
8609 }
8610
8611 /**
8612 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008613 * @return bitmap indicating if another pass through layout must be made.
8614 */
Craig Mautner2f995a72012-02-21 09:53:21 -08008615 private int handleAnimatingStoppedAndTransitionLocked() {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008616 int changes = 0;
8617
Craig Mautner9a29a5d2012-12-27 19:03:40 -08008618 mAppTransition.setIdle();
Craig Mautneref25d7a2012-05-15 23:01:47 -07008619 // Restore window app tokens to the ActivityManager views
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08008620 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautnerd9a22882013-03-16 15:00:36 -07008621 final ArrayList<Task> tasks = displayContent.getTasks();
Craig Mautnerf81b90872013-02-26 13:02:43 -08008622 final int numTasks = tasks.size();
8623 for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
8624 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
8625 final int numTokens = tokens.size();
8626 for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
8627 final AppWindowToken wtoken = tokens.get(tokenNdx);
8628 wtoken.sendingToBottom = false;
8629 }
Craig Mautner3f99fde2012-06-19 14:10:01 -07008630 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008631 rebuildAppWindowListLocked();
Craig Mautneref25d7a2012-05-15 23:01:47 -07008632
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008633 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Craig Mautnerae446592012-12-06 19:05:05 -08008634 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
8635 "Wallpaper layer changed: assigning layers + relayout");
Craig Mautneref25d7a2012-05-15 23:01:47 -07008636 moveInputMethodWindowsIfNeededLocked(true);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008637 mInnerFields.mWallpaperMayChange = true;
8638 // Since the window list has been rebuilt, focus might
8639 // have to be recomputed since the actual order of windows
8640 // might have changed again.
8641 mFocusMayChange = true;
8642
8643 return changes;
8644 }
8645
Craig Mautnere32c3072012-03-12 15:25:35 -07008646 private void updateResizingWindows(final WindowState w) {
Craig Mautnera608b882012-03-30 13:03:49 -07008647 final WindowStateAnimator winAnimator = w.mWinAnimator;
Craig Mautnerade0a9a2012-10-06 13:55:07 -07008648 if (w.mHasSurface && w.mLayoutSeq == mLayoutSeq) {
Dianne Hackbornc4aad012013-02-22 15:05:25 -08008649 w.mOverscanInsetsChanged |=
8650 !w.mLastOverscanInsets.equals(w.mOverscanInsets);
Craig Mautnere32c3072012-03-12 15:25:35 -07008651 w.mContentInsetsChanged |=
Dianne Hackborn5c58de32012-04-28 19:52:37 -07008652 !w.mLastContentInsets.equals(w.mContentInsets);
Craig Mautnere32c3072012-03-12 15:25:35 -07008653 w.mVisibleInsetsChanged |=
Dianne Hackborn5c58de32012-04-28 19:52:37 -07008654 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Craig Mautner812d2ca2012-09-27 15:35:34 -07008655 boolean configChanged = w.isConfigChanged();
Craig Mautnere32c3072012-03-12 15:25:35 -07008656 if (DEBUG_CONFIGURATION && configChanged) {
8657 Slog.v(TAG, "Win " + w + " config changed: "
8658 + mCurConfiguration);
8659 }
8660 if (localLOGV) Slog.v(TAG, "Resizing " + w
8661 + ": configChanged=" + configChanged
8662 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
8663 w.mLastFrame.set(w.mFrame);
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07008664 if (w.mContentInsetsChanged
Craig Mautnere32c3072012-03-12 15:25:35 -07008665 || w.mVisibleInsetsChanged
Craig Mautnera608b882012-03-30 13:03:49 -07008666 || winAnimator.mSurfaceResized
Craig Mautnere32c3072012-03-12 15:25:35 -07008667 || configChanged) {
8668 if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
Craig Mautnerc5a6e442013-06-05 17:22:35 -07008669 Slog.v(TAG, "Resize reasons for w=" + w + ": "
Craig Mautnere32c3072012-03-12 15:25:35 -07008670 + " contentInsetsChanged=" + w.mContentInsetsChanged
Craig Mautnerae446592012-12-06 19:05:05 -08008671 + " " + w.mContentInsets.toShortString()
Craig Mautnere32c3072012-03-12 15:25:35 -07008672 + " visibleInsetsChanged=" + w.mVisibleInsetsChanged
Craig Mautnerae446592012-12-06 19:05:05 -08008673 + " " + w.mVisibleInsets.toShortString()
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008674 + " surfaceResized=" + winAnimator.mSurfaceResized
Craig Mautnere32c3072012-03-12 15:25:35 -07008675 + " configChanged=" + configChanged);
8676 }
8677
Dianne Hackbornc4aad012013-02-22 15:05:25 -08008678 w.mLastOverscanInsets.set(w.mOverscanInsets);
Craig Mautnere32c3072012-03-12 15:25:35 -07008679 w.mLastContentInsets.set(w.mContentInsets);
8680 w.mLastVisibleInsets.set(w.mVisibleInsets);
8681 makeWindowFreezingScreenIfNeededLocked(w);
8682 // If the orientation is changing, then we need to
8683 // hold off on unfreezing the display until this
8684 // window has been redrawn; to do that, we need
8685 // to go through the process of getting informed
8686 // by the application when it has finished drawing.
8687 if (w.mOrientationChanging) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07008688 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautner83339b42012-05-01 22:13:23 -07008689 "Orientation start waiting for draw mDrawState=DRAW_PENDING in "
Mathias Agopian29479eb2013-02-14 14:36:04 -08008690 + w + ", surface " + winAnimator.mSurfaceControl);
Craig Mautner749a7bb2012-04-02 13:49:53 -07008691 winAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
Craig Mautnere32c3072012-03-12 15:25:35 -07008692 if (w.mAppToken != null) {
8693 w.mAppToken.allDrawn = false;
Craig Mautner7636dfb2012-11-16 15:24:11 -08008694 w.mAppToken.deferClearAllDrawn = false;
Craig Mautnere32c3072012-03-12 15:25:35 -07008695 }
8696 }
8697 if (!mResizingWindows.contains(w)) {
8698 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008699 "Resizing window " + w + " to " + winAnimator.mSurfaceW
8700 + "x" + winAnimator.mSurfaceH);
Craig Mautnere32c3072012-03-12 15:25:35 -07008701 mResizingWindows.add(w);
8702 }
8703 } else if (w.mOrientationChanging) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07008704 if (w.isDrawnLw()) {
Craig Mautnere32c3072012-03-12 15:25:35 -07008705 if (DEBUG_ORIENTATION) Slog.v(TAG,
8706 "Orientation not waiting for draw in "
Mathias Agopian29479eb2013-02-14 14:36:04 -08008707 + w + ", surface " + winAnimator.mSurfaceControl);
Craig Mautnere32c3072012-03-12 15:25:35 -07008708 w.mOrientationChanging = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07008709 w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
8710 - mDisplayFreezeTime);
Craig Mautnere32c3072012-03-12 15:25:35 -07008711 }
8712 }
8713 }
8714 }
8715
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008716 /**
8717 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
8718 *
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008719 * @param w WindowState this method is applied to.
8720 * @param currentTime The time which animations use for calculating transitions.
8721 * @param innerDw Width of app window.
8722 * @param innerDh Height of app window.
8723 */
8724 private void handleNotObscuredLocked(final WindowState w, final long currentTime,
8725 final int innerDw, final int innerDh) {
8726 final WindowManager.LayoutParams attrs = w.mAttrs;
8727 final int attrFlags = attrs.flags;
8728 final boolean canBeSeen = w.isDisplayedLw();
8729
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07008730 if (w.mHasSurface) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008731 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
8732 mInnerFields.mHoldScreen = w.mSession;
8733 }
8734 if (!mInnerFields.mSyswin && w.mAttrs.screenBrightness >= 0
8735 && mInnerFields.mScreenBrightness < 0) {
8736 mInnerFields.mScreenBrightness = w.mAttrs.screenBrightness;
8737 }
8738 if (!mInnerFields.mSyswin && w.mAttrs.buttonBrightness >= 0
8739 && mInnerFields.mButtonBrightness < 0) {
8740 mInnerFields.mButtonBrightness = w.mAttrs.buttonBrightness;
8741 }
Jeff Brown1e3b98d2012-09-30 18:58:59 -07008742 if (!mInnerFields.mSyswin && w.mAttrs.userActivityTimeout >= 0
8743 && mInnerFields.mUserActivityTimeout < 0) {
8744 mInnerFields.mUserActivityTimeout = w.mAttrs.userActivityTimeout;
8745 }
8746
Craig Mautner65d11b32012-10-01 13:59:52 -07008747 final int type = attrs.type;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008748 if (canBeSeen
Craig Mautner65d11b32012-10-01 13:59:52 -07008749 && (type == TYPE_SYSTEM_DIALOG
Craig Mautner88400d32012-09-30 12:35:45 -07008750 || type == TYPE_RECENTS_OVERLAY
Craig Mautner65d11b32012-10-01 13:59:52 -07008751 || type == TYPE_KEYGUARD
8752 || type == TYPE_SYSTEM_ERROR)) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008753 mInnerFields.mSyswin = true;
8754 }
Craig Mautner65d11b32012-10-01 13:59:52 -07008755
8756 if (canBeSeen) {
8757 if (type == TYPE_DREAM || type == TYPE_KEYGUARD) {
8758 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_MIRROR;
8759 } else if (mInnerFields.mDisplayHasContent
8760 == LayoutFields.DISPLAY_CONTENT_UNKNOWN) {
8761 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNIQUE;
8762 }
8763 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008764 }
8765
8766 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
8767 if (opaqueDrawn && w.isFullscreen(innerDw, innerDh)) {
8768 // This window completely covers everything behind it,
Craig Mautner2fb98b12012-03-20 17:24:00 -07008769 // so we want to leave all of them as undimmed (for
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008770 // performance reasons).
8771 mInnerFields.mObscured = true;
Craig Mautner312eac42012-11-13 10:56:22 -08008772 }
8773 }
8774
8775 private void handleFlagDimBehind(WindowState w, int innerDw, int innerDh) {
8776 final WindowManager.LayoutParams attrs = w.mAttrs;
8777 if ((attrs.flags & FLAG_DIM_BEHIND) != 0
8778 && w.isDisplayedLw()
Craig Mautner236a35b2012-06-08 09:54:59 -07008779 && !w.mExiting) {
Craig Mautner312eac42012-11-13 10:56:22 -08008780 final WindowStateAnimator winAnimator = w.mWinAnimator;
Craig Mautner05d29032013-05-03 13:40:13 -07008781 final TaskStack stack = w.getStack();
8782 stack.setDimmingTag();
8783 if (!stack.isDimming(winAnimator)) {
Craig Mautner312eac42012-11-13 10:56:22 -08008784 if (localLOGV) Slog.v(TAG, "Win " + w + " start dimming.");
Craig Mautner05d29032013-05-03 13:40:13 -07008785 stack.startDimmingIfNeeded(winAnimator);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008786 }
8787 }
8788 }
8789
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08008790 private void updateAllDrawnLocked(DisplayContent displayContent) {
Craig Mautner6fbda632012-07-03 09:26:39 -07008791 // See if any windows have been drawn, so they (and others
8792 // associated with them) can now be shown.
Craig Mautnerd9a22882013-03-16 15:00:36 -07008793 final ArrayList<Task> tasks = displayContent.getTasks();
Craig Mautnerf81b90872013-02-26 13:02:43 -08008794 final int numTasks = tasks.size();
8795 for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
8796 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
8797 final int numTokens = tokens.size();
8798 for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
8799 final AppWindowToken wtoken = tokens.get(tokenNdx);
8800 if (!wtoken.allDrawn) {
8801 int numInteresting = wtoken.numInterestingWindows;
8802 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Craig Mautner11462cc2013-05-13 15:56:18 -07008803 if (DEBUG_VISIBILITY) Slog.v(TAG,
Craig Mautnerf81b90872013-02-26 13:02:43 -08008804 "allDrawn: " + wtoken
8805 + " interesting=" + numInteresting
8806 + " drawn=" + wtoken.numDrawnWindows);
8807 wtoken.allDrawn = true;
Craig Mautner5eda9b32013-07-02 11:58:16 -07008808 mH.obtainMessage(H.NOTIFY_ACTIVITY_DRAWN, wtoken.token).sendToTarget();
Craig Mautnerf81b90872013-02-26 13:02:43 -08008809 }
Craig Mautner6fbda632012-07-03 09:26:39 -07008810 }
8811 }
8812 }
8813 }
8814
Brad Fitzpatrick68044332010-11-22 18:19:48 -08008815 // "Something has changed! Let's make it correct now."
Craig Mautner76a71652012-09-03 23:23:58 -07008816 private final void performLayoutAndPlaceSurfacesLockedInner(boolean recoveringMemory) {
Craig Mautner7d8df392012-04-06 15:26:23 -07008817 if (DEBUG_WINDOW_TRACE) {
Craig Mautner3255a282012-04-16 15:42:47 -07008818 Slog.v(TAG, "performLayoutAndPlaceSurfacesLockedInner: entry. Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -07008819 + Debug.getCallers(3));
Craig Mautner7d8df392012-04-06 15:26:23 -07008820 }
Joe Onorato34bcebc2010-07-07 18:05:01 -04008821
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008822 final long currentTime = SystemClock.uptimeMillis();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008823
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008824 int i;
8825
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008826 if (mFocusMayChange) {
8827 mFocusMayChange = false;
Jeff Brown3a22cd92011-01-21 13:59:04 -08008828 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
8829 false /*updateInputWindows*/);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008830 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008831
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008832 // Initialize state of exiting tokens.
Craig Mautnerf8924152013-07-16 09:10:55 -07008833 final int numDisplays = mDisplayContents.size();
8834 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
8835 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08008836 for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {
8837 displayContent.mExitingTokens.get(i).hasVisible = false;
8838 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008839
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08008840 // Initialize state of exiting applications.
8841 for (i=displayContent.mExitingAppTokens.size()-1; i>=0; i--) {
8842 displayContent.mExitingAppTokens.get(i).hasVisible = false;
8843 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008844 }
8845
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008846 mInnerFields.mHoldScreen = null;
8847 mInnerFields.mScreenBrightness = -1;
8848 mInnerFields.mButtonBrightness = -1;
Jeff Brown1e3b98d2012-09-30 18:58:59 -07008849 mInnerFields.mUserActivityTimeout = -1;
Craig Mautner65d11b32012-10-01 13:59:52 -07008850 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNKNOWN;
Jeff Brown1e3b98d2012-09-30 18:58:59 -07008851
Craig Mautner6fbda632012-07-03 09:26:39 -07008852 mTransactionSequence++;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07008853
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008854 final DisplayContent defaultDisplay = getDefaultDisplayContentLocked();
Craig Mautner76a71652012-09-03 23:23:58 -07008855 final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
8856 final int defaultDw = defaultInfo.logicalWidth;
8857 final int defaultDh = defaultInfo.logicalHeight;
Craig Mautner76a71652012-09-03 23:23:58 -07008858
Dianne Hackborn36991742011-10-11 21:35:26 -07008859 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
8860 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
Mathias Agopian3866f0d2013-02-11 22:08:48 -08008861 SurfaceControl.openTransaction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008862 try {
Craig Mautner76a71652012-09-03 23:23:58 -07008863
Jeff Brown4ed8fe72012-08-30 18:18:29 -07008864 if (mWatermark != null) {
Craig Mautner76a71652012-09-03 23:23:58 -07008865 mWatermark.positionSurface(defaultDw, defaultDh);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07008866 }
8867 if (mStrictModeFlash != null) {
Craig Mautner76a71652012-09-03 23:23:58 -07008868 mStrictModeFlash.positionSurface(defaultDw, defaultDh);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07008869 }
8870
Craig Mautner7358fbf2012-04-12 21:06:33 -07008871 boolean focusDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008872
Craig Mautnerf8924152013-07-16 09:10:55 -07008873 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
8874 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08008875 boolean updateAllDrawn = false;
Craig Mautner76a71652012-09-03 23:23:58 -07008876 WindowList windows = displayContent.getWindowList();
8877 DisplayInfo displayInfo = displayContent.getDisplayInfo();
Craig Mautner19d59bc2012-09-04 11:15:56 -07008878 final int displayId = displayContent.getDisplayId();
Craig Mautner76a71652012-09-03 23:23:58 -07008879 final int dw = displayInfo.logicalWidth;
8880 final int dh = displayInfo.logicalHeight;
8881 final int innerDw = displayInfo.appWidth;
8882 final int innerDh = displayInfo.appHeight;
Craig Mautner19d59bc2012-09-04 11:15:56 -07008883 final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008884
Craig Mautner65d11b32012-10-01 13:59:52 -07008885 // Reset for each display unless we are forcing mirroring.
8886 if (mInnerFields.mDisplayHasContent != LayoutFields.DISPLAY_CONTENT_MIRROR) {
8887 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNKNOWN;
8888 }
8889
Craig Mautner76a71652012-09-03 23:23:58 -07008890 int repeats = 0;
8891 do {
8892 repeats++;
8893 if (repeats > 6) {
8894 Slog.w(TAG, "Animation repeat aborted after too many iterations");
Craig Mautner76a71652012-09-03 23:23:58 -07008895 displayContent.layoutNeeded = false;
8896 break;
Craig Mautner5702d4d2012-06-30 14:10:16 -07008897 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008898
Craig Mautner76a71652012-09-03 23:23:58 -07008899 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("On entry to LockedInner",
8900 displayContent.pendingLayoutChanges);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008901
Craig Mautner0bf6ec92012-12-18 08:33:27 -08008902 if ((displayContent.pendingLayoutChanges &
8903 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
8904 (adjustWallpaperWindowsLocked() &
8905 ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Craig Mautner76a71652012-09-03 23:23:58 -07008906 assignLayersLocked(windows);
Craig Mautner76a71652012-09-03 23:23:58 -07008907 displayContent.layoutNeeded = true;
8908 }
8909
8910 if (isDefaultDisplay && (displayContent.pendingLayoutChanges
8911 & WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
8912 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
8913 if (updateOrientationFromAppTokensLocked(true)) {
Craig Mautner76a71652012-09-03 23:23:58 -07008914 displayContent.layoutNeeded = true;
8915 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008916 }
8917 }
8918
Craig Mautner76a71652012-09-03 23:23:58 -07008919 if ((displayContent.pendingLayoutChanges
8920 & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
Craig Mautner76a71652012-09-03 23:23:58 -07008921 displayContent.layoutNeeded = true;
Craig Mautner6fbda632012-07-03 09:26:39 -07008922 }
Craig Mautner76a71652012-09-03 23:23:58 -07008923
8924 // FIRST LOOP: Perform a layout, if needed.
8925 if (repeats < 4) {
8926 performLayoutLockedInner(displayContent, repeats == 1,
8927 false /*updateInputWindows*/);
8928 } else {
8929 Slog.w(TAG, "Layout repeat skipped after too many iterations");
8930 }
8931
8932 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
8933 // it is animating.
8934 displayContent.pendingLayoutChanges = 0;
8935
8936 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("loop number "
8937 + mLayoutRepeatCount, displayContent.pendingLayoutChanges);
8938
Craig Mautner69b08182012-09-05 13:07:13 -07008939 if (isDefaultDisplay) {
8940 mPolicy.beginPostLayoutPolicyLw(dw, dh);
8941 for (i = windows.size() - 1; i >= 0; i--) {
8942 WindowState w = windows.get(i);
8943 if (w.mHasSurface) {
8944 mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs);
8945 }
Craig Mautner6fbda632012-07-03 09:26:39 -07008946 }
Craig Mautner69b08182012-09-05 13:07:13 -07008947 displayContent.pendingLayoutChanges |= mPolicy.finishPostLayoutPolicyLw();
8948 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
8949 "after finishPostLayoutPolicyLw", displayContent.pendingLayoutChanges);
Craig Mautner76a71652012-09-03 23:23:58 -07008950 }
Craig Mautner76a71652012-09-03 23:23:58 -07008951 } while (displayContent.pendingLayoutChanges != 0);
8952
8953 mInnerFields.mObscured = false;
Craig Mautner76a71652012-09-03 23:23:58 -07008954 mInnerFields.mSyswin = false;
Craig Mautner05d29032013-05-03 13:40:13 -07008955 displayContent.resetDimming();
Craig Mautner76a71652012-09-03 23:23:58 -07008956
8957 // Only used if default window
8958 final boolean someoneLosingFocus = !mLosingFocus.isEmpty();
8959
8960 final int N = windows.size();
8961 for (i=N-1; i>=0; i--) {
8962 WindowState w = windows.get(i);
8963
8964 final boolean obscuredChanged = w.mObscured != mInnerFields.mObscured;
8965
8966 // Update effect.
8967 w.mObscured = mInnerFields.mObscured;
8968 if (!mInnerFields.mObscured) {
8969 handleNotObscuredLocked(w, currentTime, innerDw, innerDh);
8970 }
8971
Craig Mautner05d29032013-05-03 13:40:13 -07008972 if (!w.getStack().testDimmingTag()) {
Craig Mautner312eac42012-11-13 10:56:22 -08008973 handleFlagDimBehind(w, innerDw, innerDh);
8974 }
8975
Craig Mautner76a71652012-09-03 23:23:58 -07008976 if (isDefaultDisplay && obscuredChanged && (mWallpaperTarget == w)
8977 && w.isVisibleLw()) {
8978 // This is the wallpaper target and its obscured state
8979 // changed... make sure the current wallaper's visibility
8980 // has been updated accordingly.
8981 updateWallpaperVisibilityLocked();
8982 }
8983
8984 final WindowStateAnimator winAnimator = w.mWinAnimator;
8985
8986 // If the window has moved due to its containing
8987 // content frame changing, then we'd like to animate
8988 // it.
8989 if (w.mHasSurface && w.shouldAnimateMove()) {
8990 // Frame has moved, containing content frame
8991 // has also moved, and we're not currently animating...
8992 // let's do something.
8993 Animation a = AnimationUtils.loadAnimation(mContext,
8994 com.android.internal.R.anim.window_move_from_decor);
8995 winAnimator.setAnimation(a);
8996 winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
8997 winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
8998 try {
8999 w.mClient.moved(w.mFrame.left, w.mFrame.top);
9000 } catch (RemoteException e) {
9001 }
9002 }
9003
9004 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
9005 w.mContentChanged = false;
9006
9007 // Moved from updateWindowsAndWallpaperLocked().
9008 if (w.mHasSurface) {
9009 // Take care of the window being ready to display.
Craig Mautner69b08182012-09-05 13:07:13 -07009010 final boolean committed =
9011 winAnimator.commitFinishDrawingLocked(currentTime);
9012 if (isDefaultDisplay && committed) {
Dianne Hackborn7ad44382012-10-18 17:46:00 -07009013 if (w.mAttrs.type == TYPE_DREAM) {
9014 // HACK: When a dream is shown, it may at that
9015 // point hide the lock screen. So we need to
9016 // redo the layout to let the phone window manager
9017 // make this happen.
9018 displayContent.pendingLayoutChanges |=
9019 WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
Craig Mautner11462cc2013-05-13 15:56:18 -07009020 if (DEBUG_LAYOUT_REPEATS) {
Dianne Hackborn7ad44382012-10-18 17:46:00 -07009021 debugLayoutRepeats(
9022 "dream and commitFinishDrawingLocked true",
9023 displayContent.pendingLayoutChanges);
9024 }
9025 }
Craig Mautner65d11b32012-10-01 13:59:52 -07009026 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07009027 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Craig Mautner76a71652012-09-03 23:23:58 -07009028 "First draw done in potential wallpaper target " + w);
9029 mInnerFields.mWallpaperMayChange = true;
9030 displayContent.pendingLayoutChanges |=
9031 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Craig Mautner11462cc2013-05-13 15:56:18 -07009032 if (DEBUG_LAYOUT_REPEATS) {
Craig Mautner76a71652012-09-03 23:23:58 -07009033 debugLayoutRepeats(
9034 "wallpaper and commitFinishDrawingLocked true",
9035 displayContent.pendingLayoutChanges);
Craig Mautner6fbda632012-07-03 09:26:39 -07009036 }
9037 }
Craig Mautner76a71652012-09-03 23:23:58 -07009038 }
9039
Craig Mautnera91f9e22012-09-14 16:22:08 -07009040 winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
Craig Mautner76a71652012-09-03 23:23:58 -07009041
9042 final AppWindowToken atoken = w.mAppToken;
Craig Mautner65d11b32012-10-01 13:59:52 -07009043 if (DEBUG_STARTING_WINDOW && atoken != null
9044 && w == atoken.startingWindow) {
Craig Mautner76a71652012-09-03 23:23:58 -07009045 Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen="
9046 + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
9047 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
9048 }
9049 if (atoken != null
9050 && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
9051 if (atoken.lastTransactionSequence != mTransactionSequence) {
9052 atoken.lastTransactionSequence = mTransactionSequence;
9053 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
9054 atoken.startingDisplayed = false;
9055 }
Craig Mautner65d11b32012-10-01 13:59:52 -07009056 if ((w.isOnScreen() || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
Craig Mautner76a71652012-09-03 23:23:58 -07009057 && !w.mExiting && !w.mDestroying) {
Craig Mautner11462cc2013-05-13 15:56:18 -07009058 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Craig Mautner76a71652012-09-03 23:23:58 -07009059 Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
9060 + ", isAnimating=" + winAnimator.isAnimating());
9061 if (!w.isDrawnLw()) {
Mathias Agopian29479eb2013-02-14 14:36:04 -08009062 Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceControl
Craig Mautner76a71652012-09-03 23:23:58 -07009063 + " pv=" + w.mPolicyVisibility
9064 + " mDrawState=" + winAnimator.mDrawState
9065 + " ah=" + w.mAttachedHidden
9066 + " th=" + atoken.hiddenRequested
9067 + " a=" + winAnimator.mAnimating);
Craig Mautner6fbda632012-07-03 09:26:39 -07009068 }
9069 }
Craig Mautner76a71652012-09-03 23:23:58 -07009070 if (w != atoken.startingWindow) {
9071 if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
9072 atoken.numInterestingWindows++;
9073 if (w.isDrawnLw()) {
9074 atoken.numDrawnWindows++;
Craig Mautner11462cc2013-05-13 15:56:18 -07009075 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautner76a71652012-09-03 23:23:58 -07009076 "tokenMayBeDrawn: " + atoken
9077 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen
9078 + " mAppFreezing=" + w.mAppFreezing);
9079 updateAllDrawn = true;
9080 }
9081 }
9082 } else if (w.isDrawnLw()) {
9083 atoken.startingDisplayed = true;
9084 }
Craig Mautner6fbda632012-07-03 09:26:39 -07009085 }
9086 }
9087 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009088
Craig Mautner76a71652012-09-03 23:23:58 -07009089 if (isDefaultDisplay && someoneLosingFocus && (w == mCurrentFocus)
9090 && w.isDisplayedLw()) {
9091 focusDisplayed = true;
9092 }
Craig Mautner51bb12b2012-04-27 14:39:53 -07009093
Craig Mautner76a71652012-09-03 23:23:58 -07009094 updateResizingWindows(w);
9095 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07009096
Craig Mautner65d11b32012-10-01 13:59:52 -07009097 final boolean hasUniqueContent;
9098 switch (mInnerFields.mDisplayHasContent) {
9099 case LayoutFields.DISPLAY_CONTENT_MIRROR:
9100 hasUniqueContent = isDefaultDisplay;
9101 break;
9102 case LayoutFields.DISPLAY_CONTENT_UNIQUE:
9103 hasUniqueContent = true;
9104 break;
9105 case LayoutFields.DISPLAY_CONTENT_UNKNOWN:
9106 default:
9107 hasUniqueContent = false;
9108 break;
9109 }
9110 mDisplayManagerService.setDisplayHasContent(displayId, hasUniqueContent,
9111 true /* inTraversal, must call performTraversalInTrans... below */);
9112
Craig Mautner05d29032013-05-03 13:40:13 -07009113 getDisplayContentLocked(displayId).stopDimmingIfNeeded();
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009114
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08009115 if (updateAllDrawn) {
9116 updateAllDrawnLocked(displayContent);
9117 }
Craig Mautner6fbda632012-07-03 09:26:39 -07009118 }
9119
Craig Mautner7358fbf2012-04-12 21:06:33 -07009120 if (focusDisplayed) {
9121 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
9122 }
Craig Mautner65d11b32012-10-01 13:59:52 -07009123
9124 // Give the display manager a chance to adjust properties
9125 // like display rotation if it needs to.
9126 mDisplayManagerService.performTraversalInTransactionFromWindowManager();
9127
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009128 } catch (RuntimeException e) {
Dianne Hackborn89620282011-09-11 12:47:45 -07009129 Log.wtf(TAG, "Unhandled exception in Window Manager", e);
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07009130 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -08009131 SurfaceControl.closeTransaction();
Chet Haased5d11af2012-10-31 08:57:17 -07009132 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
9133 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009134 }
9135
Craig Mautner76a71652012-09-03 23:23:58 -07009136 final WindowList defaultWindows = defaultDisplay.getWindowList();
9137
Craig Mautner764983d2012-03-22 11:37:36 -07009138 // If we are ready to perform an app transition, check through
9139 // all of the app tokens to be shown and see if they are ready
9140 // to go.
Craig Mautner164d4bb2012-11-26 13:51:23 -08009141 if (mAppTransition.isReady()) {
Craig Mautner76a71652012-09-03 23:23:58 -07009142 defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009143 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAppTransitionReadyLocked",
Craig Mautnerae446592012-12-06 19:05:05 -08009144 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009145 }
9146
Craig Mautner164d4bb2012-11-26 13:51:23 -08009147 if (!mAnimator.mAnimating && mAppTransition.isRunning()) {
Craig Mautner764983d2012-03-22 11:37:36 -07009148 // We have finished the animation of an app transition. To do
9149 // this, we have delayed a lot of operations like showing and
9150 // hiding apps, moving apps in Z-order, etc. The app token list
9151 // reflects the correct Z-order, but the window list may now
9152 // be out of sync with it. So here we will just rebuild the
9153 // entire app window list. Fun!
Craig Mautner76a71652012-09-03 23:23:58 -07009154 defaultDisplay.pendingLayoutChanges |= handleAnimatingStoppedAndTransitionLocked();
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009155 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAnimStopAndXitionLock",
Craig Mautner76a71652012-09-03 23:23:58 -07009156 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009157 }
9158
Craig Mautner76a71652012-09-03 23:23:58 -07009159 if (mInnerFields.mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
Craig Mautner164d4bb2012-11-26 13:51:23 -08009160 && !mAppTransition.isReady()) {
Craig Mautner764983d2012-03-22 11:37:36 -07009161 // At this point, there was a window with a wallpaper that
9162 // was force hiding other windows behind it, but now it
9163 // is going away. This may be simple -- just animate
9164 // away the wallpaper and its window -- or it may be
9165 // hard -- the wallpaper now needs to be shown behind
9166 // something that was hidden.
Craig Mautnerae446592012-12-06 19:05:05 -08009167 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009168 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animateAwayWallpaperLocked",
Craig Mautner76a71652012-09-03 23:23:58 -07009169 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009170 }
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009171 mInnerFields.mWallpaperForceHidingChanged = false;
Craig Mautner764983d2012-03-22 11:37:36 -07009172
Craig Mautnere7ae2502012-03-26 17:11:19 -07009173 if (mInnerFields.mWallpaperMayChange) {
Craig Mautner11462cc2013-05-13 15:56:18 -07009174 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Wallpaper may change! Adjusting");
Craig Mautnerae446592012-12-06 19:05:05 -08009175 defaultDisplay.pendingLayoutChanges |=
9176 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
9177 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
9178 defaultDisplay.pendingLayoutChanges);
Craig Mautnere7ae2502012-03-26 17:11:19 -07009179 }
9180
9181 if (mFocusMayChange) {
9182 mFocusMayChange = false;
9183 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
9184 false /*updateInputWindows*/)) {
Craig Mautner76a71652012-09-03 23:23:58 -07009185 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
Craig Mautnere7ae2502012-03-26 17:11:19 -07009186 }
9187 }
Craig Mautner764983d2012-03-22 11:37:36 -07009188
Craig Mautner19d59bc2012-09-04 11:15:56 -07009189 if (needsLayout()) {
Craig Mautner76a71652012-09-03 23:23:58 -07009190 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
9191 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
9192 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009193 }
9194
Craig Mautnerade0a9a2012-10-06 13:55:07 -07009195 for (i = mResizingWindows.size() - 1; i >= 0; i--) {
9196 WindowState win = mResizingWindows.get(i);
9197 if (win.mAppFreezing) {
9198 // Don't remove this window until rotation has completed.
9199 continue;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009200 }
Craig Mautnerade0a9a2012-10-06 13:55:07 -07009201 final WindowStateAnimator winAnimator = win.mWinAnimator;
9202 try {
9203 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
9204 "Reporting new frame to " + win + ": " + win.mCompatFrame);
9205 int diff = 0;
9206 boolean configChanged = win.isConfigChanged();
Dianne Hackborn7ff30112012-11-08 11:12:09 -08009207 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
Craig Mautnerade0a9a2012-10-06 13:55:07 -07009208 && configChanged) {
9209 Slog.i(TAG, "Sending new config to window " + win + ": "
9210 + winAnimator.mSurfaceW + "x" + winAnimator.mSurfaceH
9211 + " / " + mCurConfiguration + " / 0x"
9212 + Integer.toHexString(diff));
9213 }
Craig Mautnere8552142012-11-07 13:55:47 -08009214 win.setConfiguration(mCurConfiguration);
Craig Mautnerade0a9a2012-10-06 13:55:07 -07009215 if (DEBUG_ORIENTATION &&
9216 winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) Slog.i(
9217 TAG, "Resizing " + win + " WITH DRAW PENDING");
Sangkyu Lee0438bd62013-01-16 14:53:17 +09009218 final IWindow client = win.mClient;
9219 final Rect frame = win.mFrame;
9220 final Rect overscanInsets = win.mLastOverscanInsets;
9221 final Rect contentInsets = win.mLastContentInsets;
9222 final Rect visibleInsets = win.mLastVisibleInsets;
9223 final boolean reportDraw
9224 = winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING;
9225 final Configuration newConfig = configChanged ? win.mConfiguration : null;
9226 if (win.mClient instanceof IWindow.Stub) {
9227 // To prevent deadlock simulate one-way call if win.mClient is a local object.
9228 mH.post(new Runnable() {
9229 @Override
9230 public void run() {
9231 try {
9232 client.resized(frame, overscanInsets, contentInsets,
9233 visibleInsets, reportDraw, newConfig);
9234 } catch (RemoteException e) {
9235 // Not a remote call, RemoteException won't be raised.
9236 }
9237 }
9238 });
9239 } else {
9240 client.resized(frame, overscanInsets, contentInsets, visibleInsets, reportDraw,
9241 newConfig);
9242 }
Dianne Hackbornc4aad012013-02-22 15:05:25 -08009243 win.mOverscanInsetsChanged = false;
Craig Mautnerade0a9a2012-10-06 13:55:07 -07009244 win.mContentInsetsChanged = false;
9245 win.mVisibleInsetsChanged = false;
9246 winAnimator.mSurfaceResized = false;
9247 } catch (RemoteException e) {
9248 win.mOrientationChanging = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009249 win.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
9250 - mDisplayFreezeTime);
Craig Mautnerade0a9a2012-10-06 13:55:07 -07009251 }
9252 mResizingWindows.remove(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009253 }
Romain Guy06882f82009-06-10 13:36:04 -07009254
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009255 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
9256 "With display frozen, orientationChangeComplete="
9257 + mInnerFields.mOrientationChangeComplete);
9258 if (mInnerFields.mOrientationChangeComplete) {
9259 if (mWindowsFreezingScreen) {
9260 mWindowsFreezingScreen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009261 mLastFinishedFreezeSource = mInnerFields.mLastWindowFreezeSource;
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009262 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
9263 }
9264 stopFreezingDisplayLocked();
9265 }
9266
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009267 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009268 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009269 i = mDestroySurface.size();
9270 if (i > 0) {
9271 do {
9272 i--;
9273 WindowState win = mDestroySurface.get(i);
9274 win.mDestroying = false;
9275 if (mInputMethodWindow == win) {
9276 mInputMethodWindow = null;
9277 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009278 if (win == mWallpaperTarget) {
9279 wallpaperDestroyed = true;
9280 }
Craig Mautner96868332012-12-04 14:29:11 -08009281 win.mWinAnimator.destroySurfaceLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009282 } while (i > 0);
9283 mDestroySurface.clear();
9284 }
9285
9286 // Time to remove any exiting tokens?
Craig Mautnerf8924152013-07-16 09:10:55 -07009287 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9288 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08009289 ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
9290 for (i = exitingTokens.size() - 1; i >= 0; i--) {
9291 WindowToken token = exitingTokens.get(i);
9292 if (!token.hasVisible) {
9293 exitingTokens.remove(i);
9294 if (token.windowType == TYPE_WALLPAPER) {
9295 mWallpaperTokens.remove(token);
9296 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07009297 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009298 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009299
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08009300 // Time to remove any exiting applications?
9301 AppTokenList exitingAppTokens = displayContent.mExitingAppTokens;
9302 for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
9303 AppWindowToken token = exitingAppTokens.get(i);
9304 if (!token.hasVisible && !mClosingApps.contains(token)) {
9305 // Make sure there is no animation running on this token,
9306 // so any windows associated with it will be removed as
9307 // soon as their animations are complete
9308 token.mAppAnimator.clearAnimation();
9309 token.mAppAnimator.animating = false;
9310 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
9311 "performLayout: App token exiting now removed" + token);
Craig Mautnerc00204b2013-03-05 15:02:14 -08009312 final Task task = mTaskIdToTask.get(token.groupId);
9313 if (task != null && task.removeAppToken(token)) {
9314 mTaskIdToTask.delete(token.groupId);
Craig Mautnerc00204b2013-03-05 15:02:14 -08009315 }
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08009316 exitingAppTokens.remove(i);
9317 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009318 }
9319 }
9320
Dianne Hackborn12d3a942012-04-27 14:16:30 -07009321 if (!mAnimator.mAnimating && mRelayoutWhileAnimating.size() > 0) {
9322 for (int j=mRelayoutWhileAnimating.size()-1; j>=0; j--) {
9323 try {
9324 mRelayoutWhileAnimating.get(j).mClient.doneAnimating();
9325 } catch (RemoteException e) {
9326 }
9327 }
9328 mRelayoutWhileAnimating.clear();
9329 }
9330
Craig Mautnerae446592012-12-06 19:05:05 -08009331 if (wallpaperDestroyed) {
9332 defaultDisplay.pendingLayoutChanges |=
9333 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
9334 defaultDisplay.layoutNeeded = true;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009335 }
Craig Mautner76a71652012-09-03 23:23:58 -07009336
Craig Mautnerf8924152013-07-16 09:10:55 -07009337 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9338 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautner76a71652012-09-03 23:23:58 -07009339 if (displayContent.pendingLayoutChanges != 0) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009340 displayContent.layoutNeeded = true;
Craig Mautner76a71652012-09-03 23:23:58 -07009341 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009342 }
Jeff Browneb857f12010-07-16 10:06:33 -07009343
Jeff Brown3a22cd92011-01-21 13:59:04 -08009344 // Finally update all input windows now that the window changes have stabilized.
Jeff Brown2e44b072011-01-24 15:21:56 -08009345 mInputMonitor.updateInputWindowsLw(true /*force*/);
Jeff Browneb857f12010-07-16 10:06:33 -07009346
Craig Mautner259328c2012-08-21 19:30:58 -07009347 setHoldScreenLocked(mInnerFields.mHoldScreen);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009348 if (!mDisplayFrozen) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009349 if (mInnerFields.mScreenBrightness < 0 || mInnerFields.mScreenBrightness > 1.0f) {
Jeff Brown96307042012-07-27 15:51:34 -07009350 mPowerManager.setScreenBrightnessOverrideFromWindowManager(-1);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009351 } else {
Jeff Brown96307042012-07-27 15:51:34 -07009352 mPowerManager.setScreenBrightnessOverrideFromWindowManager(
9353 toBrightnessOverride(mInnerFields.mScreenBrightness));
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009354 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009355 if (mInnerFields.mButtonBrightness < 0 || mInnerFields.mButtonBrightness > 1.0f) {
Jeff Brown96307042012-07-27 15:51:34 -07009356 mPowerManager.setButtonBrightnessOverrideFromWindowManager(-1);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009357 } else {
Jeff Brown96307042012-07-27 15:51:34 -07009358 mPowerManager.setButtonBrightnessOverrideFromWindowManager(
9359 toBrightnessOverride(mInnerFields.mButtonBrightness));
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009360 }
Jeff Brown1e3b98d2012-09-30 18:58:59 -07009361 mPowerManager.setUserActivityTimeoutOverrideFromWindowManager(
9362 mInnerFields.mUserActivityTimeout);
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009363 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009364
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009365 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009366 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Jeff Brown96307042012-07-27 15:51:34 -07009367 mPowerManager.wakeUp(SystemClock.uptimeMillis());
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009368 mTurnOnScreen = false;
9369 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009370
Craig Mautnera608b882012-03-30 13:03:49 -07009371 if (mInnerFields.mUpdateRotation) {
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009372 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009373 if (updateRotationUncheckedLocked(false)) {
Dianne Hackborn3e4f9d02011-02-04 14:05:55 -08009374 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07009375 } else {
Craig Mautnera608b882012-03-30 13:03:49 -07009376 mInnerFields.mUpdateRotation = false;
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009377 }
9378 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009379
Craig Mautner19d59bc2012-09-04 11:15:56 -07009380 if (mInnerFields.mOrientationChangeComplete && !defaultDisplay.layoutNeeded
9381 && !mInnerFields.mUpdateRotation) {
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07009382 checkDrawnWindowsLocked();
9383 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009384
Craig Mautner76a71652012-09-03 23:23:58 -07009385 final int N = mPendingRemove.size();
9386 if (N > 0) {
9387 if (mPendingRemoveTmp.length < N) {
9388 mPendingRemoveTmp = new WindowState[N+10];
9389 }
9390 mPendingRemove.toArray(mPendingRemoveTmp);
9391 mPendingRemove.clear();
9392 DisplayContentList displayList = new DisplayContentList();
9393 for (i = 0; i < N; i++) {
9394 WindowState w = mPendingRemoveTmp[i];
9395 removeWindowInnerLocked(w.mSession, w);
9396 if (!displayList.contains(w.mDisplayContent)) {
9397 displayList.add(w.mDisplayContent);
9398 }
9399 }
9400
9401 for (DisplayContent displayContent : displayList) {
9402 assignLayersLocked(displayContent.getWindowList());
Craig Mautner19d59bc2012-09-04 11:15:56 -07009403 displayContent.layoutNeeded = true;
Craig Mautner76a71652012-09-03 23:23:58 -07009404 }
Craig Mautner76a71652012-09-03 23:23:58 -07009405 }
9406
Craig Mautnerf7666462013-04-28 08:58:21 -07009407 setFocusedStackFrame();
Craig Mautnerc5a6e442013-06-05 17:22:35 -07009408
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08009409 // Check to see if we are now in a state where the screen should
9410 // be enabled, because the window obscured flags have changed.
9411 enableScreenIfNeededLocked();
Craig Mautner7d8df392012-04-06 15:26:23 -07009412
Craig Mautner96868332012-12-04 14:29:11 -08009413 scheduleAnimationLocked();
Craig Mautner7d8df392012-04-06 15:26:23 -07009414
9415 if (DEBUG_WINDOW_TRACE) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009416 Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: animating="
9417 + mAnimator.mAnimating);
Craig Mautner7d8df392012-04-06 15:26:23 -07009418 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009419 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009420
Jeff Brown96307042012-07-27 15:51:34 -07009421 private int toBrightnessOverride(float value) {
9422 return (int)(value * PowerManager.BRIGHTNESS_ON);
9423 }
9424
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009425 void checkDrawnWindowsLocked() {
9426 if (mWaitingForDrawn.size() > 0) {
9427 for (int j=mWaitingForDrawn.size()-1; j>=0; j--) {
9428 Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(j);
9429 WindowState win = pair.first;
9430 //Slog.i(TAG, "Waiting for drawn " + win + ": removed="
9431 // + win.mRemoved + " visible=" + win.isVisibleLw()
9432 // + " shown=" + win.mSurfaceShown);
9433 if (win.mRemoved || !win.isVisibleLw()) {
9434 // Window has been removed or made invisible; no draw
9435 // will now happen, so stop waiting.
9436 Slog.w(TAG, "Aborted waiting for drawn: " + pair.first);
9437 try {
9438 pair.second.sendResult(null);
9439 } catch (RemoteException e) {
9440 }
9441 mWaitingForDrawn.remove(pair);
9442 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009443 } else if (win.mWinAnimator.mSurfaceShown) {
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009444 // Window is now drawn (and shown).
9445 try {
9446 pair.second.sendResult(null);
9447 } catch (RemoteException e) {
9448 }
9449 mWaitingForDrawn.remove(pair);
9450 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9451 }
9452 }
9453 }
9454 }
9455
Craig Mautner2268e7e2012-12-13 15:40:00 -08009456 @Override
Jeff Brownc38c9be2012-10-04 13:16:19 -07009457 public boolean waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
9458 if (token != null && callback != null) {
9459 synchronized (mWindowMap) {
9460 WindowState win = windowForClientLocked(null, token, true);
9461 if (win != null) {
9462 Pair<WindowState, IRemoteCallback> pair =
9463 new Pair<WindowState, IRemoteCallback>(win, callback);
9464 Message m = mH.obtainMessage(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9465 mH.sendMessageDelayed(m, 2000);
9466 mWaitingForDrawn.add(pair);
9467 checkDrawnWindowsLocked();
9468 return true;
9469 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009470 }
9471 }
Jeff Brownc38c9be2012-10-04 13:16:19 -07009472 return false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009473 }
9474
Craig Mautner259328c2012-08-21 19:30:58 -07009475 void setHoldScreenLocked(final Session newHoldScreen) {
9476 final boolean hold = newHoldScreen != null;
9477
9478 if (hold && mHoldingScreenOn != newHoldScreen) {
9479 mHoldingScreenWakeLock.setWorkSource(new WorkSource(newHoldScreen.mUid));
9480 }
9481 mHoldingScreenOn = newHoldScreen;
9482
9483 final boolean state = mHoldingScreenWakeLock.isHeld();
9484 if (hold != state) {
9485 if (hold) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07009486 mHoldingScreenWakeLock.acquire();
Jeff Brownc38c9be2012-10-04 13:16:19 -07009487 mPolicy.keepScreenOnStartedLw();
Jeff Brown46b9ac02010-04-22 18:58:52 -07009488 } else {
Jeff Brownc38c9be2012-10-04 13:16:19 -07009489 mPolicy.keepScreenOnStoppedLw();
Jeff Brown46b9ac02010-04-22 18:58:52 -07009490 mHoldingScreenWakeLock.release();
9491 }
9492 }
9493 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009494
Craig Mautner722285e2012-09-07 13:55:58 -07009495 @Override
Jeff Brown4ed8fe72012-08-30 18:18:29 -07009496 public void requestTraversal() {
9497 synchronized (mWindowMap) {
9498 requestTraversalLocked();
9499 }
9500 }
9501
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08009502 void requestTraversalLocked() {
9503 if (!mTraversalScheduled) {
9504 mTraversalScheduled = true;
9505 mH.sendEmptyMessage(H.DO_TRAVERSAL);
9506 }
9507 }
9508
Craig Mautner711f90a2012-07-03 18:43:52 -07009509 /** Note that Locked in this case is on mLayoutToAnim */
Jeff Brown4a06c802012-02-15 15:06:01 -08009510 void scheduleAnimationLocked() {
Craig Mautner96868332012-12-04 14:29:11 -08009511 if (!mAnimationScheduled) {
9512 mAnimationScheduled = true;
Craig Mautner711f90a2012-07-03 18:43:52 -07009513 mChoreographer.postCallback(
9514 Choreographer.CALLBACK_ANIMATION, mAnimator.mAnimationRunnable, null);
9515 }
9516 }
9517
Craig Mautner19d59bc2012-09-04 11:15:56 -07009518 private boolean needsLayout() {
Craig Mautnerf8924152013-07-16 09:10:55 -07009519 final int numDisplays = mDisplayContents.size();
9520 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9521 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
9522 if (displayContent.layoutNeeded) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009523 return true;
9524 }
9525 }
9526 return false;
9527 }
9528
Craig Mautner96868332012-12-04 14:29:11 -08009529 boolean copyAnimToLayoutParamsLocked() {
Craig Mautner322e4032012-07-13 13:35:20 -07009530 boolean doRequest = false;
Craig Mautner322e4032012-07-13 13:35:20 -07009531
Craig Mautner96868332012-12-04 14:29:11 -08009532 final int bulkUpdateParams = mAnimator.mBulkUpdateParams;
Craig Mautner96868332012-12-04 14:29:11 -08009533 if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) {
9534 mInnerFields.mUpdateRotation = true;
9535 doRequest = true;
Craig Mautner322e4032012-07-13 13:35:20 -07009536 }
Craig Mautner96868332012-12-04 14:29:11 -08009537 if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
9538 mInnerFields.mWallpaperMayChange = true;
9539 doRequest = true;
9540 }
9541 if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
9542 mInnerFields.mWallpaperForceHidingChanged = true;
9543 doRequest = true;
9544 }
9545 if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
9546 mInnerFields.mOrientationChangeComplete = false;
9547 } else {
9548 mInnerFields.mOrientationChangeComplete = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009549 mInnerFields.mLastWindowFreezeSource = mAnimator.mLastWindowFreezeSource;
Craig Mautner96868332012-12-04 14:29:11 -08009550 if (mWindowsFreezingScreen) {
9551 doRequest = true;
9552 }
9553 }
9554 if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
9555 mTurnOnScreen = true;
9556 }
9557 if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_ACTION_PENDING) != 0) {
9558 mInnerFields.mWallpaperActionPending = true;
9559 }
9560
Craig Mautner322e4032012-07-13 13:35:20 -07009561 return doRequest;
9562 }
9563
Craig Mautner05d29032013-05-03 13:40:13 -07009564 /** If a window that has an animation specifying a colored background is the current wallpaper
9565 * target, then the color goes *below* the wallpaper so we don't cause the wallpaper to
9566 * suddenly disappear. */
9567 int adjustAnimationBackground(WindowStateAnimator winAnimator) {
9568 final WindowState win = winAnimator.mWin;
9569 if (mWallpaperTarget == win || mLowerWallpaperTarget == win
9570 || mUpperWallpaperTarget == win) {
9571 WindowList windows = win.getWindowList();
9572 for (int i = windows.size() - 1; i >= 0; --i) {
9573 WindowState testWin = windows.get(i);
9574 if (testWin.mIsWallpaper) {
9575 return testWin.mWinAnimator.mAnimLayer;
9576 }
9577 }
9578 }
9579 return winAnimator.mAnimLayer;
9580 }
9581
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009582 boolean reclaimSomeSurfaceMemoryLocked(WindowStateAnimator winAnimator, String operation,
9583 boolean secure) {
Mathias Agopian29479eb2013-02-14 14:36:04 -08009584 final SurfaceControl surface = winAnimator.mSurfaceControl;
Dianne Hackborn64825172011-03-02 21:32:58 -08009585 boolean leakedSurface = false;
9586 boolean killedApps = false;
Romain Guy06882f82009-06-10 13:36:04 -07009587
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009588 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
9589 winAnimator.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -07009590
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009591 if (mForceRemoves == null) {
9592 mForceRemoves = new ArrayList<WindowState>();
9593 }
Romain Guy06882f82009-06-10 13:36:04 -07009594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009595 long callingIdentity = Binder.clearCallingIdentity();
9596 try {
9597 // There was some problem... first, do a sanity check of the
9598 // window list to make sure we haven't left any dangling surfaces
9599 // around.
Craig Mautner59c00972012-07-30 12:10:24 -07009600
Joe Onorato8a9b2202010-02-26 18:56:32 -08009601 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
Craig Mautnerf8924152013-07-16 09:10:55 -07009602 final int numDisplays = mDisplayContents.size();
9603 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9604 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
9605 final int numWindows = windows.size();
9606 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
9607 final WindowState ws = windows.get(winNdx);
9608 WindowStateAnimator wsa = ws.mWinAnimator;
9609 if (wsa.mSurfaceControl != null) {
9610 if (!mSessions.contains(wsa.mSession)) {
9611 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
9612 + ws + " surface=" + wsa.mSurfaceControl
9613 + " token=" + ws.mToken
9614 + " pid=" + ws.mSession.mPid
9615 + " uid=" + ws.mSession.mUid);
9616 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
9617 wsa.mSurfaceControl.destroy();
9618 wsa.mSurfaceShown = false;
9619 wsa.mSurfaceControl = null;
9620 ws.mHasSurface = false;
9621 mForceRemoves.add(ws);
9622 leakedSurface = true;
9623 } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
9624 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
9625 + ws + " surface=" + wsa.mSurfaceControl
9626 + " token=" + ws.mAppToken);
9627 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
9628 wsa.mSurfaceControl.destroy();
9629 wsa.mSurfaceShown = false;
9630 wsa.mSurfaceControl = null;
9631 ws.mHasSurface = false;
9632 leakedSurface = true;
9633 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009634 }
9635 }
9636 }
Romain Guy06882f82009-06-10 13:36:04 -07009637
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009638 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009639 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009640 SparseIntArray pidCandidates = new SparseIntArray();
Craig Mautnerf8924152013-07-16 09:10:55 -07009641 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9642 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
9643 final int numWindows = windows.size();
9644 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
9645 final WindowState ws = windows.get(winNdx);
9646 if (mForceRemoves.contains(ws)) {
9647 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009648 }
Craig Mautnerf8924152013-07-16 09:10:55 -07009649 WindowStateAnimator wsa = ws.mWinAnimator;
9650 if (wsa.mSurfaceControl != null) {
9651 pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
9652 }
9653 }
9654 if (pidCandidates.size() > 0) {
9655 int[] pids = new int[pidCandidates.size()];
9656 for (int i=0; i<pids.length; i++) {
9657 pids[i] = pidCandidates.keyAt(i);
9658 }
9659 try {
9660 if (mActivityManager.killPids(pids, "Free memory", secure)) {
9661 killedApps = true;
9662 }
9663 } catch (RemoteException e) {
9664 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009665 }
9666 }
9667 }
Romain Guy06882f82009-06-10 13:36:04 -07009668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009669 if (leakedSurface || killedApps) {
9670 // We managed to reclaim some memory, so get rid of the trouble
9671 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -08009672 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009673 if (surface != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009674 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
Dianne Hackborn5fd21692011-06-07 14:09:47 -07009675 "RECOVER DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009676 surface.destroy();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009677 winAnimator.mSurfaceShown = false;
Mathias Agopian29479eb2013-02-14 14:36:04 -08009678 winAnimator.mSurfaceControl = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009679 winAnimator.mWin.mHasSurface = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009680 }
Romain Guy06882f82009-06-10 13:36:04 -07009681
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009682 try {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009683 winAnimator.mWin.mClient.dispatchGetNewSurface();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009684 } catch (RemoteException e) {
9685 }
9686 }
9687 } finally {
9688 Binder.restoreCallingIdentity(callingIdentity);
9689 }
Dianne Hackborn64825172011-03-02 21:32:58 -08009690
9691 return leakedSurface || killedApps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009692 }
Romain Guy06882f82009-06-10 13:36:04 -07009693
Jeff Brown3a22cd92011-01-21 13:59:04 -08009694 private boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009695 WindowState newFocus = computeFocusedWindowLocked();
9696 if (mCurrentFocus != newFocus) {
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07009697 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009698 // This check makes sure that we don't already have the focus
9699 // change message pending.
9700 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
9701 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Satoshi Kataoka02679f62013-05-20 16:13:44 +09009702 // TODO(multidisplay): Focused windows on default display only.
9703 final DisplayContent displayContent = getDefaultDisplayContentLocked();
9704 final boolean imWindowChanged = moveInputMethodWindowsIfNeededLocked(
9705 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS
9706 && mode != UPDATE_FOCUS_WILL_PLACE_SURFACES);
9707 if (imWindowChanged) {
9708 displayContent.layoutNeeded = true;
9709 newFocus = computeFocusedWindowLocked();
9710 }
9711
Joe Onorato8a9b2202010-02-26 18:56:32 -08009712 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009713 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
9714 final WindowState oldFocus = mCurrentFocus;
9715 mCurrentFocus = newFocus;
9716 mLosingFocus.remove(newFocus);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009717 int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus);
Romain Guy06882f82009-06-10 13:36:04 -07009718
Satoshi Kataoka12afe142013-05-21 06:19:27 +09009719 if (imWindowChanged && oldFocus != mInputMethodWindow) {
Satoshi Kataoka02679f62013-05-20 16:13:44 +09009720 // Focus of the input method window changed. Perform layout if needed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009721 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Craig Mautner59c00972012-07-30 12:10:24 -07009722 performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009723 focusChanged &= ~WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009724 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
9725 // Client will do the layout, but we need to assign layers
9726 // for handleNewWindowLocked() below.
Craig Mautner59c00972012-07-30 12:10:24 -07009727 assignLayersLocked(displayContent.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009728 }
9729 }
Dianne Hackborndf89e652011-10-06 22:35:11 -07009730
Craig Mautner39834192012-09-02 07:47:24 -07009731 if ((focusChanged & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07009732 // The change in focus caused us to need to do a layout. Okay.
Jeff Brown20337632012-09-24 14:25:54 -07009733 displayContent.layoutNeeded = true;
Dianne Hackborndf89e652011-10-06 22:35:11 -07009734 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Craig Mautner59c00972012-07-30 12:10:24 -07009735 performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009736 }
9737 }
9738
Jeff Brown349703e2010-06-22 01:27:15 -07009739 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
9740 // If we defer assigning layers, then the caller is responsible for
9741 // doing this part.
Jeff Brown3a22cd92011-01-21 13:59:04 -08009742 finishUpdateFocusedWindowAfterAssignLayersLocked(updateInputWindows);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009743 }
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07009744
9745 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009746 return true;
9747 }
9748 return false;
9749 }
Craig Mautner66f78d72012-12-04 16:46:50 -08009750
Jeff Brown3a22cd92011-01-21 13:59:04 -08009751 private void finishUpdateFocusedWindowAfterAssignLayersLocked(boolean updateInputWindows) {
9752 mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows);
Jeff Brown349703e2010-06-22 01:27:15 -07009753 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009754
9755 private WindowState computeFocusedWindowLocked() {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07009756 if (mAnimator.mUniverseBackground != null
9757 && mAnimator.mUniverseBackground.mWin.canReceiveKeys()) {
9758 return mAnimator.mUniverseBackground.mWin;
9759 }
9760
Jeff Brown20337632012-09-24 14:25:54 -07009761 final int displayCount = mDisplayContents.size();
9762 for (int i = 0; i < displayCount; i++) {
9763 final DisplayContent displayContent = mDisplayContents.valueAt(i);
9764 WindowState win = findFocusedWindowLocked(displayContent);
9765 if (win != null) {
9766 return win;
9767 }
9768 }
9769 return null;
9770 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009771
Jeff Brown20337632012-09-24 14:25:54 -07009772 private WindowState findFocusedWindowLocked(DisplayContent displayContent) {
Craig Mautnerd9a22882013-03-16 15:00:36 -07009773 // Set nextApp to the first app and set taskNdx and tokenNdx to point to the app following.
9774 final ArrayList<Task> tasks = displayContent.getTasks();
Craig Mautnerf81b90872013-02-26 13:02:43 -08009775 int taskNdx = tasks.size() - 1;
9776 AppTokenList tokens = taskNdx >= 0 ? tasks.get(taskNdx).mAppTokens : null;
9777 int tokenNdx = tokens != null ? tokens.size() - 1 : -1;
9778 WindowToken nextApp = tokenNdx >= 0 ? tokens.get(tokenNdx) : null;
9779 --tokenNdx;
9780 if (tokenNdx < 0) {
9781 --taskNdx;
9782 if (taskNdx >= 0) {
9783 tokens = tasks.get(taskNdx).mAppTokens;
9784 tokenNdx = tokens.size() - 1;
9785 }
9786 }
Jeff Brown20337632012-09-24 14:25:54 -07009787
9788 final WindowList windows = displayContent.getWindowList();
Craig Mautner59c00972012-07-30 12:10:24 -07009789 for (int i = windows.size() - 1; i >= 0; i--) {
Jeff Brown20337632012-09-24 14:25:54 -07009790 final WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009791
Joe Onorato8a9b2202010-02-26 18:56:32 -08009792 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009793 TAG, "Looking for focus: " + i
9794 + " = " + win
9795 + ", flags=" + win.mAttrs.flags
9796 + ", canReceive=" + win.canReceiveKeys());
9797
9798 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -07009799
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009800 // If this window's application has been removed, just skip it.
Craig Mautneref25d7a2012-05-15 23:01:47 -07009801 if (thisApp != null && (thisApp.removed || thisApp.sendingToBottom)) {
Craig Mautnerd9a22882013-03-16 15:00:36 -07009802 if (DEBUG_FOCUS) Slog.v(TAG, "Skipping " + thisApp + " because "
9803 + (thisApp.removed ? "removed" : "sendingToBottom"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009804 continue;
9805 }
Romain Guy06882f82009-06-10 13:36:04 -07009806
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009807 // If there is a focused app, don't allow focus to go to any
9808 // windows below it. If this is an application window, step
9809 // through the app tokens until we find its app.
9810 if (thisApp != null && nextApp != null && thisApp != nextApp
9811 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
Craig Mautner30e2d722013-02-12 11:30:16 -08009812 final WindowToken origAppToken = nextApp;
Craig Mautnerf81b90872013-02-26 13:02:43 -08009813 final int origTaskNdx = taskNdx;
9814 final int origTokenNdx = tokenNdx;
9815 for ( ; taskNdx >= 0; --taskNdx) {
9816 tokens = tasks.get(taskNdx).mAppTokens;
9817 for ( ; tokenNdx >= 0; --tokenNdx) {
9818 if (nextApp == mFocusedApp) {
9819 // Whoops, we are below the focused app... no focus
9820 // for you!
9821 if (localLOGV || DEBUG_FOCUS) Slog.v(
9822 TAG, "Reached focused app: " + mFocusedApp);
9823 return null;
9824 }
9825 nextApp = tokens.get(tokenNdx);
9826 if (nextApp == thisApp) {
9827 break;
9828 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009829 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08009830 if (thisApp == nextApp) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009831 break;
9832 }
9833 }
9834 if (thisApp != nextApp) {
9835 // Uh oh, the app token doesn't exist! This shouldn't
9836 // happen, but if it does we can get totally hosed...
9837 // so restart at the original app.
Craig Mautner30e2d722013-02-12 11:30:16 -08009838 nextApp = origAppToken;
Craig Mautnerf81b90872013-02-26 13:02:43 -08009839 // return indices to same place.
9840 taskNdx = origTaskNdx;
9841 tokenNdx = origTokenNdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009842 }
9843 }
9844
9845 // Dispatch to this window if it is wants key events.
9846 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009847 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009848 TAG, "Found focus @ " + i + " = " + win);
Jeff Brown20337632012-09-24 14:25:54 -07009849 return win;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009850 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009851 }
Jeff Brown20337632012-09-24 14:25:54 -07009852 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009853 }
9854
Craig Mautner3c174372013-02-21 17:54:37 -08009855 private void startFreezingDisplayLocked(boolean inTransaction, int exitAnim, int enterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009856 if (mDisplayFrozen) {
9857 return;
9858 }
Romain Guy06882f82009-06-10 13:36:04 -07009859
Jeff Browne215f262012-09-10 16:01:14 -07009860 if (!mDisplayReady || !mPolicy.isScreenOnFully()) {
Dianne Hackborn8e8d65f2011-08-11 19:36:18 -07009861 // No need to freeze the screen before the system is ready or if
9862 // the screen is off.
9863 return;
9864 }
9865
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009866 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -07009867
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009868 mDisplayFrozen = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009869 mDisplayFreezeTime = SystemClock.elapsedRealtime();
9870 mLastFinishedFreezeSource = null;
Craig Mautner7d8df392012-04-06 15:26:23 -07009871
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009872 mInputMonitor.freezeInputDispatchingLw();
Craig Mautner7d8df392012-04-06 15:26:23 -07009873
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07009874 // Clear the last input window -- that is just used for
9875 // clean transitions between IMEs, and if we are freezing
9876 // the screen then the whole world is changing behind the scenes.
9877 mPolicy.setLastInputMethodWindowLw(null, null);
9878
Craig Mautner164d4bb2012-11-26 13:51:23 -08009879 if (mAppTransition.isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08009880 mAppTransition.freeze();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009881 }
Romain Guy06882f82009-06-10 13:36:04 -07009882
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009883 if (PROFILE_ORIENTATION) {
9884 File file = new File("/data/system/frozen");
9885 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
9886 }
Dianne Hackborna1111872010-11-23 20:55:11 -08009887
9888 if (CUSTOM_SCREEN_ROTATION) {
Craig Mautner3c174372013-02-21 17:54:37 -08009889 mExitAnimId = exitAnim;
9890 mEnterAnimId = enterAnim;
Craig Mautnera91f9e22012-09-14 16:22:08 -07009891 final DisplayContent displayContent = getDefaultDisplayContentLocked();
9892 final int displayId = displayContent.getDisplayId();
9893 ScreenRotationAnimation screenRotationAnimation =
9894 mAnimator.getScreenRotationAnimationLocked(displayId);
9895 if (screenRotationAnimation != null) {
9896 screenRotationAnimation.kill();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08009897 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07009898
Craig Mautner59c00972012-07-30 12:10:24 -07009899 // TODO(multidisplay): rotation on main screen only.
Jeff Browne215f262012-09-10 16:01:14 -07009900 final Display display = displayContent.getDisplay();
9901 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
Craig Mautnera91f9e22012-09-14 16:22:08 -07009902 screenRotationAnimation = new ScreenRotationAnimation(mContext,
Jeff Browne215f262012-09-10 16:01:14 -07009903 display, mFxSession, inTransaction, displayInfo.logicalWidth,
Craig Mautner3c174372013-02-21 17:54:37 -08009904 displayInfo.logicalHeight, display.getRotation());
Craig Mautnera91f9e22012-09-14 16:22:08 -07009905 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackborna1111872010-11-23 20:55:11 -08009906 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009907 }
Romain Guy06882f82009-06-10 13:36:04 -07009908
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009909 private void stopFreezingDisplayLocked() {
9910 if (!mDisplayFrozen) {
9911 return;
9912 }
Romain Guy06882f82009-06-10 13:36:04 -07009913
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009914 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen
9915 || mClientFreezingScreen) {
Craig Mautnerd87946b2012-03-29 18:00:19 -07009916 if (DEBUG_ORIENTATION) Slog.d(TAG,
9917 "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + mWaitingForConfig
9918 + ", mAppsFreezingScreen=" + mAppsFreezingScreen
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009919 + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen
9920 + ", mClientFreezingScreen=" + mClientFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009921 return;
9922 }
Craig Mautner66f78d72012-12-04 16:46:50 -08009923
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009924 mDisplayFrozen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009925 mLastDisplayFreezeDuration = (int)(SystemClock.elapsedRealtime() - mDisplayFreezeTime);
9926 StringBuilder sb = new StringBuilder(128);
9927 sb.append("Screen frozen for ");
9928 TimeUtils.formatDuration(mLastDisplayFreezeDuration, sb);
9929 if (mLastFinishedFreezeSource != null) {
9930 sb.append(" due to ");
9931 sb.append(mLastFinishedFreezeSource);
9932 }
9933 Slog.i(TAG, sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009934 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009935 mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009936 if (PROFILE_ORIENTATION) {
9937 Debug.stopMethodTracing();
9938 }
Dianne Hackborna1111872010-11-23 20:55:11 -08009939
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009940 boolean updateRotation = false;
Craig Mautner59c00972012-07-30 12:10:24 -07009941
Craig Mautnera91f9e22012-09-14 16:22:08 -07009942 final DisplayContent displayContent = getDefaultDisplayContentLocked();
9943 final int displayId = displayContent.getDisplayId();
9944 ScreenRotationAnimation screenRotationAnimation =
9945 mAnimator.getScreenRotationAnimationLocked(displayId);
9946 if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
9947 && screenRotationAnimation.hasScreenshot()) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07009948 if (DEBUG_ORIENTATION) Slog.i(TAG, "**** Dismissing screen rotation animation");
Craig Mautner59c00972012-07-30 12:10:24 -07009949 // TODO(multidisplay): rotation on main screen only.
Craig Mautnera91f9e22012-09-14 16:22:08 -07009950 DisplayInfo displayInfo = displayContent.getDisplayInfo();
Craig Mautner3c174372013-02-21 17:54:37 -08009951 // Get rotation animation again, with new top window
Craig Mautner05d29032013-05-03 13:40:13 -07009952 boolean isDimming = displayContent.isDimming();
Craig Mautner3c174372013-02-21 17:54:37 -08009953 if (!mPolicy.validateRotationAnimationLw(mExitAnimId, mEnterAnimId, isDimming)) {
9954 mExitAnimId = mEnterAnimId = 0;
9955 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07009956 if (screenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
Craig Mautner59c00972012-07-30 12:10:24 -07009957 mTransitionAnimationScale, displayInfo.logicalWidth,
Craig Mautner3c174372013-02-21 17:54:37 -08009958 displayInfo.logicalHeight, mExitAnimId, mEnterAnimId)) {
Craig Mautner96868332012-12-04 14:29:11 -08009959 scheduleAnimationLocked();
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009960 } else {
Craig Mautnera91f9e22012-09-14 16:22:08 -07009961 screenRotationAnimation.kill();
9962 screenRotationAnimation = null;
9963 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009964 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -08009965 }
9966 } else {
Craig Mautnera91f9e22012-09-14 16:22:08 -07009967 if (screenRotationAnimation != null) {
9968 screenRotationAnimation.kill();
9969 screenRotationAnimation = null;
9970 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009971 }
9972 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -08009973 }
Romain Guy06882f82009-06-10 13:36:04 -07009974
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009975 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009976
Dianne Hackborn420829e2011-01-28 11:30:35 -08009977 boolean configChanged;
Craig Mautner0bf6ec92012-12-18 08:33:27 -08009978
Christopher Tateb696aee2010-04-02 19:08:30 -07009979 // While the display is frozen we don't re-compute the orientation
9980 // to avoid inconsistent states. However, something interesting
9981 // could have actually changed during that time so re-evaluate it
9982 // now to catch that.
Dianne Hackborn420829e2011-01-28 11:30:35 -08009983 configChanged = updateOrientationFromAppTokensLocked(false);
Christopher Tateb696aee2010-04-02 19:08:30 -07009984
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009985 // A little kludge: a lot could have happened while the
9986 // display was frozen, so now that we are coming back we
9987 // do a gc so that any remote references the system
9988 // processes holds on others can be released if they are
9989 // no longer needed.
9990 mH.removeMessages(H.FORCE_GC);
You Kimcb6291c2012-12-04 23:22:28 +09009991 mH.sendEmptyMessageDelayed(H.FORCE_GC, 2000);
Romain Guy06882f82009-06-10 13:36:04 -07009992
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009993 mScreenFrozenLock.release();
Craig Mautner6cfa7292013-01-15 09:05:42 -08009994
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009995 if (updateRotation) {
9996 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Jeff Brown01a98dd2011-09-20 15:08:29 -07009997 configChanged |= updateRotationUncheckedLocked(false);
Dianne Hackborn420829e2011-01-28 11:30:35 -08009998 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08009999
Dianne Hackborn420829e2011-01-28 11:30:35 -080010000 if (configChanged) {
10001 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackborn89ba6752011-01-23 16:51:16 -080010002 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010003 }
Romain Guy06882f82009-06-10 13:36:04 -070010004
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010005 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
10006 DisplayMetrics dm) {
10007 if (index < tokens.length) {
10008 String str = tokens[index];
10009 if (str != null && str.length() > 0) {
10010 try {
10011 int val = Integer.parseInt(str);
10012 return val;
10013 } catch (Exception e) {
10014 }
10015 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010016 }
10017 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
10018 return defDps;
10019 }
10020 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
10021 return val;
10022 }
10023
Jeff Brown4ed8fe72012-08-30 18:18:29 -070010024 void createWatermarkInTransaction() {
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010025 if (mWatermark != null) {
10026 return;
10027 }
10028
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010029 File file = new File("/system/etc/setup.conf");
10030 FileInputStream in = null;
Craig Mautner2268e7e2012-12-13 15:40:00 -080010031 DataInputStream ind = null;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010032 try {
10033 in = new FileInputStream(file);
Craig Mautner2268e7e2012-12-13 15:40:00 -080010034 ind = new DataInputStream(in);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010035 String line = ind.readLine();
10036 if (line != null) {
10037 String[] toks = line.split("%");
10038 if (toks != null && toks.length > 0) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010039 mWatermark = new Watermark(getDefaultDisplayContentLocked().getDisplay(),
Jeff Browne215f262012-09-10 16:01:14 -070010040 mRealDisplayMetrics, mFxSession, toks);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010041 }
10042 }
10043 } catch (FileNotFoundException e) {
10044 } catch (IOException e) {
10045 } finally {
Craig Mautner2268e7e2012-12-13 15:40:00 -080010046 if (ind != null) {
10047 try {
10048 ind.close();
10049 } catch (IOException e) {
10050 }
Craig Mautner0bf6ec92012-12-18 08:33:27 -080010051 } else if (in != null) {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010052 try {
10053 in.close();
10054 } catch (IOException e) {
10055 }
10056 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010057 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010058 }
10059
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010060 @Override
Joe Onorato664644d2011-01-23 17:53:23 -080010061 public void statusBarVisibilityChanged(int visibility) {
Dianne Hackborndf89e652011-10-06 22:35:11 -070010062 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
10063 != PackageManager.PERMISSION_GRANTED) {
10064 throw new SecurityException("Caller does not hold permission "
10065 + android.Manifest.permission.STATUS_BAR);
10066 }
Dianne Hackborn9a230e02011-10-06 11:51:27 -070010067
Joe Onorato664644d2011-01-23 17:53:23 -080010068 synchronized (mWindowMap) {
Dianne Hackborndf89e652011-10-06 22:35:11 -070010069 mLastStatusBarVisibility = visibility;
10070 visibility = mPolicy.adjustSystemUiVisibilityLw(visibility);
10071 updateStatusBarVisibilityLocked(visibility);
10072 }
10073 }
10074
Craig Mautner59c00972012-07-30 12:10:24 -070010075 // TOOD(multidisplay): StatusBar on multiple screens?
Dianne Hackborndf89e652011-10-06 22:35:11 -070010076 void updateStatusBarVisibilityLocked(int visibility) {
10077 mInputManager.setSystemUiVisibility(visibility);
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010078 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -070010079 final int N = windows.size();
Dianne Hackborndf89e652011-10-06 22:35:11 -070010080 for (int i = 0; i < N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -070010081 WindowState ws = windows.get(i);
Dianne Hackborndf89e652011-10-06 22:35:11 -070010082 try {
10083 int curValue = ws.mSystemUiVisibility;
10084 int diff = curValue ^ visibility;
10085 // We are only interested in differences of one of the
10086 // clearable flags...
10087 diff &= View.SYSTEM_UI_CLEARABLE_FLAGS;
10088 // ...if it has actually been cleared.
10089 diff &= ~visibility;
10090 int newValue = (curValue&~diff) | (visibility&diff);
10091 if (newValue != curValue) {
10092 ws.mSeq++;
10093 ws.mSystemUiVisibility = newValue;
10094 }
10095 if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) {
10096 ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq,
10097 visibility, newValue, diff);
10098 }
10099 } catch (RemoteException e) {
10100 // so sorry
10101 }
10102 }
10103 }
Craig Mautner6cfa7292013-01-15 09:05:42 -080010104
Dianne Hackborndf89e652011-10-06 22:35:11 -070010105 @Override
10106 public void reevaluateStatusBarVisibility() {
10107 synchronized (mWindowMap) {
10108 int visibility = mPolicy.adjustSystemUiVisibilityLw(mLastStatusBarVisibility);
10109 updateStatusBarVisibilityLocked(visibility);
10110 performLayoutAndPlaceSurfacesLocked();
10111 }
10112 }
10113
10114 @Override
Jeff Brown32cbc38552011-12-01 14:01:49 -080010115 public FakeWindow addFakeWindow(Looper looper,
10116 InputEventReceiver.Factory inputEventReceiverFactory,
Dianne Hackborndf89e652011-10-06 22:35:11 -070010117 String name, int windowType, int layoutParamsFlags, boolean canReceiveKeys,
10118 boolean hasFocus, boolean touchFullscreen) {
10119 synchronized (mWindowMap) {
Jeff Brown32cbc38552011-12-01 14:01:49 -080010120 FakeWindowImpl fw = new FakeWindowImpl(this, looper, inputEventReceiverFactory,
10121 name, windowType,
Dianne Hackborndf89e652011-10-06 22:35:11 -070010122 layoutParamsFlags, canReceiveKeys, hasFocus, touchFullscreen);
10123 int i=0;
10124 while (i<mFakeWindows.size()) {
10125 if (mFakeWindows.get(i).mWindowLayer <= fw.mWindowLayer) {
10126 break;
Joe Onorato664644d2011-01-23 17:53:23 -080010127 }
10128 }
Dianne Hackborndf89e652011-10-06 22:35:11 -070010129 mFakeWindows.add(i, fw);
10130 mInputMonitor.updateInputWindowsLw(true);
10131 return fw;
10132 }
10133 }
10134
10135 boolean removeFakeWindowLocked(FakeWindow window) {
10136 synchronized (mWindowMap) {
10137 if (mFakeWindows.remove(window)) {
10138 mInputMonitor.updateInputWindowsLw(true);
10139 return true;
10140 }
10141 return false;
Joe Onorato664644d2011-01-23 17:53:23 -080010142 }
10143 }
10144
satoke0a99412012-05-10 02:22:58 +090010145 // It is assumed that this method is called only by InputMethodManagerService.
10146 public void saveLastInputMethodWindowForTransition() {
10147 synchronized (mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -070010148 // TODO(multidisplay): Pass in the displayID.
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010149 DisplayContent displayContent = getDefaultDisplayContentLocked();
satoke0a99412012-05-10 02:22:58 +090010150 if (mInputMethodWindow != null) {
10151 mPolicy.setLastInputMethodWindowLw(mInputMethodWindow, mInputMethodTarget);
10152 }
10153 }
10154 }
10155
Daniel Sandler0c4ccff2011-10-19 16:39:14 -040010156 @Override
10157 public boolean hasNavigationBar() {
10158 return mPolicy.hasNavigationBar();
10159 }
10160
Craig Mautner96868332012-12-04 14:29:11 -080010161 @Override
Adam Cohenf7522022012-10-03 20:03:18 -070010162 public void lockNow(Bundle options) {
10163 mPolicy.lockNow(options);
Jim Miller93c518e2012-01-17 15:55:31 -080010164 }
Craig Mautner6cfa7292013-01-15 09:05:42 -080010165
Craig Mautner96868332012-12-04 14:29:11 -080010166 @Override
Jim Millerbfec0a82012-11-05 20:05:22 -080010167 public boolean isSafeModeEnabled() {
10168 return mSafeMode;
10169 }
Jim Miller93c518e2012-01-17 15:55:31 -080010170
Craig Mautner96868332012-12-04 14:29:11 -080010171 @Override
Jim Miller4eeb4f62012-11-08 00:04:29 -080010172 public void showAssistant() {
10173 // TODO: What permission?
10174 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
10175 != PackageManager.PERMISSION_GRANTED) {
10176 return;
10177 }
10178 mPolicy.showAssistant();
10179 }
10180
Jeff Brownd7a04de2012-06-17 14:17:52 -070010181 void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010182 pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010183 mPolicy.dump(" ", pw, args);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010184 }
10185
Dianne Hackborn529e7442012-11-01 14:22:28 -070010186 void dumpAnimatorLocked(PrintWriter pw, String[] args, boolean dumpAll) {
10187 pw.println("WINDOW MANAGER ANIMATOR STATE (dumpsys window animator)");
10188 mAnimator.dumpLocked(pw, " ", dumpAll);
10189 }
10190
Jeff Brownd7a04de2012-06-17 14:17:52 -070010191 void dumpTokensLocked(PrintWriter pw, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010192 pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
10193 if (mTokenMap.size() > 0) {
10194 pw.println(" All tokens:");
10195 Iterator<WindowToken> it = mTokenMap.values().iterator();
10196 while (it.hasNext()) {
10197 WindowToken token = it.next();
Dianne Hackbornef03a7f2012-10-29 18:46:52 -070010198 pw.print(" "); pw.print(token);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010199 if (dumpAll) {
10200 pw.println(':');
10201 token.dump(pw, " ");
10202 } else {
10203 pw.println();
10204 }
10205 }
10206 }
10207 if (mWallpaperTokens.size() > 0) {
10208 pw.println();
10209 pw.println(" Wallpaper tokens:");
10210 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
10211 WindowToken token = mWallpaperTokens.get(i);
10212 pw.print(" Wallpaper #"); pw.print(i);
10213 pw.print(' '); pw.print(token);
10214 if (dumpAll) {
10215 pw.println(':');
10216 token.dump(pw, " ");
10217 } else {
10218 pw.println();
10219 }
10220 }
10221 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010222 if (mFinishedStarting.size() > 0) {
10223 pw.println();
10224 pw.println(" Finishing start of application tokens:");
10225 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
10226 WindowToken token = mFinishedStarting.get(i);
10227 pw.print(" Finished Starting #"); pw.print(i);
10228 pw.print(' '); pw.print(token);
10229 if (dumpAll) {
10230 pw.println(':');
10231 token.dump(pw, " ");
10232 } else {
10233 pw.println();
10234 }
10235 }
10236 }
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010237 if (mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
10238 pw.println();
10239 if (mOpeningApps.size() > 0) {
10240 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
10241 }
10242 if (mClosingApps.size() > 0) {
10243 pw.print(" mClosingApps="); pw.println(mClosingApps);
10244 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010245 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010246 }
10247
Jeff Brownd7a04de2012-06-17 14:17:52 -070010248 void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010249 pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
10250 if (mSessions.size() > 0) {
10251 Iterator<Session> it = mSessions.iterator();
10252 while (it.hasNext()) {
10253 Session s = it.next();
10254 pw.print(" Session "); pw.print(s); pw.println(':');
10255 s.dump(pw, " ");
10256 }
10257 }
10258 }
10259
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010260 void dumpDisplayContentsLocked(PrintWriter pw, boolean dumpAll) {
10261 pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)");
10262 if (mDisplayReady) {
Craig Mautnerf8924152013-07-16 09:10:55 -070010263 final int numDisplays = mDisplayContents.size();
10264 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10265 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
10266 displayContent.dump(" ", pw);
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010267 }
10268 } else {
10269 pw.println(" NO DISPLAY");
10270 }
10271 }
10272
Jeff Brownd7a04de2012-06-17 14:17:52 -070010273 void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010274 ArrayList<WindowState> windows) {
10275 pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010276 dumpWindowsNoHeaderLocked(pw, dumpAll, windows);
10277 }
10278
10279 void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll,
10280 ArrayList<WindowState> windows) {
Craig Mautner59c00972012-07-30 12:10:24 -070010281 int j = 0;
Craig Mautnerf8924152013-07-16 09:10:55 -070010282 final int numDisplays = mDisplayContents.size();
10283 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10284 final WindowList windowList = mDisplayContents.valueAt(displayNdx).getWindowList();
10285 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
10286 final WindowState w = windowList.get(winNdx);
10287 if (windows == null || windows.contains(w)) {
10288 pw.print(" Window #"); pw.print(j++); pw.print(' ');
10289 pw.print(w); pw.println(":");
10290 w.dump(pw, " ", dumpAll || windows != null);
10291 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010292 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010293 }
10294 if (mInputMethodDialogs.size() > 0) {
10295 pw.println();
10296 pw.println(" Input method dialogs:");
10297 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
10298 WindowState w = mInputMethodDialogs.get(i);
10299 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010300 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010301 }
10302 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010303 }
10304 if (mPendingRemove.size() > 0) {
10305 pw.println();
10306 pw.println(" Remove pending for:");
10307 for (int i=mPendingRemove.size()-1; i>=0; i--) {
10308 WindowState w = mPendingRemove.get(i);
10309 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010310 pw.print(" Remove #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010311 pw.print(w);
10312 if (dumpAll) {
10313 pw.println(":");
10314 w.dump(pw, " ", true);
10315 } else {
10316 pw.println();
10317 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010318 }
10319 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010320 }
10321 if (mForceRemoves != null && mForceRemoves.size() > 0) {
10322 pw.println();
10323 pw.println(" Windows force removing:");
10324 for (int i=mForceRemoves.size()-1; i>=0; i--) {
10325 WindowState w = mForceRemoves.get(i);
10326 pw.print(" Removing #"); pw.print(i); pw.print(' ');
10327 pw.print(w);
10328 if (dumpAll) {
10329 pw.println(":");
10330 w.dump(pw, " ", true);
10331 } else {
10332 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010333 }
10334 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010335 }
10336 if (mDestroySurface.size() > 0) {
10337 pw.println();
10338 pw.println(" Windows waiting to destroy their surface:");
10339 for (int i=mDestroySurface.size()-1; i>=0; i--) {
10340 WindowState w = mDestroySurface.get(i);
10341 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010342 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010343 pw.print(w);
10344 if (dumpAll) {
10345 pw.println(":");
10346 w.dump(pw, " ", true);
10347 } else {
10348 pw.println();
10349 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010350 }
10351 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010352 }
10353 if (mLosingFocus.size() > 0) {
10354 pw.println();
10355 pw.println(" Windows losing focus:");
10356 for (int i=mLosingFocus.size()-1; i>=0; i--) {
10357 WindowState w = mLosingFocus.get(i);
10358 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010359 pw.print(" Losing #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010360 pw.print(w);
10361 if (dumpAll) {
10362 pw.println(":");
10363 w.dump(pw, " ", true);
10364 } else {
10365 pw.println();
10366 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010367 }
10368 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010369 }
10370 if (mResizingWindows.size() > 0) {
10371 pw.println();
10372 pw.println(" Windows waiting to resize:");
10373 for (int i=mResizingWindows.size()-1; i>=0; i--) {
10374 WindowState w = mResizingWindows.get(i);
10375 if (windows == null || windows.contains(w)) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010376 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010377 pw.print(w);
10378 if (dumpAll) {
10379 pw.println(":");
10380 w.dump(pw, " ", true);
10381 } else {
10382 pw.println();
10383 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010384 }
10385 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010386 }
Dianne Hackborn38e29a62011-09-18 14:43:08 -070010387 if (mWaitingForDrawn.size() > 0) {
10388 pw.println();
10389 pw.println(" Clients waiting for these windows to be drawn:");
10390 for (int i=mWaitingForDrawn.size()-1; i>=0; i--) {
10391 Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(i);
10392 pw.print(" Waiting #"); pw.print(i); pw.print(' '); pw.print(pair.first);
10393 pw.print(": "); pw.println(pair.second);
10394 }
10395 }
Dianne Hackborn77119bc2012-10-23 14:32:48 -070010396 pw.println();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010397 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
10398 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
10399 if (mLastFocus != mCurrentFocus) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010400 pw.print(" mLastFocus="); pw.println(mLastFocus);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010401 }
10402 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
10403 if (mInputMethodTarget != null) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010404 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010405 }
10406 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
10407 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborna57c6952013-03-29 14:46:40 -070010408 pw.print(" mLastDisplayFreezeDuration=");
10409 TimeUtils.formatDuration(mLastDisplayFreezeDuration, pw);
10410 if ( mLastFinishedFreezeSource != null) {
10411 pw.print(" due to ");
10412 pw.print(mLastFinishedFreezeSource);
10413 }
10414 pw.println();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010415 if (dumpAll) {
Dianne Hackborn85afd1b2012-05-13 13:31:06 -070010416 pw.print(" mSystemDecorRect="); pw.print(mSystemDecorRect.toShortString());
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070010417 pw.print(" mSystemDecorLayer="); pw.print(mSystemDecorLayer);
Dianne Hackbornc652de82013-02-15 16:32:56 -080010418 pw.print(" mScreenRect="); pw.println(mScreenRect.toShortString());
Dianne Hackborndf89e652011-10-06 22:35:11 -070010419 if (mLastStatusBarVisibility != 0) {
10420 pw.print(" mLastStatusBarVisibility=0x");
10421 pw.println(Integer.toHexString(mLastStatusBarVisibility));
10422 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010423 if (mInputMethodWindow != null) {
10424 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
10425 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -070010426 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn529e7442012-11-01 14:22:28 -070010427 if (mLowerWallpaperTarget != null || mUpperWallpaperTarget != null) {
Dianne Hackborn284ac932009-08-28 10:34:25 -070010428 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
10429 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
10430 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010431 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
10432 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
10433 if (mInputMethodAnimLayerAdjustment != 0 ||
10434 mWallpaperAnimLayerAdjustment != 0) {
10435 pw.print(" mInputMethodAnimLayerAdjustment=");
10436 pw.print(mInputMethodAnimLayerAdjustment);
10437 pw.print(" mWallpaperAnimLayerAdjustment=");
10438 pw.println(mWallpaperAnimLayerAdjustment);
10439 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010440 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
10441 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
Craig Mautner19d59bc2012-09-04 11:15:56 -070010442 if (needsLayout()) {
10443 pw.print(" layoutNeeded on displays=");
Craig Mautnerf8924152013-07-16 09:10:55 -070010444 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10445 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautner19d59bc2012-09-04 11:15:56 -070010446 if (displayContent.layoutNeeded) {
10447 pw.print(displayContent.getDisplayId());
10448 }
10449 }
10450 pw.println();
10451 }
Craig Mautner69b08182012-09-05 13:07:13 -070010452 pw.print(" mTransactionSequence="); pw.println(mTransactionSequence);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010453 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -070010454 pw.print(" windows="); pw.print(mWindowsFreezingScreen);
10455 pw.print(" client="); pw.print(mClientFreezingScreen);
10456 pw.print(" apps="); pw.print(mAppsFreezingScreen);
10457 pw.print(" waitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010458 pw.print(" mRotation="); pw.print(mRotation);
Dianne Hackborndacea8c2011-04-21 17:26:39 -070010459 pw.print(" mAltOrientation="); pw.println(mAltOrientation);
Craig Mautnerf20588f2012-04-11 17:06:21 -070010460 pw.print(" mLastWindowForcedOrientation="); pw.print(mLastWindowForcedOrientation);
Dianne Hackbornbc7386c2011-06-06 17:27:54 -070010461 pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation);
Jeff Brown01a98dd2011-09-20 15:08:29 -070010462 pw.print(" mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
Dianne Hackborn4dcece82012-02-10 14:50:32 -080010463 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
10464 pw.print(" mTransitionWindowAnimationScale="); pw.print(mTransitionAnimationScale);
Chet Haasec38fa1f2012-02-01 16:37:46 -080010465 pw.print(" mAnimatorDurationScale="); pw.println(mAnimatorDurationScale);
Craig Mautner164d4bb2012-11-26 13:51:23 -080010466 pw.print(" mTraversalScheduled="); pw.println(mTraversalScheduled);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010467 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010468 pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Dianne Hackborn529e7442012-11-01 14:22:28 -070010469 pw.println(" mLayoutToAnim:");
Craig Mautner164d4bb2012-11-26 13:51:23 -080010470 mAppTransition.dump(pw);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010471 }
10472 }
10473
Jeff Brownd7a04de2012-06-17 14:17:52 -070010474 boolean dumpWindows(PrintWriter pw, String name, String[] args,
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010475 int opti, boolean dumpAll) {
Craig Mautner722285e2012-09-07 13:55:58 -070010476 WindowList windows = new WindowList();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010477 if ("visible".equals(name)) {
10478 synchronized(mWindowMap) {
Craig Mautnerf8924152013-07-16 09:10:55 -070010479 final int numDisplays = mDisplayContents.size();
10480 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10481 final WindowList windowList =
10482 mDisplayContents.valueAt(displayNdx).getWindowList();
10483 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
10484 final WindowState w = windowList.get(winNdx);
10485 if (w.mWinAnimator.mSurfaceShown) {
10486 windows.add(w);
10487 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010488 }
10489 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010490 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010491 } else {
10492 int objectId = 0;
10493 // See if this is an object ID.
10494 try {
10495 objectId = Integer.parseInt(name, 16);
10496 name = null;
10497 } catch (RuntimeException e) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010498 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010499 synchronized(mWindowMap) {
Craig Mautnerf8924152013-07-16 09:10:55 -070010500 final int numDisplays = mDisplayContents.size();
10501 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10502 final WindowList windowList =
10503 mDisplayContents.valueAt(displayNdx).getWindowList();
10504 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
10505 final WindowState w = windowList.get(winNdx);
10506 if (name != null) {
10507 if (w.mAttrs.getTitle().toString().contains(name)) {
10508 windows.add(w);
10509 }
10510 } else if (System.identityHashCode(w) == objectId) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010511 windows.add(w);
10512 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010513 }
10514 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010515 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010516 }
10517
10518 if (windows.size() <= 0) {
10519 return false;
10520 }
10521
10522 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010523 dumpWindowsLocked(pw, dumpAll, windows);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010524 }
10525 return true;
10526 }
10527
Jeff Brownd7a04de2012-06-17 14:17:52 -070010528 void dumpLastANRLocked(PrintWriter pw) {
10529 pw.println("WINDOW MANAGER LAST ANR (dumpsys window lastanr)");
10530 if (mLastANRState == null) {
10531 pw.println(" <no ANR has occurred since boot>");
10532 } else {
10533 pw.println(mLastANRState);
10534 }
10535 }
10536
10537 /**
10538 * Saves information about the state of the window manager at
10539 * the time an ANR occurred before anything else in the system changes
10540 * in response.
10541 *
Jeff Brownee172412012-06-18 12:58:03 -070010542 * @param appWindowToken The application that ANR'd, may be null.
Jeff Brownd7a04de2012-06-17 14:17:52 -070010543 * @param windowState The window that ANR'd, may be null.
10544 */
10545 public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState) {
10546 StringWriter sw = new StringWriter();
Dianne Hackborn8c841092013-06-24 13:46:13 -070010547 PrintWriter pw = new FastPrintWriter(sw, false, 1024);
Jeff Brownd7a04de2012-06-17 14:17:52 -070010548 pw.println(" ANR time: " + DateFormat.getInstance().format(new Date()));
Jeff Brownee172412012-06-18 12:58:03 -070010549 if (appWindowToken != null) {
10550 pw.println(" Application at fault: " + appWindowToken.stringName);
10551 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010552 if (windowState != null) {
10553 pw.println(" Window at fault: " + windowState.mAttrs.getTitle());
10554 }
10555 pw.println();
10556 dumpWindowsNoHeaderLocked(pw, true, null);
10557 pw.close();
10558 mLastANRState = sw.toString();
10559 }
10560
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010561 @Override
10562 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10563 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
10564 != PackageManager.PERMISSION_GRANTED) {
10565 pw.println("Permission Denial: can't dump WindowManager from from pid="
10566 + Binder.getCallingPid()
10567 + ", uid=" + Binder.getCallingUid());
10568 return;
10569 }
10570
10571 boolean dumpAll = false;
10572
10573 int opti = 0;
10574 while (opti < args.length) {
10575 String opt = args[opti];
10576 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10577 break;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010578 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010579 opti++;
10580 if ("-a".equals(opt)) {
10581 dumpAll = true;
10582 } else if ("-h".equals(opt)) {
10583 pw.println("Window manager dump options:");
10584 pw.println(" [-a] [-h] [cmd] ...");
10585 pw.println(" cmd may be one of:");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010586 pw.println(" l[astanr]: last ANR information");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010587 pw.println(" p[policy]: policy state");
Dianne Hackborn529e7442012-11-01 14:22:28 -070010588 pw.println(" a[animator]: animator state");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010589 pw.println(" s[essions]: active sessions");
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010590 pw.println(" d[isplays]: active display contents");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010591 pw.println(" t[okens]: token list");
10592 pw.println(" w[indows]: window list");
10593 pw.println(" cmd may also be a NAME to dump windows. NAME may");
10594 pw.println(" be a partial substring in a window name, a");
10595 pw.println(" Window hex object identifier, or");
10596 pw.println(" \"all\" for all windows, or");
10597 pw.println(" \"visible\" for the visible windows.");
10598 pw.println(" -a: include all available server state.");
10599 return;
Dianne Hackborn87fc3082010-12-03 13:09:12 -080010600 } else {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010601 pw.println("Unknown argument: " + opt + "; use -h for help");
Dianne Hackborn87fc3082010-12-03 13:09:12 -080010602 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010603 }
10604
10605 // Is the caller requesting to dump a particular piece of data?
10606 if (opti < args.length) {
10607 String cmd = args[opti];
10608 opti++;
Jeff Brownd7a04de2012-06-17 14:17:52 -070010609 if ("lastanr".equals(cmd) || "l".equals(cmd)) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010610 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010611 dumpLastANRLocked(pw);
10612 }
10613 return;
10614 } else if ("policy".equals(cmd) || "p".equals(cmd)) {
10615 synchronized(mWindowMap) {
10616 dumpPolicyLocked(pw, args, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010617 }
10618 return;
Dianne Hackborn529e7442012-11-01 14:22:28 -070010619 } else if ("animator".equals(cmd) || "a".equals(cmd)) {
10620 synchronized(mWindowMap) {
10621 dumpAnimatorLocked(pw, args, true);
10622 }
10623 return;
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010624 } else if ("sessions".equals(cmd) || "s".equals(cmd)) {
10625 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010626 dumpSessionsLocked(pw, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010627 }
10628 return;
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010629 } else if ("displays".equals(cmd) || "d".equals(cmd)) {
10630 synchronized(mWindowMap) {
10631 dumpDisplayContentsLocked(pw, true);
10632 }
10633 return;
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010634 } else if ("tokens".equals(cmd) || "t".equals(cmd)) {
10635 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010636 dumpTokensLocked(pw, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010637 }
10638 return;
10639 } else if ("windows".equals(cmd) || "w".equals(cmd)) {
10640 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010641 dumpWindowsLocked(pw, true, null);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010642 }
10643 return;
10644 } else if ("all".equals(cmd) || "a".equals(cmd)) {
10645 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010646 dumpWindowsLocked(pw, true, null);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010647 }
10648 return;
10649 } else {
10650 // Dumping a single name?
Jeff Brownd7a04de2012-06-17 14:17:52 -070010651 if (!dumpWindows(pw, cmd, args, opti, dumpAll)) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010652 pw.println("Bad window command, or no windows match: " + cmd);
10653 pw.println("Use -h for help.");
10654 }
10655 return;
10656 }
10657 }
10658
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010659 synchronized(mWindowMap) {
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010660 pw.println();
10661 if (dumpAll) {
10662 pw.println("-------------------------------------------------------------------------------");
10663 }
10664 dumpLastANRLocked(pw);
10665 pw.println();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010666 if (dumpAll) {
10667 pw.println("-------------------------------------------------------------------------------");
10668 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010669 dumpPolicyLocked(pw, args, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010670 pw.println();
10671 if (dumpAll) {
10672 pw.println("-------------------------------------------------------------------------------");
10673 }
Dianne Hackborn529e7442012-11-01 14:22:28 -070010674 dumpAnimatorLocked(pw, args, dumpAll);
10675 pw.println();
10676 if (dumpAll) {
10677 pw.println("-------------------------------------------------------------------------------");
10678 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010679 dumpSessionsLocked(pw, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010680 pw.println();
10681 if (dumpAll) {
10682 pw.println("-------------------------------------------------------------------------------");
10683 }
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010684 dumpDisplayContentsLocked(pw, dumpAll);
10685 pw.println();
10686 if (dumpAll) {
10687 pw.println("-------------------------------------------------------------------------------");
10688 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010689 dumpTokensLocked(pw, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010690 pw.println();
10691 if (dumpAll) {
10692 pw.println("-------------------------------------------------------------------------------");
10693 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010694 dumpWindowsLocked(pw, dumpAll, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010695 }
10696 }
10697
Jeff Brown349703e2010-06-22 01:27:15 -070010698 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
Craig Mautner96868332012-12-04 14:29:11 -080010699 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010700 public void monitor() {
10701 synchronized (mWindowMap) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070010702 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010703
Jeff Brown2992ea72011-01-28 22:04:14 -080010704 public interface OnHardKeyboardStatusChangeListener {
10705 public void onHardKeyboardStatusChange(boolean available, boolean enabled);
10706 }
Craig Mautnera2c77052012-03-26 12:14:43 -070010707
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070010708 void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
Craig Mautnercf8cbbe2012-03-25 21:54:36 -070010709 if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070010710 Slog.v(TAG, "Layouts looping: " + msg + ", mPendingLayoutChanges = 0x" +
10711 Integer.toHexString(pendingLayoutChanges));
Craig Mautnercf8cbbe2012-03-25 21:54:36 -070010712 }
10713 }
Craig Mautner59c00972012-07-30 12:10:24 -070010714
Dianne Hackbornc652de82013-02-15 16:32:56 -080010715 private DisplayContent newDisplayContentLocked(final Display display) {
10716 DisplayContent displayContent = new DisplayContent(display);
Craig Mautnercf910b02013-04-23 11:23:27 -070010717 final int displayId = display.getDisplayId();
10718 mDisplayContents.put(displayId, displayContent);
Dianne Hackbornc652de82013-02-15 16:32:56 -080010719 final Rect rect = new Rect();
10720 DisplayInfo info = displayContent.getDisplayInfo();
10721 mDisplaySettings.getOverscanLocked(info.name, rect);
10722 info.overscanLeft = rect.left;
10723 info.overscanTop = rect.top;
10724 info.overscanRight = rect.right;
10725 info.overscanBottom = rect.bottom;
10726 mDisplayManagerService.setOverscan(display.getDisplayId(), rect.left, rect.top,
10727 rect.right, rect.bottom);
10728 mPolicy.setDisplayOverscan(displayContent.getDisplay(), rect.left, rect.top,
10729 rect.right, rect.bottom);
Craig Mautnercf910b02013-04-23 11:23:27 -070010730
10731 // TODO: Create an input channel for each display with touch capability.
10732 if (displayId == Display.DEFAULT_DISPLAY) {
Craig Mautner037aa8d2013-06-07 10:35:44 -070010733 displayContent.mTapDetector = new StackTapPointerEventListener(this, displayContent);
10734 registerPointerEventListener(displayContent.mTapDetector);
Craig Mautnercf910b02013-04-23 11:23:27 -070010735 }
10736
Dianne Hackbornc652de82013-02-15 16:32:56 -080010737 return displayContent;
10738 }
10739
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010740 public void createDisplayContentLocked(final Display display) {
Craig Mautner722285e2012-09-07 13:55:58 -070010741 if (display == null) {
10742 throw new IllegalArgumentException("getDisplayContent: display must not be null");
10743 }
Dianne Hackbornc652de82013-02-15 16:32:56 -080010744 newDisplayContentLocked(display);
Craig Mautner722285e2012-09-07 13:55:58 -070010745 }
10746
Craig Mautner2d5618c2012-10-18 13:55:47 -070010747 /**
10748 * Retrieve the DisplayContent for the specified displayId. Will create a new DisplayContent if
10749 * there is a Display for the displayId.
10750 * @param displayId The display the caller is interested in.
10751 * @return The DisplayContent associated with displayId or null if there is no Display for it.
10752 */
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010753 public DisplayContent getDisplayContentLocked(final int displayId) {
Craig Mautner59c00972012-07-30 12:10:24 -070010754 DisplayContent displayContent = mDisplayContents.get(displayId);
10755 if (displayContent == null) {
Craig Mautner2d5618c2012-10-18 13:55:47 -070010756 final Display display = mDisplayManager.getDisplay(displayId);
10757 if (display != null) {
Dianne Hackbornc652de82013-02-15 16:32:56 -080010758 displayContent = newDisplayContentLocked(display);
Craig Mautner2d5618c2012-10-18 13:55:47 -070010759 }
Craig Mautner59c00972012-07-30 12:10:24 -070010760 }
10761 return displayContent;
10762 }
10763
Craig Mautner2d5618c2012-10-18 13:55:47 -070010764 // There is an inherent assumption that this will never return null.
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010765 public DisplayContent getDefaultDisplayContentLocked() {
10766 return getDisplayContentLocked(Display.DEFAULT_DISPLAY);
Craig Mautner59c00972012-07-30 12:10:24 -070010767 }
10768
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010769 public WindowList getDefaultWindowListLocked() {
10770 return getDefaultDisplayContentLocked().getWindowList();
Craig Mautner59c00972012-07-30 12:10:24 -070010771 }
10772
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010773 public DisplayInfo getDefaultDisplayInfoLocked() {
10774 return getDefaultDisplayContentLocked().getDisplayInfo();
Craig Mautner59c00972012-07-30 12:10:24 -070010775 }
10776
Craig Mautner2d5618c2012-10-18 13:55:47 -070010777 /**
10778 * Return the list of WindowStates associated on the passed display.
10779 * @param display The screen to return windows from.
10780 * @return The list of WindowStates on the screen, or null if the there is no screen.
10781 */
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010782 public WindowList getWindowListLocked(final Display display) {
Craig Mautner96868332012-12-04 14:29:11 -080010783 return getWindowListLocked(display.getDisplayId());
10784 }
10785
10786 /**
10787 * Return the list of WindowStates associated on the passed display.
10788 * @param displayId The screen to return windows from.
10789 * @return The list of WindowStates on the screen, or null if the there is no screen.
10790 */
10791 public WindowList getWindowListLocked(final int displayId) {
10792 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -070010793 return displayContent != null ? displayContent.getWindowList() : null;
Craig Mautner39834192012-09-02 07:47:24 -070010794 }
Craig Mautner722285e2012-09-07 13:55:58 -070010795
10796 @Override
10797 public void onDisplayAdded(int displayId) {
10798 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_ADDED, displayId, 0));
10799 }
10800
10801 private void handleDisplayAddedLocked(int displayId) {
Craig Mautner2d5618c2012-10-18 13:55:47 -070010802 final Display display = mDisplayManager.getDisplay(displayId);
10803 if (display != null) {
10804 createDisplayContentLocked(display);
10805 displayReady(displayId);
10806 }
Craig Mautner722285e2012-09-07 13:55:58 -070010807 }
10808
10809 @Override
10810 public void onDisplayRemoved(int displayId) {
10811 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_REMOVED, displayId, 0));
10812 }
10813
10814 private void handleDisplayRemovedLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010815 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -070010816 if (displayContent != null) {
10817 mDisplayContents.delete(displayId);
Andreas Huberb551c6d2013-04-26 11:54:53 -070010818
Craig Mautner037aa8d2013-06-07 10:35:44 -070010819 if (displayId == Display.DEFAULT_DISPLAY) {
10820 unregisterPointerEventListener(displayContent.mTapDetector);
Andreas Huberb551c6d2013-04-26 11:54:53 -070010821 }
Craig Mautner2d5618c2012-10-18 13:55:47 -070010822 WindowList windows = displayContent.getWindowList();
10823 while (!windows.isEmpty()) {
10824 final WindowState win = windows.get(windows.size() - 1);
10825 removeWindowLocked(win.mSession, win);
10826 }
Craig Mautner722285e2012-09-07 13:55:58 -070010827 }
Craig Mautnera91f9e22012-09-14 16:22:08 -070010828 mAnimator.removeDisplayLocked(displayId);
Craig Mautner722285e2012-09-07 13:55:58 -070010829 }
10830
10831 @Override
10832 public void onDisplayChanged(int displayId) {
10833 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_CHANGED, displayId, 0));
10834 }
10835
10836 private void handleDisplayChangedLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010837 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner722285e2012-09-07 13:55:58 -070010838 if (displayContent != null) {
10839 displayContent.updateDisplayInfo();
10840 }
10841 }
John Spurlock04db1762013-05-13 12:46:41 -040010842
10843 @Override
10844 public Object getWindowManagerLock() {
10845 return mWindowMap;
10846 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010847}