blob: 0755281cabbf7d50e57cb032280127b619f82c2b [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080017package com.android.server.wm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080019import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
20import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
Craig Mautner65d11b32012-10-01 13:59:52 -070021import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Dianne Hackborn5fd21692011-06-07 14:09:47 -070022import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
24import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070026import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
28import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
Craig Mautner65d11b32012-10-01 13:59:52 -070029import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
31import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Craig Mautner65d11b32012-10-01 13:59:52 -070032import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
Daniel Sandler7d276c32012-01-30 14:33:52 -050033import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
35import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
Craig Mautner65d11b32012-10-01 13:59:52 -070036import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD;
Craig Mautner88400d32012-09-30 12:35:45 -070037import static android.view.WindowManager.LayoutParams.TYPE_RECENTS_OVERLAY;
Craig Mautner65d11b32012-10-01 13:59:52 -070038import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
39import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070040import static android.view.WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070041import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042
Craig Mautnerae446592012-12-06 19:05:05 -080043import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
44
Dianne Hackbornc2293022013-02-06 23:14:49 -080045import android.app.AppOpsManager;
Dianne Hackborna57c6952013-03-29 14:46:40 -070046import android.util.TimeUtils;
Dianne Hackborne3f23a32013-03-01 13:25:35 -080047import android.view.IWindowId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import com.android.internal.app.IBatteryStats;
49import com.android.internal.policy.PolicyManager;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080050import com.android.internal.policy.impl.PhoneWindowManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import com.android.internal.view.IInputContext;
52import com.android.internal.view.IInputMethodClient;
53import com.android.internal.view.IInputMethodManager;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080054import com.android.internal.view.WindowManagerPolicyThread;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080055import com.android.server.AttributeCache;
56import com.android.server.EventLogTags;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080057import com.android.server.Watchdog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import com.android.server.am.BatteryStatsService;
Jeff Brownfa25bf52012-07-23 19:26:30 -070059import com.android.server.display.DisplayManagerService;
Jeff Brown4532e612012-04-05 14:27:12 -070060import com.android.server.input.InputManagerService;
Jeff Brown4f8ecd82012-06-18 18:29:13 -070061import com.android.server.power.PowerManagerService;
62import com.android.server.power.ShutdownThread;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063
64import android.Manifest;
65import android.app.ActivityManagerNative;
66import android.app.IActivityManager;
Joe Onoratoac0ee892011-01-30 15:38:30 -080067import android.app.StatusBarManager;
Jim Millerd6b57052010-06-07 17:52:42 -070068import android.app.admin.DevicePolicyManager;
Jeff Brownff7e6ef2012-08-15 02:05:18 -070069import android.animation.ValueAnimator;
Jim Miller284b62e2010-06-08 14:27:42 -070070import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071import android.content.Context;
Jim Miller284b62e2010-06-08 14:27:42 -070072import android.content.Intent;
73import android.content.IntentFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074import android.content.pm.ActivityInfo;
75import android.content.pm.PackageManager;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070076import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077import android.content.res.Configuration;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080078import android.graphics.Bitmap;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070079import android.graphics.Canvas;
Craig Mautner24d887472013-03-20 15:40:36 -070080import android.graphics.Color;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.graphics.Matrix;
82import android.graphics.PixelFormat;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -070083import android.graphics.Point;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import android.graphics.Rect;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070085import android.graphics.RectF;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086import android.graphics.Region;
Craig Mautnerb47bbc32012-08-22 17:41:48 -070087import android.hardware.display.DisplayManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088import android.os.Binder;
Dianne Hackborn75804932009-10-20 20:15:20 -070089import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.os.Debug;
91import android.os.Handler;
92import android.os.IBinder;
Dianne Hackborn38e29a62011-09-18 14:43:08 -070093import android.os.IRemoteCallback;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094import android.os.Looper;
95import android.os.Message;
96import android.os.Parcel;
97import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098import android.os.PowerManager;
99import android.os.Process;
100import android.os.RemoteException;
101import android.os.ServiceManager;
Brad Fitzpatrickec062f62010-11-03 09:56:54 -0700102import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103import android.os.SystemClock;
104import android.os.SystemProperties;
Dianne Hackborn1ded0b12012-04-26 14:14:50 -0700105import android.os.Trace;
Craig Mautner259328c2012-08-21 19:30:58 -0700106import android.os.WorkSource;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import android.provider.Settings;
Dianne Hackborn723738c2009-06-25 19:48:04 -0700108import android.util.DisplayMetrics;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109import android.util.EventLog;
Michael Jurka4accb6a2012-03-26 09:18:46 -0700110import android.util.FloatMath;
Jim Millerd6b57052010-06-07 17:52:42 -0700111import android.util.Log;
Craig Mautner59c00972012-07-30 12:10:24 -0700112import android.util.SparseArray;
Dianne Hackborn38e29a62011-09-18 14:43:08 -0700113import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800114import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115import android.util.SparseIntArray;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700116import android.util.TypedValue;
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800117import android.view.Choreographer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118import android.view.Display;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700119import android.view.DisplayInfo;
Adam Powelldfee59a2011-08-05 20:48:30 -0700120import android.view.Gravity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121import android.view.IApplicationToken;
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -0700122import android.view.IInputFilter;
Svetoslav Ganov545252f2012-12-10 18:29:24 -0800123import android.view.IMagnificationCallbacks;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124import android.view.IOnKeyguardExitResult;
125import android.view.IRotationWatcher;
126import android.view.IWindow;
127import android.view.IWindowManager;
128import android.view.IWindowSession;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700129import android.view.InputChannel;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700130import android.view.InputDevice;
Jeff Brownbbda99d2010-07-28 15:48:59 -0700131import android.view.InputEvent;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800132import android.view.InputEventReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133import android.view.KeyEvent;
Svetoslav Ganov545252f2012-12-10 18:29:24 -0800134import android.view.MagnificationSpec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135import android.view.MotionEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136import android.view.Surface;
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800137import android.view.SurfaceControl;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138import android.view.SurfaceSession;
139import android.view.View;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700140import android.view.ViewTreeObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141import android.view.WindowManager;
Jeff Brown98365d72012-08-19 20:30:52 -0700142import android.view.WindowManagerGlobal;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143import android.view.WindowManagerPolicy;
144import android.view.WindowManager.LayoutParams;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700145import android.view.WindowManagerPolicy.FakeWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146import android.view.animation.Animation;
147import android.view.animation.AnimationUtils;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700148import android.view.animation.Transformation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149
150import java.io.BufferedWriter;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700151import java.io.DataInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152import java.io.File;
153import java.io.FileDescriptor;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700154import java.io.FileInputStream;
155import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156import java.io.IOException;
157import java.io.OutputStream;
158import java.io.OutputStreamWriter;
159import java.io.PrintWriter;
160import java.io.StringWriter;
161import java.net.Socket;
Jeff Brownd7a04de2012-06-17 14:17:52 -0700162import java.text.DateFormat;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163import java.util.ArrayList;
Jeff Brownd7a04de2012-06-17 14:17:52 -0700164import java.util.Date;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165import java.util.HashMap;
166import java.util.HashSet;
167import java.util.Iterator;
168import java.util.List;
Craig Mautner59c00972012-07-30 12:10:24 -0700169import java.util.NoSuchElementException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170
171/** {@hide} */
Dianne Hackbornddca3ee2009-07-23 19:01:31 -0700172public class WindowManagerService extends IWindowManager.Stub
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700173 implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs,
Craig Mautner722285e2012-09-07 13:55:58 -0700174 DisplayManagerService.WindowManagerFuncs, DisplayManager.DisplayListener {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175 static final String TAG = "WindowManager";
176 static final boolean DEBUG = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700177 static final boolean DEBUG_ADD_REMOVE = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800178 static final boolean DEBUG_FOCUS = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179 static final boolean DEBUG_ANIM = false;
Dianne Hackborn9b52a212009-12-11 14:51:35 -0800180 static final boolean DEBUG_LAYOUT = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800181 static final boolean DEBUG_RESIZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 static final boolean DEBUG_LAYERS = false;
183 static final boolean DEBUG_INPUT = false;
184 static final boolean DEBUG_INPUT_METHOD = false;
185 static final boolean DEBUG_VISIBILITY = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700186 static final boolean DEBUG_WINDOW_MOVEMENT = false;
Craig Mautner2ad92072013-02-25 16:19:24 -0800187 static final boolean DEBUG_TOKEN_MOVEMENT = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188 static final boolean DEBUG_ORIENTATION = false;
Dianne Hackbornbc7386c2011-06-06 17:27:54 -0700189 static final boolean DEBUG_APP_ORIENTATION = false;
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700190 static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800191 static final boolean DEBUG_APP_TRANSITIONS = false;
192 static final boolean DEBUG_STARTING_WINDOW = false;
193 static final boolean DEBUG_REORDER = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800194 static final boolean DEBUG_WALLPAPER = false;
Dianne Hackborn98129732012-11-01 16:28:16 -0700195 static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER;
Christopher Tate994ef922011-01-12 20:06:07 -0800196 static final boolean DEBUG_DRAG = false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700197 static final boolean DEBUG_SCREEN_ON = false;
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -0700198 static final boolean DEBUG_SCREENSHOT = false;
Dianne Hackborn38cc8962011-10-13 11:33:55 -0700199 static final boolean DEBUG_BOOT = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700200 static final boolean DEBUG_LAYOUT_REPEATS = true;
Craig Mautner7358fbf2012-04-12 21:06:33 -0700201 static final boolean DEBUG_SURFACE_TRACE = false;
Craig Mautner7d8df392012-04-06 15:26:23 -0700202 static final boolean DEBUG_WINDOW_TRACE = false;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700203 static final boolean SHOW_SURFACE_ALLOC = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800204 static final boolean SHOW_TRANSACTIONS = false;
Dianne Hackborn36991742011-10-11 21:35:26 -0700205 static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700206 static final boolean HIDE_STACK_CRAWLS = true;
Craig Mautnercf8cbbe2012-03-25 21:54:36 -0700207 static final int LAYOUT_REPEAT_THRESHOLD = 4;
Michael Chan53071d62009-05-13 17:29:48 -0700208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 static final boolean PROFILE_ORIENTATION = false;
Dave Bortcfe65242009-04-09 14:51:04 -0700210 static final boolean localLOGV = DEBUG;
Romain Guy06882f82009-06-10 13:36:04 -0700211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 /** How much to multiply the policy's type layer, to reserve room
213 * for multiple windows of the same type and Z-ordering adjustment
214 * with TYPE_LAYER_OFFSET. */
215 static final int TYPE_LAYER_MULTIPLIER = 10000;
Romain Guy06882f82009-06-10 13:36:04 -0700216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
218 * or below others in the same layer. */
219 static final int TYPE_LAYER_OFFSET = 1000;
Romain Guy06882f82009-06-10 13:36:04 -0700220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 /** How much to increment the layer for each window, to reserve room
222 * for effect surfaces between them.
223 */
224 static final int WINDOW_LAYER_MULTIPLIER = 5;
Romain Guy06882f82009-06-10 13:36:04 -0700225
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800226 /**
227 * Dim surface layer is immediately below target window.
228 */
229 static final int LAYER_OFFSET_DIM = 1;
230
231 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700232 * Blur surface layer is immediately below dim layer.
233 */
234 static final int LAYER_OFFSET_BLUR = 2;
235
236 /**
237 * Animation thumbnail is as far as possible below the window above
238 * the thumbnail (or in other words as far as possible above the window
239 * below it).
240 */
241 static final int LAYER_OFFSET_THUMBNAIL = WINDOW_LAYER_MULTIPLIER-1;
242
243 /**
Dianne Hackborn7916ac62011-05-16 20:45:48 -0700244 * Layer at which to put the rotation freeze snapshot.
245 */
246 static final int FREEZE_LAYER = (TYPE_LAYER_MULTIPLIER * 200) + 1;
247
248 /**
249 * Layer at which to put the mask for emulated screen sizes.
250 */
251 static final int MASK_LAYER = TYPE_LAYER_MULTIPLIER * 200;
252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 /** The maximum length we will accept for a loaded animation duration:
254 * this is 10 seconds.
255 */
256 static final int MAX_ANIMATION_DURATION = 10*1000;
257
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700258 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
259 * compatible windows.
260 */
261 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
262
Craig Mautner7dfcb012012-10-10 10:24:47 -0700263 /** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */
Craig Mautnera4942c92012-10-16 09:06:53 -0700264 static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000;
Craig Mautner7dfcb012012-10-10 10:24:47 -0700265
Dianne Hackborna1111872010-11-23 20:55:11 -0800266 /**
267 * If true, the window manager will do its own custom freezing and general
268 * management of the screen during rotation.
269 */
270 static final boolean CUSTOM_SCREEN_ROTATION = true;
271
Jeff Brownb09abc12011-01-13 21:08:27 -0800272 // Maximum number of milliseconds to wait for input devices to be enumerated before
273 // proceding with safe mode detection.
274 private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
Jim Miller28637ba2011-07-06 19:57:05 -0700275
Jeff Brown349703e2010-06-22 01:27:15 -0700276 // Default input dispatching timeout in nanoseconds.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800277 static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
Romain Guy06882f82009-06-10 13:36:04 -0700278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 static final int UPDATE_FOCUS_NORMAL = 0;
280 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
281 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
282 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700283
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700285 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286
Craig Mautner24d887472013-03-20 15:40:36 -0700287 private static final int MAX_SCREENSHOT_RETRIES = 3;
288
Craig Mautner5642a482012-08-23 12:16:53 -0700289 final private KeyguardDisableHandler mKeyguardDisableHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800290
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700291 private final boolean mHeadless;
292
Jim Miller284b62e2010-06-08 14:27:42 -0700293 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
294 @Override
295 public void onReceive(Context context, Intent intent) {
Craig Mautner9dc52bc2012-08-06 14:15:42 -0700296 final String action = intent.getAction();
297 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
Craig Mautner5642a482012-08-23 12:16:53 -0700298 mKeyguardDisableHandler.sendEmptyMessage(
299 KeyguardDisableHandler.KEYGUARD_POLICY_CHANGED);
Jim Miller284b62e2010-06-08 14:27:42 -0700300 }
301 }
302 };
303
Craig Mautner9dc52bc2012-08-06 14:15:42 -0700304 // Current user when multi-user is enabled. Don't show windows of non-current user.
305 int mCurrentUserId;
306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307 final Context mContext;
308
309 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700310
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700311 final boolean mAllowBootMessages;
312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
316
317 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700318
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700320
Dianne Hackbornc2293022013-02-06 23:14:49 -0800321 final AppOpsManager mAppOps;
322
Dianne Hackbornc652de82013-02-15 16:32:56 -0800323 final DisplaySettings mDisplaySettings;
324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325 /**
326 * All currently active sessions with clients.
327 */
328 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 /**
331 * Mapping from an IWindow IBinder to the server's Window object.
332 * This is also used as the lock for all of our state.
Craig Mautner58106812012-12-28 12:27:40 -0800333 * NOTE: Never call into methods that lock ActivityManagerService while holding this object.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 */
335 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
336
337 /**
338 * Mapping from a token IBinder to a WindowToken object.
339 */
Craig Mautner2ad92072013-02-25 16:19:24 -0800340 final HashMap<IBinder, WindowToken> mTokenMap =
341 new HashMap<IBinder, WindowToken>();
342
343 /**
344 * Window tokens that are in the process of exiting, but still
345 * on screen for animations.
346 */
347 final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
348
349 /**
350 * List controlling the ordering of windows in different applications which must
351 * be kept in sync with ActivityManager.
352 */
353 final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
354
355 /**
356 * AppWindowTokens in the Z order they were in at the start of an animation. Between
357 * animations this list is maintained in the exact order of mAppTokens. If tokens
358 * are added to mAppTokens during an animation an attempt is made to insert them at the same
359 * logical location in this list. Note that this list is always in sync with mWindows.
360 */
361 ArrayList<AppWindowToken> mAnimatingAppTokens = new ArrayList<AppWindowToken>();
362
363 /**
364 * Application tokens that are in the process of exiting, but still
365 * on screen for animations.
366 */
367 final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368
369 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370 * List of window tokens that have finished starting their application,
371 * and now need to have the policy remove their windows.
372 */
373 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
374
375 /**
Dianne Hackborndf89e652011-10-06 22:35:11 -0700376 * Fake windows added to the window manager. Note: ordered from top to
377 * bottom, opposite of mWindows.
378 */
379 final ArrayList<FakeWindowImpl> mFakeWindows = new ArrayList<FakeWindowImpl>();
380
381 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 * Windows that are being resized. Used so we can tell the client about
383 * the resize after closing the transaction in which we resized the
384 * underlying surface.
385 */
386 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
387
388 /**
389 * Windows whose animations have ended and now must be removed.
390 */
391 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
392
393 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800394 * Used when processing mPendingRemove to avoid working on the original array.
395 */
396 WindowState[] mPendingRemoveTmp = new WindowState[20];
397
398 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 * Windows whose surface should be destroyed.
400 */
401 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
402
403 /**
404 * Windows that have lost input focus and are waiting for the new
405 * focus window to be displayed before they are told about this.
406 */
407 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
408
409 /**
410 * This is set when we have run out of memory, and will either be an empty
411 * list or contain windows that need to be force removed.
412 */
413 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700414
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800415 /**
Dianne Hackborn38e29a62011-09-18 14:43:08 -0700416 * Windows that clients are waiting to have drawn.
417 */
418 ArrayList<Pair<WindowState, IRemoteCallback>> mWaitingForDrawn
419 = new ArrayList<Pair<WindowState, IRemoteCallback>>();
420
421 /**
Dianne Hackborn12d3a942012-04-27 14:16:30 -0700422 * Windows that have called relayout() while we were running animations,
423 * so we need to tell when the animation is done.
424 */
425 final ArrayList<WindowState> mRelayoutWhileAnimating = new ArrayList<WindowState>();
426
427 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800428 * Used when rebuilding window list to keep track of windows that have
429 * been removed.
430 */
431 WindowState[] mRebuildTmp = new WindowState[20];
432
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800433 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700434
Svetoslav Ganov545252f2012-12-10 18:29:24 -0800435 DisplayMagnifier mDisplayMagnifier;
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -0700436
Craig Mautner7358fbf2012-04-12 21:06:33 -0700437 final SurfaceSession mFxSession;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700438 Watermark mWatermark;
Brad Fitzpatrick68044332010-11-22 18:19:48 -0800439 StrictModeFlash mStrictModeFlash;
Romain Guy06882f82009-06-10 13:36:04 -0700440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 final float[] mTmpFloats = new float[9];
442
Jeff Browne215f262012-09-10 16:01:14 -0700443 boolean mDisplayReady;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800444 boolean mSafeMode;
445 boolean mDisplayEnabled = false;
446 boolean mSystemBooted = false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700447 boolean mForceDisplayEnabled = false;
Dianne Hackborn661cd522011-08-22 00:26:20 -0700448 boolean mShowingBootMessages = false;
Dianne Hackborn1fbee792011-11-30 11:29:58 -0800449
Jeff Brownd7a04de2012-06-17 14:17:52 -0700450 String mLastANRState;
451
Craig Mautner2ad92072013-02-25 16:19:24 -0800452 /** All DisplayDontents in the world, kept here */
Craig Mautner7c6be102013-07-16 12:30:28 -0700453 SparseArray<DisplayContent> mDisplayContents = new SparseArray<DisplayContent>();
Craig Mautner343ad712013-02-13 22:37:26 -0800454
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800455 int mRotation = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800456 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborndacea8c2011-04-21 17:26:39 -0700457 boolean mAltOrientation = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458 ArrayList<IRotationWatcher> mRotationWatchers
459 = new ArrayList<IRotationWatcher>();
Jeff Brown01a98dd2011-09-20 15:08:29 -0700460 int mDeferredRotationPauseCount;
Romain Guy06882f82009-06-10 13:36:04 -0700461
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700462 final Rect mSystemDecorRect = new Rect();
463 int mSystemDecorLayer = 0;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700464 final Rect mScreenRect = new Rect();
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700465
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800466 boolean mTraversalScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800467 boolean mDisplayFrozen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -0700468 long mDisplayFreezeTime = 0;
469 int mLastDisplayFreezeDuration = 0;
470 Object mLastFinishedFreezeSource = null;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800471 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472 boolean mWindowsFreezingScreen = false;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700473 boolean mClientFreezingScreen = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 int mAppsFreezingScreen = 0;
Dianne Hackbornbc7386c2011-06-06 17:27:54 -0700475 int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800476
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800477 int mLayoutSeq = 0;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700478
479 int mLastStatusBarVisibility = 0;
480
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800481 // State while inside of layoutAndPlaceSurfacesLocked().
482 boolean mFocusMayChange;
Craig Mautner01cd0e72012-06-18 10:19:11 -0700483
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800484 Configuration mCurConfiguration = new Configuration();
Craig Mautner01cd0e72012-06-18 10:19:11 -0700485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486 // This is held as long as we have the screen frozen, to give us time to
487 // perform a rotation animation when turning off shows the lock screen which
488 // changes the orientation.
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800489 private PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700490
Craig Mautner164d4bb2012-11-26 13:51:23 -0800491 final AppTransition mAppTransition;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800492 boolean mStartingIconInTransition = false;
493 boolean mSkipAppTransitionAnimation = false;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
496 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700497
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700498 boolean mIsTouchDevice;
499
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700500 final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Jeff Brownbc68a592011-07-25 12:58:12 -0700501 final DisplayMetrics mRealDisplayMetrics = new DisplayMetrics();
Dianne Hackborn48a76512011-06-08 21:51:44 -0700502 final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics();
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700503 final DisplayMetrics mCompatDisplayMetrics = new DisplayMetrics();
504
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800505 final H mH = new H();
506
507 final Choreographer mChoreographer = Choreographer.getInstance();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800508
509 WindowState mCurrentFocus = null;
510 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700511
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800512 /** This just indicates the window the input method is on top of, not
513 * necessarily the window its input is going to. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800514 WindowState mInputMethodTarget = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800515
516 /** If true hold off on modifying the animation layer of mInputMethodTarget */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 boolean mInputMethodTargetWaitingAnim;
518 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700519
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520 WindowState mInputMethodWindow = null;
521 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
522
Jeff Brown2992ea72011-01-28 22:04:14 -0800523 boolean mHardKeyboardAvailable;
524 boolean mHardKeyboardEnabled;
525 OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
526
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700527 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800528
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700529 // If non-null, this is the currently visible window that is associated
530 // with the wallpaper.
531 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700532 // If non-null, we are in the middle of animating from one wallpaper target
533 // to another, and this is the lower one in Z-order.
Dianne Hackborn98129732012-11-01 16:28:16 -0700534 WindowState mLowerWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700535 // If non-null, we are in the middle of animating from one wallpaper target
536 // to another, and this is the higher one in Z-order.
Craig Mautner96868332012-12-04 14:29:11 -0800537 WindowState mUpperWallpaperTarget = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700538 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700539 float mLastWallpaperX = -1;
540 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800541 float mLastWallpaperXStep = -1;
542 float mLastWallpaperYStep = -1;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700543 // This is set when we are waiting for a wallpaper to tell us it is done
544 // changing its scroll position.
545 WindowState mWaitingOnWallpaper;
546 // The last time we had a timeout when waiting for a wallpaper.
547 long mLastWallpaperTimeoutTime;
548 // We give a wallpaper up to 150ms to finish scrolling.
549 static final long WALLPAPER_TIMEOUT = 150;
550 // Time we wait after a timeout before trying to wait again.
551 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800552
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800553 AppWindowToken mFocusedApp = null;
554
555 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700556
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800557 float mWindowAnimationScale = 1.0f;
558 float mTransitionAnimationScale = 1.0f;
Chet Haasec38fa1f2012-02-01 16:37:46 -0800559 float mAnimatorDurationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700560
Jeff Brown4532e612012-04-05 14:27:12 -0700561 final InputManagerService mInputManager;
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700562 final DisplayManagerService mDisplayManagerService;
563 final DisplayManager mDisplayManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800564
565 // Who is holding the screen on.
566 Session mHoldingScreenOn;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700567 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700568
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700569 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800570
Christopher Tatea53146c2010-09-07 11:57:52 -0700571 DragState mDragState = null;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800572
Craig Mautner3c174372013-02-21 17:54:37 -0800573 // For frozen screen animations.
574 int mExitAnimId, mEnterAnimId;
575
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800576 /** Pulled out of performLayoutAndPlaceSurfacesLockedInner in order to refactor into multiple
577 * methods. */
Craig Mautnera608b882012-03-30 13:03:49 -0700578 class LayoutFields {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700579 static final int SET_UPDATE_ROTATION = 1 << 0;
580 static final int SET_WALLPAPER_MAY_CHANGE = 1 << 1;
581 static final int SET_FORCE_HIDING_CHANGED = 1 << 2;
Craig Mautner2639da52012-07-09 09:39:06 -0700582 static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3;
Craig Mautner7d8df392012-04-06 15:26:23 -0700583 static final int SET_TURN_ON_SCREEN = 1 << 4;
Craig Mautner96868332012-12-04 14:29:11 -0800584 static final int SET_WALLPAPER_ACTION_PENDING = 1 << 5;
Craig Mautnera608b882012-03-30 13:03:49 -0700585
Craig Mautner764983d2012-03-22 11:37:36 -0700586 boolean mWallpaperForceHidingChanged = false;
587 boolean mWallpaperMayChange = false;
Craig Mautner764983d2012-03-22 11:37:36 -0700588 boolean mOrientationChangeComplete = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -0700589 Object mLastWindowFreezeSource = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800590 private Session mHoldScreen = null;
591 private boolean mObscured = false;
Craig Mautner764983d2012-03-22 11:37:36 -0700592 boolean mDimming = false;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800593 private boolean mSyswin = false;
594 private float mScreenBrightness = -1;
595 private float mButtonBrightness = -1;
Jeff Brown1e3b98d2012-09-30 18:58:59 -0700596 private long mUserActivityTimeout = -1;
Craig Mautnera608b882012-03-30 13:03:49 -0700597 private boolean mUpdateRotation = false;
Craig Mautner96868332012-12-04 14:29:11 -0800598 boolean mWallpaperActionPending = false;
Craig Mautner65d11b32012-10-01 13:59:52 -0700599
600 private static final int DISPLAY_CONTENT_UNKNOWN = 0;
601 private static final int DISPLAY_CONTENT_MIRROR = 1;
602 private static final int DISPLAY_CONTENT_UNIQUE = 2;
603 private int mDisplayHasContent = DISPLAY_CONTENT_UNKNOWN;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800604 }
Craig Mautner01cd0e72012-06-18 10:19:11 -0700605 final LayoutFields mInnerFields = new LayoutFields();
606
Craig Mautner322e4032012-07-13 13:35:20 -0700607 static class AppWindowAnimParams {
608 AppWindowAnimator mAppAnimator;
609 ArrayList<WindowStateAnimator> mWinAnimators;
610
611 public AppWindowAnimParams(final AppWindowAnimator appAnimator) {
612 mAppAnimator = appAnimator;
613
Craig Mautner5c0e78c2012-09-12 16:45:36 -0700614 final AppWindowToken atoken = appAnimator.mAppToken;
Craig Mautner322e4032012-07-13 13:35:20 -0700615 mWinAnimators = new ArrayList<WindowStateAnimator>();
Craig Mautner5c0e78c2012-09-12 16:45:36 -0700616 final int N = atoken.allAppWindows.size();
Craig Mautner322e4032012-07-13 13:35:20 -0700617 for (int i = 0; i < N; i++) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -0700618 mWinAnimators.add(atoken.allAppWindows.get(i).mWinAnimator);
Craig Mautner322e4032012-07-13 13:35:20 -0700619 }
620 }
621 }
622
Craig Mautner96868332012-12-04 14:29:11 -0800623 boolean mAnimationScheduled;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800624
Craig Mautner6fbda632012-07-03 09:26:39 -0700625 /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
626 * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
627 private int mTransactionSequence;
628
Craig Mautnerbb1449b2012-03-23 16:11:14 -0700629 /** Only do a maximum of 6 repeated layouts. After that quit */
630 private int mLayoutRepeatCount;
631
Craig Mautner764983d2012-03-22 11:37:36 -0700632 final WindowAnimator mAnimator;
Jeff Brown4a06c802012-02-15 15:06:01 -0800633
Jeff Brown32cbc38552011-12-01 14:01:49 -0800634 final class DragInputEventReceiver extends InputEventReceiver {
635 public DragInputEventReceiver(InputChannel inputChannel, Looper looper) {
636 super(inputChannel, looper);
637 }
638
Christopher Tatea53146c2010-09-07 11:57:52 -0700639 @Override
Jeff Brown32cbc38552011-12-01 14:01:49 -0800640 public void onInputEvent(InputEvent event) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700641 boolean handled = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700642 try {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800643 if (event instanceof MotionEvent
644 && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
Jeff Brown3915bb82010-11-05 15:02:16 -0700645 && mDragState != null) {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800646 final MotionEvent motionEvent = (MotionEvent)event;
Jeff Brown3915bb82010-11-05 15:02:16 -0700647 boolean endDrag = false;
Jeff Brown4952dfd2011-11-30 19:23:22 -0800648 final float newX = motionEvent.getRawX();
649 final float newY = motionEvent.getRawY();
Jeff Brown3915bb82010-11-05 15:02:16 -0700650
Jeff Brown4952dfd2011-11-30 19:23:22 -0800651 switch (motionEvent.getAction()) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700652 case MotionEvent.ACTION_DOWN: {
653 if (DEBUG_DRAG) {
654 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
655 }
656 } break;
657
658 case MotionEvent.ACTION_MOVE: {
659 synchronized (mWindowMap) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700660 // move the surface and tell the involved window(s) where we are
Christopher Tatea53146c2010-09-07 11:57:52 -0700661 mDragState.notifyMoveLw(newX, newY);
662 }
663 } break;
664
665 case MotionEvent.ACTION_UP: {
666 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
667 + newX + "," + newY);
668 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700669 endDrag = mDragState.notifyDropLw(newX, newY);
Christopher Tatea53146c2010-09-07 11:57:52 -0700670 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700671 } break;
672
673 case MotionEvent.ACTION_CANCEL: {
674 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
675 endDrag = true;
676 } break;
677 }
678
679 if (endDrag) {
680 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
681 // tell all the windows that the drag has ended
Chris Tate59943592010-10-11 20:33:44 -0700682 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700683 mDragState.endDragLw();
Chris Tate59943592010-10-11 20:33:44 -0700684 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700685 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700686
687 handled = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700688 }
689 } catch (Exception e) {
690 Slog.e(TAG, "Exception caught by drag handleMotion", e);
691 } finally {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800692 finishInputEvent(event, handled);
Christopher Tatea53146c2010-09-07 11:57:52 -0700693 }
694 }
Jeff Brown32cbc38552011-12-01 14:01:49 -0800695 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700696
697 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800698 * Whether the UI is currently running in touch mode (not showing
699 * navigational focus because the user is directly pressing the screen).
700 */
Michael Jurkae99adc72011-08-11 18:28:01 -0700701 boolean mInTouchMode = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800702
703 private ViewServer mViewServer;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700704 private ArrayList<WindowChangeListener> mWindowChangeListeners =
705 new ArrayList<WindowChangeListener>();
706 private boolean mWindowsChanged = false;
707
708 public interface WindowChangeListener {
709 public void windowsChanged();
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -0700710 public void focusChanged();
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700711 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800712
Dianne Hackbornc485a602009-03-24 22:39:49 -0700713 final Configuration mTempConfiguration = new Configuration();
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700714
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700715 // The desired scaling factor for compatible apps.
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400716 float mCompatibleScreenScale;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700717
Jeff Brown780c46f2012-06-24 12:15:38 -0700718 // If true, only the core apps and services are being launched because the device
719 // is in a special boot mode, such as being encrypted or waiting for a decryption password.
720 // For example, when this flag is true, there will be no wallpaper service.
721 final boolean mOnlyCore;
722
Jeff Brownbd6e1502012-08-28 03:27:37 -0700723 public static WindowManagerService main(final Context context,
724 final PowerManagerService pm, final DisplayManagerService dm,
Jeff Browna9d131c2012-09-20 16:48:17 -0700725 final InputManagerService im,
Jeff Brownbd6e1502012-08-28 03:27:37 -0700726 final Handler uiHandler, final Handler wmHandler,
727 final boolean haveInputMethods, final boolean showBootMsgs,
728 final boolean onlyCore) {
729 final WindowManagerService[] holder = new WindowManagerService[1];
730 wmHandler.runWithScissors(new Runnable() {
731 @Override
732 public void run() {
Jeff Browna9d131c2012-09-20 16:48:17 -0700733 holder[0] = new WindowManagerService(context, pm, dm, im,
Jeff Brownbd6e1502012-08-28 03:27:37 -0700734 uiHandler, haveInputMethods, showBootMsgs, onlyCore);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800735 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700736 }, 0);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700737 return holder[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800738 }
Romain Guy06882f82009-06-10 13:36:04 -0700739
Jeff Brownbd6e1502012-08-28 03:27:37 -0700740 private void initPolicy(Handler uiHandler) {
741 uiHandler.runWithScissors(new Runnable() {
742 @Override
743 public void run() {
744 WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
Romain Guy06882f82009-06-10 13:36:04 -0700745
Jeff Brownbd6e1502012-08-28 03:27:37 -0700746 mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
747 mAnimator.mAboveUniverseLayer = mPolicy.getAboveUniverseLayer()
748 * TYPE_LAYER_MULTIPLIER
749 + TYPE_LAYER_OFFSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800750 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700751 }, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800752 }
753
754 private WindowManagerService(Context context, PowerManagerService pm,
Jeff Browna9d131c2012-09-20 16:48:17 -0700755 DisplayManagerService displayManager, InputManagerService inputManager,
756 Handler uiHandler,
Jeff Brown780c46f2012-06-24 12:15:38 -0700757 boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800758 mContext = context;
759 mHaveInputMethods = haveInputMethods;
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700760 mAllowBootMessages = showBootMsgs;
Jeff Brown780c46f2012-06-24 12:15:38 -0700761 mOnlyCore = onlyCore;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800762 mLimitedAlphaCompositing = context.getResources().getBoolean(
763 com.android.internal.R.bool.config_sf_limitedAlpha);
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700764 mDisplayManagerService = displayManager;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700765 mHeadless = displayManager.isHeadless();
Dianne Hackbornc652de82013-02-15 16:32:56 -0800766 mDisplaySettings = new DisplaySettings(context);
767 mDisplaySettings.readSettingsLocked();
Romain Guy06882f82009-06-10 13:36:04 -0700768
Craig Mautner722285e2012-09-07 13:55:58 -0700769 mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
770 mDisplayManager.registerDisplayListener(this, null);
771 Display[] displays = mDisplayManager.getDisplays();
772 for (Display display : displays) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -0700773 createDisplayContentLocked(display);
Craig Mautner722285e2012-09-07 13:55:58 -0700774 }
775
Craig Mautner5642a482012-08-23 12:16:53 -0700776 mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);
777
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800778 mPowerManager = pm;
779 mPowerManager.setPolicy(mPolicy);
780 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800781 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800782 mScreenFrozenLock.setReferenceCounted(false);
783
Craig Mautner164d4bb2012-11-26 13:51:23 -0800784 mAppTransition = new AppTransition(context, mH);
785
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800786 mActivityManager = ActivityManagerNative.getDefault();
787 mBatteryStats = BatteryStatsService.getService();
Dianne Hackbornc2293022013-02-06 23:14:49 -0800788 mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -0800789 mAppOps.startWatchingMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, null,
790 new AppOpsManager.Callback() {
791 @Override
792 public void opChanged(int op, String packageName) {
793 updateAppOpsState();
794 }
795 }
796 );
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800797
798 // Get persisted window scale setting
Jeff Sharkey6e2bee72012-10-01 13:39:08 -0700799 mWindowAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
800 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
801 mTransitionAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
802 Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
803 setAnimatorDurationScale(Settings.Global.getFloat(context.getContentResolver(),
Craig Mautnera7233fe32012-11-15 14:25:14 -0800804 Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale));
Romain Guy06882f82009-06-10 13:36:04 -0700805
Jim Miller284b62e2010-06-08 14:27:42 -0700806 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
807 IntentFilter filter = new IntentFilter();
808 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
809 mContext.registerReceiver(mBroadcastReceiver, filter);
810
Dianne Hackbornb80395c2012-06-14 19:38:20 -0700811 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
Craig Mautner259328c2012-08-21 19:30:58 -0700812 | PowerManager.ON_AFTER_RELEASE, TAG);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700813 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800814
Jeff Browna9d131c2012-09-20 16:48:17 -0700815 mInputManager = inputManager;
Craig Mautner9e809442012-06-22 17:13:04 -0700816 mFxSession = new SurfaceSession();
Craig Mautner918b53b2012-07-09 14:15:54 -0700817 mAnimator = new WindowAnimator(this);
Romain Guy06882f82009-06-10 13:36:04 -0700818
Jeff Brownbd6e1502012-08-28 03:27:37 -0700819 initPolicy(uiHandler);
Romain Guy06882f82009-06-10 13:36:04 -0700820
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800821 // Add ourself to the Watchdog monitors.
822 Watchdog.getInstance().addMonitor(this);
Craig Mautner7358fbf2012-04-12 21:06:33 -0700823
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800824 SurfaceControl.openTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700825 try {
826 createWatermarkInTransaction();
827 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800828 SurfaceControl.closeTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700829 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 }
831
Jeff Browna9d131c2012-09-20 16:48:17 -0700832 public InputMonitor getInputMonitor() {
833 return mInputMonitor;
Jeff Brown4532e612012-04-05 14:27:12 -0700834 }
835
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800836 @Override
837 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
838 throws RemoteException {
839 try {
840 return super.onTransact(code, data, reply, flags);
841 } catch (RuntimeException e) {
842 // The window manager only throws security exceptions, so let's
843 // log all others.
844 if (!(e instanceof SecurityException)) {
Dianne Hackborn89620282011-09-11 12:47:45 -0700845 Log.wtf(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800846 }
847 throw e;
848 }
849 }
850
Jeff Browne33348b2010-07-15 23:54:05 -0700851 private void placeWindowAfter(WindowState pos, WindowState window) {
Craig Mautner59c00972012-07-30 12:10:24 -0700852 final WindowList windows = pos.getWindowList();
853 final int i = windows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800854 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800855 TAG, "Adding window " + window + " at "
Craig Mautner59c00972012-07-30 12:10:24 -0700856 + (i+1) + " of " + windows.size() + " (after " + pos + ")");
857 windows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700858 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800859 }
860
Jeff Browne33348b2010-07-15 23:54:05 -0700861 private void placeWindowBefore(WindowState pos, WindowState window) {
Craig Mautner59c00972012-07-30 12:10:24 -0700862 final WindowList windows = pos.getWindowList();
863 final int i = windows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800864 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800865 TAG, "Adding window " + window + " at "
Craig Mautner59c00972012-07-30 12:10:24 -0700866 + i + " of " + windows.size() + " (before " + pos + ")");
867 windows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700868 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800869 }
870
871 //This method finds out the index of a window that has the same app token as
872 //win. used for z ordering the windows in mWindows
873 private int findIdxBasedOnAppTokens(WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -0700874 WindowList windows = win.getWindowList();
875 for(int j = windows.size() - 1; j >= 0; j--) {
876 WindowState wentry = windows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800877 if(wentry.mAppToken == win.mAppToken) {
878 return j;
879 }
880 }
881 return -1;
882 }
Romain Guy06882f82009-06-10 13:36:04 -0700883
Craig Mautnerefb735d2012-09-07 15:40:24 -0700884 /**
885 * Return the list of Windows from the passed token on the given Display.
886 * @param token The token with all the windows.
887 * @param displayContent The display we are interested in.
888 * @return List of windows from token that are on displayContent.
889 */
Craig Mautner69b08182012-09-05 13:07:13 -0700890 WindowList getTokenWindowsOnDisplay(WindowToken token, DisplayContent displayContent) {
891 final WindowList windowList = new WindowList();
892 final int count = token.windows.size();
893 for (int i = 0; i < count; i++) {
894 final WindowState win = token.windows.get(i);
895 if (win.mDisplayContent == displayContent) {
896 windowList.add(win);
897 }
898 }
899 return windowList;
900 }
901
Craig Mautner7b1aa772012-11-30 16:14:45 -0800902 /**
903 * Recursive search through a WindowList and all of its windows' children.
904 * @param targetWin The window to search for.
905 * @param windows The list to search.
906 * @return The index of win in windows or of the window that is an ancestor of win.
907 */
908 private int indexOfWinInWindowList(WindowState targetWin, WindowList windows) {
909 for (int i = windows.size() - 1; i >= 0; i--) {
910 final WindowState w = windows.get(i);
911 if (w == targetWin) {
912 return i;
913 }
914 if (!w.mChildWindows.isEmpty()) {
915 if (indexOfWinInWindowList(targetWin, w.mChildWindows) >= 0) {
916 return i;
917 }
918 }
919 }
920 return -1;
921 }
922
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800923 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
924 final IWindow client = win.mClient;
925 final WindowToken token = win.mToken;
Craig Mautner69b08182012-09-05 13:07:13 -0700926 final DisplayContent displayContent = win.mDisplayContent;
Romain Guy06882f82009-06-10 13:36:04 -0700927
Craig Mautner59c00972012-07-30 12:10:24 -0700928 final WindowList windows = win.getWindowList();
929 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930 final WindowState attached = win.mAttachedWindow;
Craig Mautner2ad92072013-02-25 16:19:24 -0800931 int i;
Craig Mautner69b08182012-09-05 13:07:13 -0700932 WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 if (attached == null) {
Craig Mautner69b08182012-09-05 13:07:13 -0700934 int tokenWindowsPos = 0;
935 int windowListPos = tokenWindowList.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800936 if (token.appWindowToken != null) {
Craig Mautner69b08182012-09-05 13:07:13 -0700937 int index = windowListPos - 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800938 if (index >= 0) {
939 // If this application has existing windows, we
940 // simply place the new window on top of them... but
941 // keep the starting window on top.
942 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
943 // Base windows go behind everything else.
Craig Mautner69b08182012-09-05 13:07:13 -0700944 WindowState lowestWindow = tokenWindowList.get(0);
945 placeWindowBefore(lowestWindow, win);
Craig Mautner7b1aa772012-11-30 16:14:45 -0800946 tokenWindowsPos = indexOfWinInWindowList(lowestWindow, token.windows);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800947 } else {
948 AppWindowToken atoken = win.mAppToken;
Craig Mautner69b08182012-09-05 13:07:13 -0700949 WindowState lastWindow = tokenWindowList.get(index);
950 if (atoken != null && lastWindow == atoken.startingWindow) {
951 placeWindowBefore(lastWindow, win);
Craig Mautner7b1aa772012-11-30 16:14:45 -0800952 tokenWindowsPos = indexOfWinInWindowList(lastWindow, token.windows);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800953 } else {
Craig Mautner69b08182012-09-05 13:07:13 -0700954 int newIdx = findIdxBasedOnAppTokens(win);
955 //there is a window above this one associated with the same
956 //apptoken note that the window could be a floating window
957 //that was created later or a window at the top of the list of
958 //windows associated with this token.
959 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
960 Slog.v(TAG, "Adding window " + win + " at "
Craig Mautnerefb735d2012-09-07 15:40:24 -0700961 + (newIdx + 1) + " of " + N);
Romain Guy06882f82009-06-10 13:36:04 -0700962 }
Craig Mautnerefb735d2012-09-07 15:40:24 -0700963 windows.add(newIdx + 1, win);
964 if (newIdx < 0) {
965 // No window from token found on win's display.
966 tokenWindowsPos = 0;
967 } else {
Craig Mautner7b1aa772012-11-30 16:14:45 -0800968 tokenWindowsPos = indexOfWinInWindowList(
969 windows.get(newIdx), token.windows) + 1;
Craig Mautnerefb735d2012-09-07 15:40:24 -0700970 }
Craig Mautner69b08182012-09-05 13:07:13 -0700971 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800972 }
973 }
974 } else {
Craig Mautner69b08182012-09-05 13:07:13 -0700975 // No windows from this token on this display
Joe Onorato8a9b2202010-02-26 18:56:32 -0800976 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800977 TAG, "Figuring out where to add app window "
978 + client.asBinder() + " (token=" + token + ")");
979 // Figure out where the window should go, based on the
980 // order of applications.
Craig Mautner2ad92072013-02-25 16:19:24 -0800981 final int NA = mAnimatingAppTokens.size();
Jeff Browne33348b2010-07-15 23:54:05 -0700982 WindowState pos = null;
Craig Mautner2ad92072013-02-25 16:19:24 -0800983 for (i=NA-1; i>=0; i--) {
984 AppWindowToken t = mAnimatingAppTokens.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800985 if (t == token) {
Craig Mautner2ad92072013-02-25 16:19:24 -0800986 i--;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800987 break;
988 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800989
Dianne Hackborna8f60182009-09-01 19:01:50 -0700990 // We haven't reached the token yet; if this token
Craig Mautner69b08182012-09-05 13:07:13 -0700991 // is not going to the bottom and has windows on this display, we can
Dianne Hackborna8f60182009-09-01 19:01:50 -0700992 // use it as an anchor for when we do reach the token.
Craig Mautner69b08182012-09-05 13:07:13 -0700993 tokenWindowList = getTokenWindowsOnDisplay(t, win.mDisplayContent);
994 if (!t.sendingToBottom && tokenWindowList.size() > 0) {
995 pos = tokenWindowList.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800996 }
997 }
998 // We now know the index into the apps. If we found
999 // an app window above, that gives us the position; else
1000 // we need to look some more.
1001 if (pos != null) {
1002 // Move behind any windows attached to this one.
Jeff Browne33348b2010-07-15 23:54:05 -07001003 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001004 if (atoken != null) {
Craig Mautner69b08182012-09-05 13:07:13 -07001005 tokenWindowList =
1006 getTokenWindowsOnDisplay(atoken, win.mDisplayContent);
1007 final int NC = tokenWindowList.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001008 if (NC > 0) {
Craig Mautner69b08182012-09-05 13:07:13 -07001009 WindowState bottom = tokenWindowList.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001010 if (bottom.mSubLayer < 0) {
1011 pos = bottom;
1012 }
1013 }
1014 }
1015 placeWindowBefore(pos, win);
1016 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -07001017 // Continue looking down until we find the first
Craig Mautner69b08182012-09-05 13:07:13 -07001018 // token that has windows on this display.
Craig Mautner2ad92072013-02-25 16:19:24 -08001019 while (i >= 0) {
1020 AppWindowToken t = mAnimatingAppTokens.get(i);
1021 tokenWindowList = getTokenWindowsOnDisplay(t, win.mDisplayContent);
Craig Mautner69b08182012-09-05 13:07:13 -07001022 final int NW = tokenWindowList.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001023 if (NW > 0) {
Craig Mautner69b08182012-09-05 13:07:13 -07001024 pos = tokenWindowList.get(NW-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001025 break;
1026 }
Craig Mautner2ad92072013-02-25 16:19:24 -08001027 i--;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001028 }
1029 if (pos != null) {
1030 // Move in front of any windows attached to this
1031 // one.
Jeff Browne33348b2010-07-15 23:54:05 -07001032 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001033 if (atoken != null) {
1034 final int NC = atoken.windows.size();
1035 if (NC > 0) {
1036 WindowState top = atoken.windows.get(NC-1);
1037 if (top.mSubLayer >= 0) {
1038 pos = top;
1039 }
1040 }
1041 }
1042 placeWindowAfter(pos, win);
1043 } else {
1044 // Just search for the start of this layer.
1045 final int myLayer = win.mBaseLayer;
Craig Mautner2ad92072013-02-25 16:19:24 -08001046 for (i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07001047 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001048 if (w.mBaseLayer > myLayer) {
1049 break;
1050 }
1051 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001052 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
1053 Slog.v(TAG, "Adding window " + win + " at "
1054 + i + " of " + N);
1055 }
Craig Mautner59c00972012-07-30 12:10:24 -07001056 windows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001057 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001058 }
1059 }
1060 }
1061 } else {
1062 // Figure out where window should go, based on layer.
1063 final int myLayer = win.mBaseLayer;
Craig Mautner2ad92072013-02-25 16:19:24 -08001064 for (i=N-1; i>=0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07001065 if (windows.get(i).mBaseLayer <= myLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001066 break;
1067 }
1068 }
Craig Mautner69b08182012-09-05 13:07:13 -07001069 i++;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001070 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001071 TAG, "Adding window " + win + " at "
1072 + i + " of " + N);
Craig Mautner59c00972012-07-30 12:10:24 -07001073 windows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001074 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001075 }
Craig Mautner59c00972012-07-30 12:10:24 -07001076
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001077 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001078 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001079 token.windows.add(tokenWindowsPos, win);
1080 }
1081
1082 } else {
1083 // Figure out this window's ordering relative to the window
1084 // it is attached to.
Craig Mautner69b08182012-09-05 13:07:13 -07001085 final int NA = tokenWindowList.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001086 final int sublayer = win.mSubLayer;
1087 int largestSublayer = Integer.MIN_VALUE;
1088 WindowState windowWithLargestSublayer = null;
Craig Mautner2ad92072013-02-25 16:19:24 -08001089 for (i=0; i<NA; i++) {
Craig Mautner69b08182012-09-05 13:07:13 -07001090 WindowState w = tokenWindowList.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001091 final int wSublayer = w.mSubLayer;
1092 if (wSublayer >= largestSublayer) {
1093 largestSublayer = wSublayer;
1094 windowWithLargestSublayer = w;
1095 }
1096 if (sublayer < 0) {
1097 // For negative sublayers, we go below all windows
1098 // in the same sublayer.
1099 if (wSublayer >= sublayer) {
1100 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001101 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001102 token.windows.add(i, win);
1103 }
Craig Mautner59c00972012-07-30 12:10:24 -07001104 placeWindowBefore(wSublayer >= 0 ? attached : w, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001105 break;
1106 }
1107 } else {
1108 // For positive sublayers, we go above all windows
1109 // in the same sublayer.
1110 if (wSublayer > sublayer) {
1111 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001112 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001113 token.windows.add(i, win);
1114 }
1115 placeWindowBefore(w, win);
1116 break;
1117 }
1118 }
1119 }
1120 if (i >= NA) {
1121 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001122 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001123 token.windows.add(win);
1124 }
1125 if (sublayer < 0) {
1126 placeWindowBefore(attached, win);
1127 } else {
1128 placeWindowAfter(largestSublayer >= 0
1129 ? windowWithLargestSublayer
1130 : attached,
1131 win);
1132 }
1133 }
1134 }
Romain Guy06882f82009-06-10 13:36:04 -07001135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001136 if (win.mAppToken != null && addToToken) {
1137 win.mAppToken.allAppWindows.add(win);
1138 }
1139 }
Romain Guy06882f82009-06-10 13:36:04 -07001140
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001141 static boolean canBeImeTarget(WindowState w) {
1142 final int fl = w.mAttrs.flags
1143 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
Dianne Hackborne75d8722011-01-27 19:37:40 -08001144 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)
Craig Mautner65d11b32012-10-01 13:59:52 -07001145 || w.mAttrs.type == TYPE_APPLICATION_STARTING) {
Dianne Hackborne75d8722011-01-27 19:37:40 -08001146 if (DEBUG_INPUT_METHOD) {
1147 Slog.i(TAG, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
1148 if (!w.isVisibleOrAdding()) {
Mathias Agopian29479eb2013-02-14 14:36:04 -08001149 Slog.i(TAG, " mSurface=" + w.mWinAnimator.mSurfaceControl
Dianne Hackborne75d8722011-01-27 19:37:40 -08001150 + " relayoutCalled=" + w.mRelayoutCalled + " viewVis=" + w.mViewVisibility
Dianne Hackbornac920872012-05-22 11:49:49 -07001151 + " policyVis=" + w.mPolicyVisibility
1152 + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim
1153 + " attachHid=" + w.mAttachedHidden
Dianne Hackborne75d8722011-01-27 19:37:40 -08001154 + " exiting=" + w.mExiting + " destroying=" + w.mDestroying);
1155 if (w.mAppToken != null) {
1156 Slog.i(TAG, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
1157 }
1158 }
1159 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001160 return w.isVisibleOrAdding();
1161 }
1162 return false;
1163 }
Romain Guy06882f82009-06-10 13:36:04 -07001164
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001165 /**
1166 * Dig through the WindowStates and find the one that the Input Method will target.
1167 * @param willMove
1168 * @return The index+1 in mWindows of the discovered target.
1169 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001170 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001171 // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
1172 // same display. Or even when the current IME/target are not on the same screen as the next
1173 // IME/target. For now only look for input windows on the main screen.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001174 WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07001175 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001176 WindowState w = null;
1177 int i = N;
1178 while (i > 0) {
1179 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07001180 w = windows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -07001181
Dianne Hackborne75d8722011-01-27 19:37:40 -08001182 if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG, "Checking window @" + i
1183 + " " + w + " fl=0x" + Integer.toHexString(w.mAttrs.flags));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001184 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001185 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -07001186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001187 // Yet more tricksyness! If this window is a "starting"
1188 // window, we do actually want to be on top of it, but
1189 // it is not -really- where input will go. So if the caller
1190 // is not actually looking to move the IME, look down below
1191 // for a real window to target...
1192 if (!willMove
Craig Mautner65d11b32012-10-01 13:59:52 -07001193 && w.mAttrs.type == TYPE_APPLICATION_STARTING
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001194 && i > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001195 WindowState wb = windows.get(i-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001196 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1197 i--;
1198 w = wb;
1199 }
1200 }
1201 break;
1202 }
1203 }
Romain Guy06882f82009-06-10 13:36:04 -07001204
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001205 // Now w is either mWindows[0] or an IME (or null if mWindows is empty).
1206
Dianne Hackborne75d8722011-01-27 19:37:40 -08001207 if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG, "Proposed new IME target: " + w);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001208
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001209 // Now, a special case -- if the last target's window is in the
1210 // process of exiting, and is above the new target, keep on the
1211 // last target to avoid flicker. Consider for example a Dialog with
1212 // the IME shown: when the Dialog is dismissed, we want to keep
1213 // the IME above it until it is completely gone so it doesn't drop
1214 // behind the dialog or its full-screen scrim.
Craig Mautner59c00972012-07-30 12:10:24 -07001215 final WindowState curTarget = mInputMethodTarget;
1216 if (curTarget != null && w != null
1217 && curTarget.isDisplayedLw()
Craig Mautnera987d432012-10-11 14:07:58 -07001218 && curTarget.isClosing()
Craig Mautnere6f7d5052012-10-08 10:34:17 -07001219 && (curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) {
1220 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Current target higher, not changing");
1221 return windows.indexOf(curTarget) + 1;
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001222 }
Romain Guy06882f82009-06-10 13:36:04 -07001223
Joe Onorato8a9b2202010-02-26 18:56:32 -08001224 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001225 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -07001226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001227 if (willMove && w != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07001228 AppWindowToken token = curTarget == null ? null : curTarget.mAppToken;
1229 if (token != null) {
Romain Guy06882f82009-06-10 13:36:04 -07001230
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001231 // Now some fun for dealing with window animations that
1232 // modify the Z order. We need to look at all windows below
1233 // the current target that are in this app, finding the highest
1234 // visible one in layering.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001235 WindowState highestTarget = null;
1236 int highestPos = 0;
Craig Mautner59431632012-04-04 11:56:44 -07001237 if (token.mAppAnimator.animating || token.mAppAnimator.animation != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07001238 WindowList curWindows = curTarget.getWindowList();
1239 int pos = curWindows.indexOf(curTarget);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001240 while (pos >= 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001241 WindowState win = curWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001242 if (win.mAppToken != token) {
1243 break;
1244 }
1245 if (!win.mRemoved) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001246 if (highestTarget == null || win.mWinAnimator.mAnimLayer >
1247 highestTarget.mWinAnimator.mAnimLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001248 highestTarget = win;
1249 highestPos = pos;
1250 }
1251 }
1252 pos--;
1253 }
1254 }
Romain Guy06882f82009-06-10 13:36:04 -07001255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001256 if (highestTarget != null) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08001257 if (DEBUG_INPUT_METHOD) Slog.v(TAG, mAppTransition + " " + highestTarget
Craig Mautnera2c77052012-03-26 12:14:43 -07001258 + " animating=" + highestTarget.mWinAnimator.isAnimating()
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001259 + " layer=" + highestTarget.mWinAnimator.mAnimLayer
1260 + " new layer=" + w.mWinAnimator.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001261
Craig Mautner164d4bb2012-11-26 13:51:23 -08001262 if (mAppTransition.isTransitionSet()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001263 // If we are currently setting up for an animation,
1264 // hold everything until we can find out what will happen.
1265 mInputMethodTargetWaitingAnim = true;
1266 mInputMethodTarget = highestTarget;
1267 return highestPos + 1;
Craig Mautnera2c77052012-03-26 12:14:43 -07001268 } else if (highestTarget.mWinAnimator.isAnimating() &&
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001269 highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001270 // If the window we are currently targeting is involved
1271 // with an animation, and it is on top of the next target
1272 // we will be over, then hold off on moving until
1273 // that is done.
Dianne Hackborne75d8722011-01-27 19:37:40 -08001274 mInputMethodTargetWaitingAnim = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001275 mInputMethodTarget = highestTarget;
1276 return highestPos + 1;
1277 }
1278 }
1279 }
1280 }
Romain Guy06882f82009-06-10 13:36:04 -07001281
Joe Onorato8a9b2202010-02-26 18:56:32 -08001282 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001283 if (w != null) {
1284 if (willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001285 if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to "
1286 + w + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001287 mInputMethodTarget = w;
Dianne Hackborne75d8722011-01-27 19:37:40 -08001288 mInputMethodTargetWaitingAnim = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001289 if (w.mAppToken != null) {
Craig Mautner59431632012-04-04 11:56:44 -07001290 setInputMethodAnimLayerAdjustment(w.mAppToken.mAppAnimator.animLayerAdjustment);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001291 } else {
1292 setInputMethodAnimLayerAdjustment(0);
1293 }
1294 }
1295 return i+1;
1296 }
1297 if (willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001298 if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to null."
1299 + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001300 mInputMethodTarget = null;
1301 setInputMethodAnimLayerAdjustment(0);
1302 }
1303 return -1;
1304 }
Romain Guy06882f82009-06-10 13:36:04 -07001305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001306 void addInputMethodWindowToListLocked(WindowState win) {
1307 int pos = findDesiredInputMethodWindowIndexLocked(true);
1308 if (pos >= 0) {
1309 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001310 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001311 TAG, "Adding input method window " + win + " at " + pos);
Craig Mautner59c00972012-07-30 12:10:24 -07001312 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001313 getDefaultWindowListLocked().add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001314 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001315 moveInputMethodDialogsLocked(pos+1);
1316 return;
1317 }
1318 win.mTargetAppToken = null;
1319 addWindowToListInOrderLocked(win, true);
1320 moveInputMethodDialogsLocked(pos);
1321 }
Romain Guy06882f82009-06-10 13:36:04 -07001322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001323 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001324 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001325 mInputMethodAnimLayerAdjustment = adj;
1326 WindowState imw = mInputMethodWindow;
1327 if (imw != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001328 imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001329 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001330 + " anim layer: " + imw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001331 int wi = imw.mChildWindows.size();
1332 while (wi > 0) {
1333 wi--;
Jeff Browne33348b2010-07-15 23:54:05 -07001334 WindowState cw = imw.mChildWindows.get(wi);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001335 cw.mWinAnimator.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001336 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001337 + " anim layer: " + cw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001338 }
1339 }
1340 int di = mInputMethodDialogs.size();
1341 while (di > 0) {
1342 di --;
1343 imw = mInputMethodDialogs.get(di);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001344 imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001345 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001346 + " anim layer: " + imw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001347 }
1348 }
Romain Guy06882f82009-06-10 13:36:04 -07001349
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001350 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -07001351 WindowList windows = win.getWindowList();
1352 int wpos = windows.indexOf(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001353 if (wpos >= 0) {
1354 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001355 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
Craig Mautner59c00972012-07-30 12:10:24 -07001356 windows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001357 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001358 int NC = win.mChildWindows.size();
1359 while (NC > 0) {
1360 NC--;
Jeff Browne33348b2010-07-15 23:54:05 -07001361 WindowState cw = win.mChildWindows.get(NC);
Craig Mautner59c00972012-07-30 12:10:24 -07001362 int cpos = windows.indexOf(cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001363 if (cpos >= 0) {
1364 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001365 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001366 + cpos + ": " + cw);
Craig Mautner59c00972012-07-30 12:10:24 -07001367 windows.remove(cpos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001368 }
1369 }
1370 }
1371 return interestingPos;
1372 }
Romain Guy06882f82009-06-10 13:36:04 -07001373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001374 private void reAddWindowToListInOrderLocked(WindowState win) {
1375 addWindowToListInOrderLocked(win, false);
1376 // This is a hack to get all of the child windows added as well
1377 // at the right position. Child windows should be rare and
1378 // this case should be rare, so it shouldn't be that big a deal.
Craig Mautner59c00972012-07-30 12:10:24 -07001379 WindowList windows = win.getWindowList();
1380 int wpos = windows.indexOf(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001381 if (wpos >= 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001382 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos + ": " + win);
1383 windows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001384 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001385 reAddWindowLocked(wpos, win);
1386 }
1387 }
Romain Guy06882f82009-06-10 13:36:04 -07001388
Craig Mautner59c00972012-07-30 12:10:24 -07001389 void logWindowList(final WindowList windows, String prefix) {
1390 int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001391 while (N > 0) {
1392 N--;
Craig Mautner59c00972012-07-30 12:10:24 -07001393 Slog.v(TAG, prefix + "#" + N + ": " + windows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001394 }
1395 }
Romain Guy06882f82009-06-10 13:36:04 -07001396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001397 void moveInputMethodDialogsLocked(int pos) {
1398 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001399
Craig Mautner59c00972012-07-30 12:10:24 -07001400 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001401 WindowList windows = getDefaultWindowListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001402 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001403 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001404 for (int i=0; i<N; i++) {
1405 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1406 }
1407 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001408 Slog.v(TAG, "Window list w/pos=" + pos);
Craig Mautner59c00972012-07-30 12:10:24 -07001409 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001410 }
Romain Guy06882f82009-06-10 13:36:04 -07001411
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001412 if (pos >= 0) {
1413 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
Craig Mautner59c00972012-07-30 12:10:24 -07001414 if (pos < windows.size()) {
1415 WindowState wp = windows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001416 if (wp == mInputMethodWindow) {
1417 pos++;
1418 }
1419 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001420 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001421 for (int i=0; i<N; i++) {
1422 WindowState win = dialogs.get(i);
1423 win.mTargetAppToken = targetAppToken;
1424 pos = reAddWindowLocked(pos, win);
1425 }
1426 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001427 Slog.v(TAG, "Final window list:");
Craig Mautner59c00972012-07-30 12:10:24 -07001428 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001429 }
1430 return;
1431 }
1432 for (int i=0; i<N; i++) {
1433 WindowState win = dialogs.get(i);
1434 win.mTargetAppToken = null;
1435 reAddWindowToListInOrderLocked(win);
1436 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001437 Slog.v(TAG, "No IM target, final list:");
Craig Mautner59c00972012-07-30 12:10:24 -07001438 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001439 }
1440 }
1441 }
Romain Guy06882f82009-06-10 13:36:04 -07001442
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001443 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1444 final WindowState imWin = mInputMethodWindow;
1445 final int DN = mInputMethodDialogs.size();
1446 if (imWin == null && DN == 0) {
1447 return false;
1448 }
Romain Guy06882f82009-06-10 13:36:04 -07001449
Craig Mautner59c00972012-07-30 12:10:24 -07001450 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001451 WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07001452
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001453 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1454 if (imPos >= 0) {
1455 // In this case, the input method windows are to be placed
1456 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001457
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001458 // First check to see if the input method windows are already
1459 // located here, and contiguous.
Craig Mautner59c00972012-07-30 12:10:24 -07001460 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001461 WindowState firstImWin = imPos < N
Craig Mautner59c00972012-07-30 12:10:24 -07001462 ? windows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001463
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001464 // Figure out the actual input method window that should be
1465 // at the bottom of their stack.
1466 WindowState baseImWin = imWin != null
1467 ? imWin : mInputMethodDialogs.get(0);
1468 if (baseImWin.mChildWindows.size() > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001469 WindowState cw = baseImWin.mChildWindows.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001470 if (cw.mSubLayer < 0) baseImWin = cw;
1471 }
Romain Guy06882f82009-06-10 13:36:04 -07001472
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001473 if (firstImWin == baseImWin) {
1474 // The windows haven't moved... but are they still contiguous?
1475 // First find the top IM window.
1476 int pos = imPos+1;
1477 while (pos < N) {
Craig Mautner59c00972012-07-30 12:10:24 -07001478 if (!(windows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001479 break;
1480 }
1481 pos++;
1482 }
1483 pos++;
1484 // Now there should be no more input method windows above.
1485 while (pos < N) {
Craig Mautner59c00972012-07-30 12:10:24 -07001486 if ((windows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487 break;
1488 }
1489 pos++;
1490 }
1491 if (pos >= N) {
Carrie Xu5c971842012-10-30 17:28:39 +08001492 // Z order is good.
1493 // The IM target window may be changed, so update the mTargetAppToken.
1494 if (imWin != null) {
1495 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1496 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001497 return false;
1498 }
1499 }
Romain Guy06882f82009-06-10 13:36:04 -07001500
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001501 if (imWin != null) {
1502 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001503 Slog.v(TAG, "Moving IM from " + imPos);
Craig Mautner59c00972012-07-30 12:10:24 -07001504 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 }
1506 imPos = tmpRemoveWindowLocked(imPos, imWin);
1507 if (DEBUG_INPUT_METHOD) {
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001508 Slog.v(TAG, "List after removing with new pos " + imPos + ":");
Craig Mautner59c00972012-07-30 12:10:24 -07001509 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 }
1511 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1512 reAddWindowLocked(imPos, imWin);
1513 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001514 Slog.v(TAG, "List after moving IM to " + imPos + ":");
Craig Mautner59c00972012-07-30 12:10:24 -07001515 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001516 }
1517 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1518 } else {
1519 moveInputMethodDialogsLocked(imPos);
1520 }
Romain Guy06882f82009-06-10 13:36:04 -07001521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001522 } else {
1523 // In this case, the input method windows go in a fixed layer,
1524 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001526 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001527 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001528 tmpRemoveWindowLocked(0, imWin);
1529 imWin.mTargetAppToken = null;
1530 reAddWindowToListInOrderLocked(imWin);
1531 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001532 Slog.v(TAG, "List with no IM target:");
Craig Mautner59c00972012-07-30 12:10:24 -07001533 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001534 }
Craig Mautner01cd0e72012-06-18 10:19:11 -07001535 if (DN > 0) moveInputMethodDialogsLocked(-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001536 } else {
Craig Mautner01cd0e72012-06-18 10:19:11 -07001537 moveInputMethodDialogsLocked(-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001538 }
Romain Guy06882f82009-06-10 13:36:04 -07001539
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001540 }
Romain Guy06882f82009-06-10 13:36:04 -07001541
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001542 if (needAssignLayers) {
Craig Mautner59c00972012-07-30 12:10:24 -07001543 assignLayersLocked(windows);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001544 }
Romain Guy06882f82009-06-10 13:36:04 -07001545
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001546 return true;
1547 }
Romain Guy06882f82009-06-10 13:36:04 -07001548
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001549 void adjustInputMethodDialogsLocked() {
1550 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1551 }
Romain Guy06882f82009-06-10 13:36:04 -07001552
Dianne Hackborn25994b42009-09-04 14:21:19 -07001553 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Craig Mautnerad3a9bb2012-03-09 11:31:06 -08001554 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001555 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1556 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
Craig Mautner59431632012-04-04 11:56:44 -07001557 ? wallpaperTarget.mAppToken.mAppAnimator.animation : null)
Dianne Hackborn25994b42009-09-04 14:21:19 -07001558 + " upper=" + mUpperWallpaperTarget
1559 + " lower=" + mLowerWallpaperTarget);
1560 return (wallpaperTarget != null
1561 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
Craig Mautner59431632012-04-04 11:56:44 -07001562 && wallpaperTarget.mAppToken.mAppAnimator.animation != null)))
Dianne Hackborn25994b42009-09-04 14:21:19 -07001563 || mUpperWallpaperTarget != null
1564 || mLowerWallpaperTarget != null;
1565 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001566
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001567 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1568 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001569
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001570 int adjustWallpaperWindowsLocked() {
Craig Mautnera608b882012-03-30 13:03:49 -07001571 mInnerFields.mWallpaperMayChange = false;
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001572 boolean targetChanged = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001573
Craig Mautner59c00972012-07-30 12:10:24 -07001574 // TODO(multidisplay): Wallpapers on main screen only.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001575 final DisplayInfo displayInfo = getDefaultDisplayContentLocked().getDisplayInfo();
Craig Mautner59c00972012-07-30 12:10:24 -07001576 final int dw = displayInfo.appWidth;
1577 final int dh = displayInfo.appHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001578
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001579 // First find top-most window that has asked to be on top of the
1580 // wallpaper; all wallpapers go behind it.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001581 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07001582 int N = windows.size();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001583 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001584 WindowState foundW = null;
1585 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001586 WindowState topCurW = null;
1587 int topCurI = 0;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001588 int windowDetachedI = -1;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001589 int i = N;
1590 while (i > 0) {
1591 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07001592 w = windows.get(i);
Craig Mautner65d11b32012-10-01 13:59:52 -07001593 if ((w.mAttrs.type == TYPE_WALLPAPER)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001594 if (topCurW == null) {
1595 topCurW = w;
1596 topCurI = i;
1597 }
1598 continue;
1599 }
1600 topCurW = null;
Craig Mautner96868332012-12-04 14:29:11 -08001601 if (w != mAnimator.mWindowDetachedWallpaper && w.mAppToken != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001602 // If this window's app token is hidden and not animating,
1603 // it is of no interest to us.
Craig Mautner59431632012-04-04 11:56:44 -07001604 if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001605 if (DEBUG_WALLPAPER) Slog.v(TAG,
Craig Mautner1d961d42012-05-27 12:02:11 -07001606 "Skipping hidden and not animating token: " + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001607 continue;
1608 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001609 }
Craig Mautnerae446592012-12-06 19:05:05 -08001610 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win #" + i + " " + w + ": isOnScreen="
1611 + w.isOnScreen() + " mDrawState=" + w.mWinAnimator.mDrawState);
1612 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isOnScreen()
1613 && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001614 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001615 "Found wallpaper target: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001616 foundW = w;
1617 foundI = i;
Craig Mautner4d7349b2012-04-20 14:52:47 -07001618 if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001619 // The current wallpaper target is animating, so we'll
1620 // look behind it for another possible target and figure
1621 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001622 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001623 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001624 continue;
1625 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001626 break;
Craig Mautner96868332012-12-04 14:29:11 -08001627 } else if (w == mAnimator.mWindowDetachedWallpaper) {
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001628 windowDetachedI = i;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001629 }
1630 }
1631
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001632 if (foundW == null && windowDetachedI >= 0) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001633 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001634 "Found animating detached wallpaper activity: #" + i + "=" + w);
1635 foundW = w;
1636 foundI = windowDetachedI;
1637 }
1638
Craig Mautner8863cca2012-09-18 15:04:34 -07001639 if (mWallpaperTarget != foundW
1640 && (mLowerWallpaperTarget == null || mLowerWallpaperTarget != foundW)) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001641 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001642 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001643 + " oldTarget: " + mWallpaperTarget);
1644 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001645
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001646 mLowerWallpaperTarget = null;
1647 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001648
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001649 WindowState oldW = mWallpaperTarget;
1650 mWallpaperTarget = foundW;
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001651 targetChanged = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001652
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001653 // Now what is happening... if the current and new targets are
1654 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001655 if (foundW != null && oldW != null) {
Craig Mautnerae446592012-12-06 19:05:05 -08001656 boolean oldAnim = oldW.isAnimatingLw();
1657 boolean foundAnim = foundW.isAnimatingLw();
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001658 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001659 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001660 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001661 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001662 if (foundAnim && oldAnim) {
Craig Mautner59c00972012-07-30 12:10:24 -07001663 int oldI = windows.indexOf(oldW);
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001664 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001665 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001666 }
1667 if (oldI >= 0) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001668 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001669 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001670 + "=" + oldW + "; new#" + foundI
1671 + "=" + foundW);
1672 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001673
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001674 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001675 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001676 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001677 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001678 }
1679 mWallpaperTarget = oldW;
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001680 foundW = oldW;
1681 foundI = oldI;
Craig Mautner711f90a2012-07-03 18:43:52 -07001682 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001683 // Now set the upper and lower wallpaper targets
1684 // correctly, and make sure that we are positioning
1685 // the wallpaper below the lower.
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001686 else if (foundI > oldI) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001687 // The new target is on top of the old one.
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001688 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001689 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001690 }
1691 mUpperWallpaperTarget = foundW;
1692 mLowerWallpaperTarget = oldW;
1693 foundW = oldW;
1694 foundI = oldI;
1695 } else {
1696 // The new target is below the old one.
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001697 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001698 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001699 }
1700 mUpperWallpaperTarget = oldW;
1701 mLowerWallpaperTarget = foundW;
1702 }
1703 }
1704 }
1705 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001706
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001707 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001708 // Is it time to stop animating?
Craig Mautnerae446592012-12-06 19:05:05 -08001709 if (!mLowerWallpaperTarget.isAnimatingLw() || !mUpperWallpaperTarget.isAnimatingLw()) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001710 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001711 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001712 }
1713 mLowerWallpaperTarget = null;
1714 mUpperWallpaperTarget = null;
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001715 mWallpaperTarget = foundW;
1716 targetChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001717 }
1718 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001719
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001720 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001721 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001722 // The window is visible to the compositor... but is it visible
1723 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001724 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001725 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001726
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001727 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001728 // its layer adjustment. Only do this if we are not transfering
1729 // between two wallpaper targets.
1730 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001731 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Craig Mautner59431632012-04-04 11:56:44 -07001732 ? foundW.mAppToken.mAppAnimator.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001733
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001734 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1735 * TYPE_LAYER_MULTIPLIER
1736 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001737
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001738 // Now w is the window we are supposed to be behind... but we
1739 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001740 // AND any starting window associated with it, AND below the
1741 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001742 while (foundI > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001743 WindowState wb = windows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001744 if (wb.mBaseLayer < maxLayer &&
1745 wb.mAttachedWindow != foundW &&
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001746 (foundW.mAttachedWindow == null ||
1747 wb.mAttachedWindow != foundW.mAttachedWindow) &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001748 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001749 foundW.mToken == null || wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001750 // This window is not related to the previous one in any
1751 // interesting way, so stop here.
1752 break;
1753 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001754 foundW = wb;
1755 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001756 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001757 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001758 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001759 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001760
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001761 if (foundW == null && topCurW != null) {
1762 // There is no wallpaper target, so it goes at the bottom.
1763 // We will assume it is the same place as last time, if known.
1764 foundW = topCurW;
1765 foundI = topCurI+1;
1766 } else {
1767 // Okay i is the position immediately above the wallpaper. Look at
1768 // what is below it for later.
Craig Mautner59c00972012-07-30 12:10:24 -07001769 foundW = foundI > 0 ? windows.get(foundI-1) : null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001770 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001771
Dianne Hackborn284ac932009-08-28 10:34:25 -07001772 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001773 if (mWallpaperTarget.mWallpaperX >= 0) {
1774 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001775 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001776 }
1777 if (mWallpaperTarget.mWallpaperY >= 0) {
1778 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001779 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001780 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001781 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001782
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001783 // Start stepping backwards from here, ensuring that our wallpaper windows
1784 // are correctly placed.
Craig Mautnerae446592012-12-06 19:05:05 -08001785 int changed = 0;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001786 int curTokenIndex = mWallpaperTokens.size();
1787 while (curTokenIndex > 0) {
1788 curTokenIndex--;
1789 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001790 if (token.hidden == visible) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001791 if (DEBUG_WALLPAPER_LIGHT) Slog.d(TAG,
1792 "Wallpaper token " + token + " hidden=" + !visible);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001793 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1794 token.hidden = !visible;
1795 // Need to do a layout to ensure the wallpaper now has the
1796 // correct size.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001797 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001798 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001799
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001800 int curWallpaperIndex = token.windows.size();
1801 while (curWallpaperIndex > 0) {
1802 curWallpaperIndex--;
1803 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001804
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001805 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001806 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001807 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001808
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001809 // First, make sure the client has the current visibility
1810 // state.
Craig Mautner507a2ee2012-06-13 08:39:38 -07001811 dispatchWallpaperVisibility(wallpaper, visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001812
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001813 wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001814 if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "adjustWallpaper win "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001815 + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001816
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001817 // First, if this window is at the current index, then all
1818 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001819 if (wallpaper == foundW) {
1820 foundI--;
1821 foundW = foundI > 0
Craig Mautner59c00972012-07-30 12:10:24 -07001822 ? windows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001823 continue;
1824 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001825
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001826 // The window didn't match... the current wallpaper window,
1827 // wherever it is, is in the wrong place, so make sure it is
1828 // not in the list.
Craig Mautner59c00972012-07-30 12:10:24 -07001829 int oldIndex = windows.indexOf(wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001830 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001831 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001832 + oldIndex + ": " + wallpaper);
Craig Mautner59c00972012-07-30 12:10:24 -07001833 windows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001834 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001835 if (oldIndex < foundI) {
1836 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001837 }
1838 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001839
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001840 // Now stick it in.
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001841 if (DEBUG_WALLPAPER_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001842 Slog.v(TAG, "Moving wallpaper " + wallpaper
1843 + " from " + oldIndex + " to " + foundI);
1844 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001845
Craig Mautner59c00972012-07-30 12:10:24 -07001846 windows.add(foundI, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001847 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001848 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001849 }
1850 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001851
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001852 if (targetChanged && DEBUG_WALLPAPER_LIGHT) {
1853 Slog.d(TAG, "New wallpaper: target=" + mWallpaperTarget
1854 + " lower=" + mLowerWallpaperTarget + " upper="
1855 + mUpperWallpaperTarget);
1856 }
1857
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001858 return changed;
1859 }
1860
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001861 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001862 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001863 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001864 mWallpaperAnimLayerAdjustment = adj;
1865 int curTokenIndex = mWallpaperTokens.size();
1866 while (curTokenIndex > 0) {
1867 curTokenIndex--;
1868 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1869 int curWallpaperIndex = token.windows.size();
1870 while (curWallpaperIndex > 0) {
1871 curWallpaperIndex--;
1872 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001873 wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + adj;
Craig Mautneref25d7a2012-05-15 23:01:47 -07001874 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "setWallpaper win "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001875 + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001876 }
1877 }
1878 }
1879
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001880 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
1881 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001882 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001883 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001884 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001885 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackbornffb3d932011-05-17 17:44:51 -07001886 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001887 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
1888 changed = wallpaperWin.mXOffset != offset;
1889 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001890 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001891 + wallpaperWin + " x: " + offset);
1892 wallpaperWin.mXOffset = offset;
1893 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001894 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001895 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001896 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001897 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001898 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001899
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001900 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001901 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001902 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1903 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1904 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001905 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001906 + wallpaperWin + " y: " + offset);
1907 changed = true;
1908 wallpaperWin.mYOffset = offset;
1909 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001910 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001911 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001912 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001913 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001914 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001915
Craig Mautnerbb1449b2012-03-23 16:11:14 -07001916 if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
Chet Haasea8e5a2b2011-10-28 13:18:16 -07001917 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001918 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001919 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001920 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
1921 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001922 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001923 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001924 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001925 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001926 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
1927 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001928 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001929 if (mWaitingOnWallpaper != null) {
1930 long start = SystemClock.uptimeMillis();
1931 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
1932 < start) {
1933 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001934 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07001935 "Waiting for offset complete...");
1936 mWindowMap.wait(WALLPAPER_TIMEOUT);
1937 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001938 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001939 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07001940 if ((start+WALLPAPER_TIMEOUT)
1941 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001942 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07001943 + wallpaperWin);
1944 mLastWallpaperTimeoutTime = start;
1945 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001946 }
Dianne Hackborn75804932009-10-20 20:15:20 -07001947 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001948 }
1949 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001950 } catch (RemoteException e) {
1951 }
1952 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001953
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001954 return changed;
1955 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001956
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001957 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001958 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001959 if (mWaitingOnWallpaper != null &&
1960 mWaitingOnWallpaper.mClient.asBinder() == window) {
1961 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07001962 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001963 }
1964 }
1965 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001966
Chet Haasea8e5a2b2011-10-28 13:18:16 -07001967 void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Craig Mautner59c00972012-07-30 12:10:24 -07001968 final DisplayContent displayContent = changingTarget.mDisplayContent;
1969 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
1970 final int dw = displayInfo.appWidth;
1971 final int dh = displayInfo.appHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001972
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001973 WindowState target = mWallpaperTarget;
1974 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001975 if (target.mWallpaperX >= 0) {
1976 mLastWallpaperX = target.mWallpaperX;
1977 } else if (changingTarget.mWallpaperX >= 0) {
1978 mLastWallpaperX = changingTarget.mWallpaperX;
1979 }
1980 if (target.mWallpaperY >= 0) {
1981 mLastWallpaperY = target.mWallpaperY;
1982 } else if (changingTarget.mWallpaperY >= 0) {
1983 mLastWallpaperY = changingTarget.mWallpaperY;
1984 }
1985 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001986
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001987 int curTokenIndex = mWallpaperTokens.size();
1988 while (curTokenIndex > 0) {
1989 curTokenIndex--;
1990 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1991 int curWallpaperIndex = token.windows.size();
1992 while (curWallpaperIndex > 0) {
1993 curWallpaperIndex--;
1994 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1995 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001996 WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
1997 winAnimator.computeShownFrameLocked();
Chet Haasea8e5a2b2011-10-28 13:18:16 -07001998 // No need to lay out the windows - we can just set the wallpaper position
1999 // directly.
Craig Mautner58106812012-12-28 12:27:40 -08002000 winAnimator.setWallpaperOffset(wallpaper.mShownFrame);
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002001 // We only want to be synchronous with one wallpaper.
2002 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002003 }
2004 }
2005 }
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002006 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002007
Craig Mautner507a2ee2012-06-13 08:39:38 -07002008 /**
2009 * Check wallpaper for visiblity change and notify window if so.
2010 * @param wallpaper The wallpaper to test and notify.
2011 * @param visible Current visibility.
2012 */
2013 void dispatchWallpaperVisibility(final WindowState wallpaper, final boolean visible) {
2014 if (wallpaper.mWallpaperVisible != visible) {
2015 wallpaper.mWallpaperVisible = visible;
2016 try {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07002017 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
2018 "Updating vis of wallpaper " + wallpaper
2019 + ": " + visible + " from:\n" + Debug.getCallers(4, " "));
Craig Mautner507a2ee2012-06-13 08:39:38 -07002020 wallpaper.mClient.dispatchAppVisibility(visible);
2021 } catch (RemoteException e) {
2022 }
2023 }
2024 }
2025
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002026 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07002027 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Craig Mautner59c00972012-07-30 12:10:24 -07002028 final DisplayContent displayContent = mWallpaperTarget.mDisplayContent;
2029 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
2030 final int dw = displayInfo.appWidth;
2031 final int dh = displayInfo.appHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002032
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002033 int curTokenIndex = mWallpaperTokens.size();
2034 while (curTokenIndex > 0) {
2035 curTokenIndex--;
2036 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002037 if (token.hidden == visible) {
2038 token.hidden = !visible;
2039 // Need to do a layout to ensure the wallpaper now has the
2040 // correct size.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07002041 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002042 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002043
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002044 int curWallpaperIndex = token.windows.size();
2045 while (curWallpaperIndex > 0) {
2046 curWallpaperIndex--;
2047 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2048 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002049 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002050 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002051
Craig Mautner507a2ee2012-06-13 08:39:38 -07002052 dispatchWallpaperVisibility(wallpaper, visible);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002053 }
2054 }
2055 }
Craig Mautner711f90a2012-07-03 18:43:52 -07002056
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002057 public int addWindow(Session session, IWindow client, int seq,
Craig Mautner6881a102012-07-27 13:04:51 -07002058 WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002059 Rect outContentInsets, InputChannel outInputChannel) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08002060 int[] appOp = new int[1];
2061 int res = mPolicy.checkAddPermission(attrs, appOp);
Jeff Brown98365d72012-08-19 20:30:52 -07002062 if (res != WindowManagerGlobal.ADD_OKAY) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002063 return res;
2064 }
Romain Guy06882f82009-06-10 13:36:04 -07002065
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002066 boolean reportNewConfig = false;
2067 WindowState attachedWindow = null;
2068 WindowState win = null;
Dianne Hackborn5132b372010-07-29 12:51:35 -07002069 long origId;
Craig Mautner88400d32012-09-30 12:35:45 -07002070 final int type = attrs.type;
Romain Guy06882f82009-06-10 13:36:04 -07002071
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002072 synchronized(mWindowMap) {
Jeff Browne215f262012-09-10 16:01:14 -07002073 if (!mDisplayReady) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07002074 throw new IllegalStateException("Display has not been initialialized");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002075 }
Romain Guy06882f82009-06-10 13:36:04 -07002076
Craig Mautner2d5618c2012-10-18 13:55:47 -07002077 final DisplayContent displayContent = getDisplayContentLocked(displayId);
2078 if (displayContent == null) {
2079 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
2080 }
2081
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002082 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002083 Slog.w(TAG, "Window " + client + " is already added");
Jeff Brown98365d72012-08-19 20:30:52 -07002084 return WindowManagerGlobal.ADD_DUPLICATE_ADD;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002085 }
2086
Craig Mautner88400d32012-09-30 12:35:45 -07002087 if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002088 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002089 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002090 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002091 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002092 return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002093 }
2094 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
2095 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002096 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002097 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002098 return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002099 }
2100 }
2101
2102 boolean addToken = false;
2103 WindowToken token = mTokenMap.get(attrs.token);
2104 if (token == null) {
Craig Mautner88400d32012-09-30 12:35:45 -07002105 if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002106 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002107 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002108 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002109 }
Craig Mautner88400d32012-09-30 12:35:45 -07002110 if (type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002111 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002112 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002113 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002114 }
Craig Mautner88400d32012-09-30 12:35:45 -07002115 if (type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002116 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002117 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002118 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002119 }
Craig Mautner88400d32012-09-30 12:35:45 -07002120 if (type == TYPE_DREAM) {
Daniel Sandler7d276c32012-01-30 14:33:52 -05002121 Slog.w(TAG, "Attempted to add Dream window with unknown token "
2122 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002123 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Daniel Sandler7d276c32012-01-30 14:33:52 -05002124 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002125 token = new WindowToken(this, attrs.token, -1, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002126 addToken = true;
Craig Mautner88400d32012-09-30 12:35:45 -07002127 } else if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002128 AppWindowToken atoken = token.appWindowToken;
2129 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002130 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002131 + token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002132 return WindowManagerGlobal.ADD_NOT_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002133 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002134 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002135 + token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002136 return WindowManagerGlobal.ADD_APP_EXITING;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002137 }
Craig Mautner88400d32012-09-30 12:35:45 -07002138 if (type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002139 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002140 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002141 TAG, "**** NO NEED TO START: " + attrs.getTitle());
Jeff Brown98365d72012-08-19 20:30:52 -07002142 return WindowManagerGlobal.ADD_STARTING_NOT_NEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002143 }
Craig Mautner88400d32012-09-30 12:35:45 -07002144 } else if (type == TYPE_INPUT_METHOD) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002145 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002146 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002147 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002148 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002149 }
Craig Mautner88400d32012-09-30 12:35:45 -07002150 } else if (type == TYPE_WALLPAPER) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002151 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002152 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002153 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002154 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002155 }
Craig Mautner88400d32012-09-30 12:35:45 -07002156 } else if (type == TYPE_DREAM) {
Daniel Sandler7d276c32012-01-30 14:33:52 -05002157 if (token.windowType != TYPE_DREAM) {
2158 Slog.w(TAG, "Attempted to add Dream window with bad token "
2159 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002160 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Daniel Sandler7d276c32012-01-30 14:33:52 -05002161 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002162 }
2163
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002164 win = new WindowState(this, session, client, token,
Dianne Hackbornc2293022013-02-06 23:14:49 -08002165 attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002166 if (win.mDeathRecipient == null) {
2167 // Client has apparently died, so there is no reason to
2168 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002169 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002170 + " that is dead, aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002171 return WindowManagerGlobal.ADD_APP_EXITING;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002172 }
2173
2174 mPolicy.adjustWindowParamsLw(win.mAttrs);
Craig Mautner88400d32012-09-30 12:35:45 -07002175 win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));
Romain Guy06882f82009-06-10 13:36:04 -07002176
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002177 res = mPolicy.prepareAddWindowLw(win, attrs);
Jeff Brown98365d72012-08-19 20:30:52 -07002178 if (res != WindowManagerGlobal.ADD_OKAY) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002179 return res;
2180 }
Craig Mautner918b53b2012-07-09 14:15:54 -07002181
Jeff Browncc4f7db2011-08-30 20:34:48 -07002182 if (outInputChannel != null && (attrs.inputFeatures
2183 & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002184 String name = win.makeInputChannelName();
2185 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
Jeff Browncc4f7db2011-08-30 20:34:48 -07002186 win.setInputChannel(inputChannels[0]);
Jeff Brown0a0ab122011-08-12 18:08:08 -07002187 inputChannels[1].transferTo(outInputChannel);
Craig Mautner918b53b2012-07-09 14:15:54 -07002188
Jeff Brown928e0542011-01-10 11:17:36 -08002189 mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002190 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002191
2192 // From now on, no exceptions or errors allowed!
2193
Jeff Brown98365d72012-08-19 20:30:52 -07002194 res = WindowManagerGlobal.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002195
Dianne Hackborn5132b372010-07-29 12:51:35 -07002196 origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002198 if (addToken) {
2199 mTokenMap.put(attrs.token, token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002200 }
2201 win.attach();
2202 mWindowMap.put(client.asBinder(), win);
Dianne Hackbornc2293022013-02-06 23:14:49 -08002203 if (win.mAppOp != AppOpsManager.OP_NONE) {
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002204 if (mAppOps.startOpNoThrow(win.mAppOp, win.getOwningUid(), win.getOwningPackage())
2205 != AppOpsManager.MODE_ALLOWED) {
2206 win.setAppOpVisibilityLw(false);
2207 }
Dianne Hackbornc2293022013-02-06 23:14:49 -08002208 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002209
Craig Mautner88400d32012-09-30 12:35:45 -07002210 if (type == TYPE_APPLICATION_STARTING && token.appWindowToken != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002211 token.appWindowToken.startingWindow = win;
Craig Mautner38b24782012-07-02 16:21:28 -07002212 if (DEBUG_STARTING_WINDOW) Slog.v (TAG, "addWindow: " + token.appWindowToken
2213 + " startingWindow=" + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002214 }
2215
2216 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002217
Craig Mautner88400d32012-09-30 12:35:45 -07002218 if (type == TYPE_INPUT_METHOD) {
satok1bc0a492012-04-25 22:47:12 +09002219 win.mGivenInsetsPending = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002220 mInputMethodWindow = win;
2221 addInputMethodWindowToListLocked(win);
2222 imMayMove = false;
Craig Mautner88400d32012-09-30 12:35:45 -07002223 } else if (type == TYPE_INPUT_METHOD_DIALOG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002224 mInputMethodDialogs.add(win);
2225 addWindowToListInOrderLocked(win, true);
2226 adjustInputMethodDialogsLocked();
2227 imMayMove = false;
2228 } else {
2229 addWindowToListInOrderLocked(win, true);
Craig Mautner88400d32012-09-30 12:35:45 -07002230 if (type == TYPE_WALLPAPER) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002231 mLastWallpaperTimeoutTime = 0;
Craig Mautnerae446592012-12-06 19:05:05 -08002232 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002233 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Craig Mautnerae446592012-12-06 19:05:05 -08002234 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborn7ad44382012-10-18 17:46:00 -07002235 } else if (mWallpaperTarget != null
2236 && mWallpaperTarget.mLayer >= win.mBaseLayer) {
2237 // If there is currently a wallpaper being shown, and
2238 // the base layer of the new window is below the current
2239 // layer of the target window, then adjust the wallpaper.
2240 // This is to avoid a new window being placed between the
2241 // wallpaper and its target.
Craig Mautnerae446592012-12-06 19:05:05 -08002242 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002243 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002244 }
Romain Guy06882f82009-06-10 13:36:04 -07002245
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002246 win.mWinAnimator.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002247
Craig Mautner69b08182012-09-05 13:07:13 -07002248 if (displayContent.isDefaultDisplay) {
2249 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
2250 } else {
2251 outContentInsets.setEmpty();
2252 }
Romain Guy06882f82009-06-10 13:36:04 -07002253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002254 if (mInTouchMode) {
Jeff Brown98365d72012-08-19 20:30:52 -07002255 res |= WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002256 }
Craig Mautner764983d2012-03-22 11:37:36 -07002257 if (win.mAppToken == null || !win.mAppToken.clientHidden) {
Jeff Brown98365d72012-08-19 20:30:52 -07002258 res |= WindowManagerGlobal.ADD_FLAG_APP_VISIBLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002259 }
Romain Guy06882f82009-06-10 13:36:04 -07002260
Jeff Brown2e44b072011-01-24 15:21:56 -08002261 mInputMonitor.setUpdateInputWindowsNeededLw();
2262
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002263 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002264 if (win.canReceiveKeys()) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002265 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
2266 false /*updateInputWindows*/);
Jeff Brown349703e2010-06-22 01:27:15 -07002267 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002268 imMayMove = false;
2269 }
2270 }
Romain Guy06882f82009-06-10 13:36:04 -07002271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002272 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002273 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002274 }
Romain Guy06882f82009-06-10 13:36:04 -07002275
Craig Mautner59c00972012-07-30 12:10:24 -07002276 assignLayersLocked(displayContent.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002277 // Don't do layout here, the window must call
2278 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002279
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002280 if (focusChanged) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002281 finishUpdateFocusedWindowAfterAssignLayersLocked(false /*updateInputWindows*/);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002282 }
Jeff Brown2e44b072011-01-24 15:21:56 -08002283 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08002284
Joe Onorato8a9b2202010-02-26 18:56:32 -08002285 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002286 TAG, "New client " + client.asBinder()
2287 + ": window=" + win);
Craig Mautner9e809442012-06-22 17:13:04 -07002288
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002289 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002290 reportNewConfig = true;
2291 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002292 }
2293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002294 if (reportNewConfig) {
2295 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002296 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07002297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002298 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002300 return res;
2301 }
Romain Guy06882f82009-06-10 13:36:04 -07002302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002303 public void removeWindow(Session session, IWindow client) {
2304 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002305 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002306 if (win == null) {
2307 return;
2308 }
2309 removeWindowLocked(session, win);
2310 }
2311 }
Romain Guy06882f82009-06-10 13:36:04 -07002312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002313 public void removeWindowLocked(Session session, WindowState win) {
2314
Joe Onorato8a9b2202010-02-26 18:56:32 -08002315 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002316 TAG, "Remove " + win + " client="
2317 + Integer.toHexString(System.identityHashCode(
2318 win.mClient.asBinder()))
Mathias Agopian29479eb2013-02-14 14:36:04 -08002319 + ", surface=" + win.mWinAnimator.mSurfaceControl);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002320
2321 final long origId = Binder.clearCallingIdentity();
Craig Mautner764983d2012-03-22 11:37:36 -07002322
Jeff Brownc5ed5912010-07-14 18:48:53 -07002323 win.disposeInputChannel();
Romain Guy06882f82009-06-10 13:36:04 -07002324
Joe Onorato8a9b2202010-02-26 18:56:32 -08002325 if (DEBUG_APP_TRANSITIONS) Slog.v(
Mathias Agopian29479eb2013-02-14 14:36:04 -08002326 TAG, "Remove " + win + ": mSurface=" + win.mWinAnimator.mSurfaceControl
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002327 + " mExiting=" + win.mExiting
Craig Mautnera2c77052012-03-26 12:14:43 -07002328 + " isAnimating=" + win.mWinAnimator.isAnimating()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002329 + " app-animation="
Craig Mautner59431632012-04-04 11:56:44 -07002330 + (win.mAppToken != null ? win.mAppToken.mAppAnimator.animation : null)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002331 + " inPendingTransaction="
2332 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2333 + " mDisplayFrozen=" + mDisplayFrozen);
2334 // Visibility of the removed window. Will be used later to update orientation later on.
2335 boolean wasVisible = false;
2336 // First, see if we need to run an animation. If we do, we have
2337 // to hold off on removing the window until the animation is done.
2338 // If the display is frozen, just remove immediately, since the
2339 // animation wouldn't be seen.
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002340 if (win.mHasSurface && okToDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002341 // If we are not currently running the exit animation, we
2342 // need to see about starting one.
Craig Mautner764983d2012-03-22 11:37:36 -07002343 wasVisible = win.isWinVisibleLw();
2344 if (wasVisible) {
Romain Guy06882f82009-06-10 13:36:04 -07002345
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002346 int transit = WindowManagerPolicy.TRANSIT_EXIT;
Craig Mautnerbb1449b2012-03-23 16:11:14 -07002347 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002348 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2349 }
2350 // Try starting an animation.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002351 if (win.mWinAnimator.applyAnimationLocked(transit, false)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002352 win.mExiting = true;
2353 }
Svetoslav Ganov545252f2012-12-10 18:29:24 -08002354 //TODO (multidisplay): Magnification is supported only for the default display.
2355 if (mDisplayMagnifier != null
2356 && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
2357 mDisplayMagnifier.onWindowTransitionLocked(win, transit);
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07002358 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002359 }
Craig Mautnera2c77052012-03-26 12:14:43 -07002360 if (win.mExiting || win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002361 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002362 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002363 win.mExiting = true;
2364 win.mRemoveOnExit = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07002365 win.mDisplayContent.layoutNeeded = true;
Jeff Brown3a22cd92011-01-21 13:59:04 -08002366 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2367 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002368 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08002369 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002370 if (win.mAppToken != null) {
2371 win.mAppToken.updateReportedVisibilityLocked();
2372 }
2373 //dump();
2374 Binder.restoreCallingIdentity(origId);
2375 return;
2376 }
2377 }
2378
2379 removeWindowInnerLocked(session, win);
2380 // Removing a visible window will effect the computed orientation
2381 // So just update orientation if needed.
Craig Mautner2268e7e2012-12-13 15:40:00 -08002382 if (wasVisible && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002383 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002384 }
Jeff Brown3a22cd92011-01-21 13:59:04 -08002385 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002386 Binder.restoreCallingIdentity(origId);
2387 }
Romain Guy06882f82009-06-10 13:36:04 -07002388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002389 private void removeWindowInnerLocked(Session session, WindowState win) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002390 if (win.mRemoved) {
2391 // Nothing to do.
2392 return;
2393 }
2394
2395 for (int i=win.mChildWindows.size()-1; i>=0; i--) {
2396 WindowState cwin = win.mChildWindows.get(i);
2397 Slog.w(TAG, "Force-removing child win " + cwin + " from container "
2398 + win);
2399 removeWindowInnerLocked(cwin.mSession, cwin);
2400 }
2401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002402 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002404 if (mInputMethodTarget == win) {
2405 moveInputMethodWindowsIfNeededLocked(false);
2406 }
Romain Guy06882f82009-06-10 13:36:04 -07002407
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002408 if (false) {
2409 RuntimeException e = new RuntimeException("here");
2410 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002411 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002412 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002413
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002414 mPolicy.removeWindowLw(win);
2415 win.removeLocked();
2416
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002417 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002418 mWindowMap.remove(win.mClient.asBinder());
Dianne Hackbornc2293022013-02-06 23:14:49 -08002419 if (win.mAppOp != AppOpsManager.OP_NONE) {
2420 mAppOps.finishOp(win.mAppOp, win.getOwningUid(), win.getOwningPackage());
2421 }
Craig Mautner59c00972012-07-30 12:10:24 -07002422
2423 final WindowList windows = win.getWindowList();
2424 windows.remove(win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002425 mPendingRemove.remove(win);
Craig Mautner860f6602012-10-18 09:38:10 -07002426 mResizingWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002427 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002428 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002429
2430 if (mInputMethodWindow == win) {
2431 mInputMethodWindow = null;
2432 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2433 mInputMethodDialogs.remove(win);
2434 }
Romain Guy06882f82009-06-10 13:36:04 -07002435
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002436 final WindowToken token = win.mToken;
2437 final AppWindowToken atoken = win.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002438 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + win + " from " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002439 token.windows.remove(win);
2440 if (atoken != null) {
2441 atoken.allAppWindows.remove(win);
2442 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002443 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002444 TAG, "**** Removing window " + win + ": count="
2445 + token.windows.size());
2446 if (token.windows.size() == 0) {
2447 if (!token.explicit) {
2448 mTokenMap.remove(token.token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002449 } else if (atoken != null) {
2450 atoken.firstWindowDrawn = false;
2451 }
2452 }
2453
2454 if (atoken != null) {
2455 if (atoken.startingWindow == win) {
Craig Mautner38b24782012-07-02 16:21:28 -07002456 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling startingWindow " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002457 atoken.startingWindow = null;
2458 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2459 // If this is the last window and we had requested a starting
2460 // transition window, well there is no point now.
Craig Mautner38b24782012-07-02 16:21:28 -07002461 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling last startingWindow");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002462 atoken.startingData = null;
2463 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2464 // If this is the last window except for a starting transition
2465 // window, we need to get rid of the starting transition.
2466 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002467 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002468 + ": no more real windows");
2469 }
2470 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2471 mH.sendMessage(m);
2472 }
2473 }
Romain Guy06882f82009-06-10 13:36:04 -07002474
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002475 if (win.mAttrs.type == TYPE_WALLPAPER) {
2476 mLastWallpaperTimeoutTime = 0;
Craig Mautnerae446592012-12-06 19:05:05 -08002477 getDefaultDisplayContentLocked().pendingLayoutChanges |=
2478 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002479 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Craig Mautnerae446592012-12-06 19:05:05 -08002480 getDefaultDisplayContentLocked().pendingLayoutChanges |=
2481 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002482 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002484 if (!mInLayout) {
Craig Mautner59c00972012-07-30 12:10:24 -07002485 assignLayersLocked(windows);
Craig Mautner19d59bc2012-09-04 11:15:56 -07002486 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002487 performLayoutAndPlaceSurfacesLocked();
2488 if (win.mAppToken != null) {
2489 win.mAppToken.updateReportedVisibilityLocked();
2490 }
2491 }
Craig Mautner9e809442012-06-22 17:13:04 -07002492
Jeff Brown2e44b072011-01-24 15:21:56 -08002493 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002494 }
2495
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002496 public void updateAppOpsState() {
2497 synchronized(mWindowMap) {
Craig Mautner2ad92072013-02-25 16:19:24 -08002498 boolean changed = false;
2499 for (int i=0; i<mDisplayContents.size(); i++) {
2500 DisplayContent display = mDisplayContents.valueAt(i);
2501 WindowList windows = display.getWindowList();
2502 for (int j=0; j<windows.size(); j++) {
2503 final WindowState win = windows.get(j);
2504 if (win.mAppOp != AppOpsManager.OP_NONE) {
2505 changed |= win.setAppOpVisibilityLw(mAppOps.checkOpNoThrow(win.mAppOp,
2506 win.getOwningUid(),
2507 win.getOwningPackage()) == AppOpsManager.MODE_ALLOWED);
2508 }
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002509 }
2510 }
Craig Mautner2ad92072013-02-25 16:19:24 -08002511 if (changed) {
2512 scheduleAnimationLocked();
2513 }
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002514 }
2515 }
2516
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002517 static void logSurface(WindowState w, String msg, RuntimeException where) {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002518 String str = " SURFACE " + msg + ": " + w;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002519 if (where != null) {
2520 Slog.i(TAG, str, where);
2521 } else {
2522 Slog.i(TAG, str);
2523 }
2524 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002525
Mathias Agopian3866f0d2013-02-11 22:08:48 -08002526 static void logSurface(SurfaceControl s, String title, String msg, RuntimeException where) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002527 String str = " SURFACE " + s + ": " + msg + " / " + title;
2528 if (where != null) {
2529 Slog.i(TAG, str, where);
2530 } else {
2531 Slog.i(TAG, str);
2532 }
2533 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07002534
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002535 void setTransparentRegionWindow(Session session, IWindow client, Region region) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002536 long origId = Binder.clearCallingIdentity();
2537 try {
2538 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002539 WindowState w = windowForClientLocked(session, client, false);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002540 if ((w != null) && w.mHasSurface) {
Craig Mautneref655012013-01-03 11:20:24 -08002541 w.mWinAnimator.setTransparentRegionHintLocked(region);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002542 }
2543 }
2544 } finally {
2545 Binder.restoreCallingIdentity(origId);
2546 }
2547 }
2548
2549 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002550 int touchableInsets, Rect contentInsets,
Jeff Brownfbf09772011-01-16 14:06:57 -08002551 Rect visibleInsets, Region touchableRegion) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002552 long origId = Binder.clearCallingIdentity();
2553 try {
2554 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002555 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002556 if (w != null) {
2557 w.mGivenInsetsPending = false;
2558 w.mGivenContentInsets.set(contentInsets);
2559 w.mGivenVisibleInsets.set(visibleInsets);
Jeff Brownfbf09772011-01-16 14:06:57 -08002560 w.mGivenTouchableRegion.set(touchableRegion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002561 w.mTouchableInsets = touchableInsets;
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002562 if (w.mGlobalScale != 1) {
2563 w.mGivenContentInsets.scale(w.mGlobalScale);
2564 w.mGivenVisibleInsets.scale(w.mGlobalScale);
2565 w.mGivenTouchableRegion.scale(w.mGlobalScale);
2566 }
Craig Mautner19d59bc2012-09-04 11:15:56 -07002567 w.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002568 performLayoutAndPlaceSurfacesLocked();
2569 }
2570 }
2571 } finally {
2572 Binder.restoreCallingIdentity(origId);
2573 }
2574 }
Romain Guy06882f82009-06-10 13:36:04 -07002575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002576 public void getWindowDisplayFrame(Session session, IWindow client,
2577 Rect outDisplayFrame) {
2578 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002579 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002580 if (win == null) {
2581 outDisplayFrame.setEmpty();
2582 return;
2583 }
2584 outDisplayFrame.set(win.mDisplayFrame);
2585 }
2586 }
2587
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002588 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2589 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002590 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2591 window.mWallpaperX = x;
2592 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002593 window.mWallpaperXStep = xStep;
2594 window.mWallpaperYStep = yStep;
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002595 updateWallpaperOffsetLocked(window, true);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002596 }
2597 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002598
Dianne Hackborn75804932009-10-20 20:15:20 -07002599 void wallpaperCommandComplete(IBinder window, Bundle result) {
2600 synchronized (mWindowMap) {
2601 if (mWaitingOnWallpaper != null &&
2602 mWaitingOnWallpaper.mClient.asBinder() == window) {
2603 mWaitingOnWallpaper = null;
2604 mWindowMap.notifyAll();
2605 }
2606 }
2607 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002608
Dianne Hackborn75804932009-10-20 20:15:20 -07002609 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2610 String action, int x, int y, int z, Bundle extras, boolean sync) {
2611 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2612 || window == mUpperWallpaperTarget) {
2613 boolean doWait = sync;
2614 int curTokenIndex = mWallpaperTokens.size();
2615 while (curTokenIndex > 0) {
2616 curTokenIndex--;
2617 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2618 int curWallpaperIndex = token.windows.size();
2619 while (curWallpaperIndex > 0) {
2620 curWallpaperIndex--;
2621 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2622 try {
2623 wallpaper.mClient.dispatchWallpaperCommand(action,
2624 x, y, z, extras, sync);
2625 // We only want to be synchronous with one wallpaper.
2626 sync = false;
2627 } catch (RemoteException e) {
2628 }
2629 }
2630 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002631
Dianne Hackborn75804932009-10-20 20:15:20 -07002632 if (doWait) {
2633 // XXX Need to wait for result.
2634 }
2635 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002636
Dianne Hackborn75804932009-10-20 20:15:20 -07002637 return null;
2638 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002639
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002640 public void setUniverseTransformLocked(WindowState window, float alpha,
2641 float offx, float offy, float dsdx, float dtdx, float dsdy, float dtdy) {
2642 Transformation transform = window.mWinAnimator.mUniverseTransform;
2643 transform.setAlpha(alpha);
2644 Matrix matrix = transform.getMatrix();
2645 matrix.getValues(mTmpFloats);
2646 mTmpFloats[Matrix.MTRANS_X] = offx;
2647 mTmpFloats[Matrix.MTRANS_Y] = offy;
2648 mTmpFloats[Matrix.MSCALE_X] = dsdx;
2649 mTmpFloats[Matrix.MSKEW_Y] = dtdx;
2650 mTmpFloats[Matrix.MSKEW_X] = dsdy;
2651 mTmpFloats[Matrix.MSCALE_Y] = dtdy;
2652 matrix.setValues(mTmpFloats);
Craig Mautner59c00972012-07-30 12:10:24 -07002653 final DisplayInfo displayInfo = window.mDisplayContent.getDisplayInfo();
Jeff Brownfa25bf52012-07-23 19:26:30 -07002654 final RectF dispRect = new RectF(0, 0,
Craig Mautner59c00972012-07-30 12:10:24 -07002655 displayInfo.logicalWidth, displayInfo.logicalHeight);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002656 matrix.mapRect(dispRect);
Jeff Brownfa25bf52012-07-23 19:26:30 -07002657 window.mGivenTouchableRegion.set(0, 0,
Craig Mautner59c00972012-07-30 12:10:24 -07002658 displayInfo.logicalWidth, displayInfo.logicalHeight);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002659 window.mGivenTouchableRegion.op((int)dispRect.left, (int)dispRect.top,
2660 (int)dispRect.right, (int)dispRect.bottom, Region.Op.DIFFERENCE);
2661 window.mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
Craig Mautner19d59bc2012-09-04 11:15:56 -07002662 window.mDisplayContent.layoutNeeded = true;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002663 performLayoutAndPlaceSurfacesLocked();
2664 }
2665
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002666 public void onRectangleOnScreenRequested(IBinder token, Rect rectangle, boolean immediate) {
2667 synchronized (mWindowMap) {
Svetoslav Ganov545252f2012-12-10 18:29:24 -08002668 if (mDisplayMagnifier != null) {
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07002669 WindowState window = mWindowMap.get(token);
Svetoslav Ganov545252f2012-12-10 18:29:24 -08002670 //TODO (multidisplay): Magnification is supported only for the default display.
2671 if (window != null && window.getDisplayId() == Display.DEFAULT_DISPLAY) {
2672 mDisplayMagnifier.onRectangleOnScreenRequestedLocked(rectangle, immediate);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002673 }
2674 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002675 }
2676 }
2677
Dianne Hackborne3f23a32013-03-01 13:25:35 -08002678 public IWindowId getWindowId(IBinder token) {
2679 synchronized (mWindowMap) {
2680 WindowState window = mWindowMap.get(token);
2681 return window != null ? window.mWindowId : null;
2682 }
2683 }
2684
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002685 public int relayoutWindow(Session session, IWindow client, int seq,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002686 WindowManager.LayoutParams attrs, int requestedWidth,
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002687 int requestedHeight, int viewVisibility, int flags,
Dianne Hackbornc4aad012013-02-22 15:05:25 -08002688 Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
Dianne Hackborn5c58de32012-04-28 19:52:37 -07002689 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07002690 boolean toBeDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002691 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002692 boolean configChanged;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002693 boolean surfaceChanged = false;
Dianne Hackborn12d3a942012-04-27 14:16:30 -07002694 boolean animating;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002695
2696 // if they don't have this permission, mask out the status bar bits
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002697 int systemUiVisibility = 0;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002698 if (attrs != null) {
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002699 systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
2700 if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -07002701 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
2702 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002703 systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
Dianne Hackborna44abeb2011-08-08 19:24:01 -07002704 }
Joe Onoratoac0ee892011-01-30 15:38:30 -08002705 }
2706 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002707 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002708
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002709 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002710 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002711 if (win == null) {
2712 return 0;
2713 }
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002714 WindowStateAnimator winAnimator = win.mWinAnimator;
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08002715 if (win.mRequestedWidth != requestedWidth
2716 || win.mRequestedHeight != requestedHeight) {
2717 win.mLayoutNeeded = true;
2718 win.mRequestedWidth = requestedWidth;
2719 win.mRequestedHeight = requestedHeight;
2720 }
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002721 if (attrs != null && seq == win.mSeq) {
2722 win.mSystemUiVisibility = systemUiVisibility;
2723 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002724
2725 if (attrs != null) {
2726 mPolicy.adjustWindowParamsLw(attrs);
2727 }
Romain Guy06882f82009-06-10 13:36:04 -07002728
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002729 winAnimator.mSurfaceDestroyDeferred =
Jeff Brown98365d72012-08-19 20:30:52 -07002730 (flags&WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002731
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002732 int attrChanges = 0;
2733 int flagChanges = 0;
2734 if (attrs != null) {
Dianne Hackborn0e60db22011-09-01 11:17:57 -07002735 if (win.mAttrs.type != attrs.type) {
2736 throw new IllegalArgumentException(
2737 "Window type can not be changed after the window is added.");
2738 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002739 flagChanges = win.mAttrs.flags ^= attrs.flags;
2740 attrChanges = win.mAttrs.copyFrom(attrs);
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002741 if ((attrChanges & (WindowManager.LayoutParams.LAYOUT_CHANGED
2742 | WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED)) != 0) {
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08002743 win.mLayoutNeeded = true;
2744 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002745 }
2746
Dianne Hackborn7ff30112012-11-08 11:12:09 -08002747 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": viewVisibility=" + viewVisibility
Chet Haased5d11af2012-10-31 08:57:17 -07002748 + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002749
Dianne Hackborn5fd21692011-06-07 14:09:47 -07002750 win.mEnforceSizeCompat = (win.mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0;
2751
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002752 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002753 winAnimator.mAlpha = attrs.alpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002754 }
2755
2756 final boolean scaledWindow =
2757 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2758
2759 if (scaledWindow) {
2760 // requested{Width|Height} Surface's physical size
2761 // attrs.{width|height} Size on screen
2762 win.mHScale = (attrs.width != requestedWidth) ?
2763 (attrs.width / (float)requestedWidth) : 1.0f;
2764 win.mVScale = (attrs.height != requestedHeight) ?
2765 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002766 } else {
2767 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002768 }
2769
Craig Mautner65d11b32012-10-01 13:59:52 -07002770 boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002771
Craig Mautner69b08182012-09-05 13:07:13 -07002772 final boolean isDefaultDisplay = win.isDefaultDisplay();
2773 boolean focusMayChange = isDefaultDisplay && (win.mViewVisibility != viewVisibility
Craig Mautner65d11b32012-10-01 13:59:52 -07002774 || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0)
Craig Mautner69b08182012-09-05 13:07:13 -07002775 || (!win.mRelayoutCalled));
Romain Guy06882f82009-06-10 13:36:04 -07002776
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002777 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2778 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07002779 wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002780
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002781 win.mRelayoutCalled = true;
2782 final int oldVisibility = win.mViewVisibility;
2783 win.mViewVisibility = viewVisibility;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07002784 if (DEBUG_SCREEN_ON) {
2785 RuntimeException stack = new RuntimeException();
2786 stack.fillInStackTrace();
2787 Slog.i(TAG, "Relayout " + win + ": oldVis=" + oldVisibility
2788 + " newVis=" + viewVisibility, stack);
2789 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002790 if (viewVisibility == View.VISIBLE &&
2791 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07002792 toBeDisplayed = !win.isVisibleLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002793 if (win.mExiting) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002794 winAnimator.cancelExitAnimationForNextAnimationLocked();
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002795 win.mExiting = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002796 }
2797 if (win.mDestroying) {
2798 win.mDestroying = false;
2799 mDestroySurface.remove(win);
2800 }
2801 if (oldVisibility == View.GONE) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002802 winAnimator.mEnterAnimationPending = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002803 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002804 if (toBeDisplayed) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07002805 if (win.isDrawnLw() && okToDisplay()) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002806 winAnimator.applyEnterAnimationLocked();
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002807 }
2808 if ((win.mAttrs.flags
2809 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2810 if (DEBUG_VISIBILITY) Slog.v(TAG,
2811 "Relayout window turning screen on: " + win);
2812 win.mTurnOnScreen = true;
2813 }
Craig Mautnera3f4bf52012-10-10 20:37:48 -07002814 if (win.isConfigChanged()) {
2815 if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + win
Craig Mautnere8552142012-11-07 13:55:47 -08002816 + " visible with new config: " + mCurConfiguration);
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002817 outConfig.setTo(mCurConfiguration);
2818 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002819 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002820 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2821 // To change the format, we need to re-build the surface.
Craig Mautner96868332012-12-04 14:29:11 -08002822 winAnimator.destroySurfaceLocked();
Craig Mautnerbf08af32012-05-16 19:43:42 -07002823 toBeDisplayed = true;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002824 surfaceChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002825 }
2826 try {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002827 if (!win.mHasSurface) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002828 surfaceChanged = true;
2829 }
Mathias Agopian29479eb2013-02-14 14:36:04 -08002830 SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
2831 if (surfaceControl != null) {
2832 outSurface.copyFrom(surfaceControl);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002833 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002834 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002835 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002836 // For some reason there isn't a surface. Clear the
2837 // caller's object so they see the same state.
2838 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002839 }
2840 } catch (Exception e) {
Jeff Brown2e44b072011-01-24 15:21:56 -08002841 mInputMonitor.updateInputWindowsLw(true /*force*/);
Craig Mautner9e809442012-06-22 17:13:04 -07002842
Joe Onorato8a9b2202010-02-26 18:56:32 -08002843 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002844 + client + " (" + win.mAttrs.getTitle() + ")",
2845 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002846 Binder.restoreCallingIdentity(origId);
2847 return 0;
2848 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002849 if (toBeDisplayed) {
Craig Mautner69b08182012-09-05 13:07:13 -07002850 focusMayChange = isDefaultDisplay;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002851 }
2852 if (win.mAttrs.type == TYPE_INPUT_METHOD
2853 && mInputMethodWindow == null) {
2854 mInputMethodWindow = win;
2855 imMayMove = true;
2856 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002857 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2858 && win.mAppToken != null
2859 && win.mAppToken.startingWindow != null) {
2860 // Special handling of starting window over the base
2861 // window of the app: propagate lock screen flags to it,
2862 // to provide the correct semantics while starting.
2863 final int mask =
2864 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002865 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2866 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002867 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2868 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2869 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002870 } else {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002871 winAnimator.mEnterAnimationPending = false;
Mathias Agopian29479eb2013-02-14 14:36:04 -08002872 if (winAnimator.mSurfaceControl != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002873 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Craig Mautnerbf08af32012-05-16 19:43:42 -07002874 + ": mExiting=" + win.mExiting);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002875 // If we are not currently running the exit animation, we
2876 // need to see about starting one.
Craig Mautnerbf08af32012-05-16 19:43:42 -07002877 if (!win.mExiting) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002878 surfaceChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002879 // Try starting an animation; if there isn't one, we
2880 // can destroy the surface right away.
2881 int transit = WindowManagerPolicy.TRANSIT_EXIT;
Craig Mautnerbb1449b2012-03-23 16:11:14 -07002882 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002883 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2884 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002885 if (win.isWinVisibleLw() &&
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002886 winAnimator.applyAnimationLocked(transit, false)) {
Craig Mautner69b08182012-09-05 13:07:13 -07002887 focusMayChange = isDefaultDisplay;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002888 win.mExiting = true;
Craig Mautnera2c77052012-03-26 12:14:43 -07002889 } else if (win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002890 // Currently in a hide animation... turn this into
2891 // an exit.
2892 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002893 } else if (win == mWallpaperTarget) {
2894 // If the wallpaper is currently behind this
2895 // window, we need to change both of them inside
2896 // of a transaction to avoid artifacts.
2897 win.mExiting = true;
Craig Mautnera2c77052012-03-26 12:14:43 -07002898 win.mWinAnimator.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002899 } else {
2900 if (mInputMethodWindow == win) {
2901 mInputMethodWindow = null;
2902 }
Craig Mautner96868332012-12-04 14:29:11 -08002903 winAnimator.destroySurfaceLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002904 }
Svetoslav Ganov545252f2012-12-10 18:29:24 -08002905 //TODO (multidisplay): Magnification is supported only for the default
2906 if (mDisplayMagnifier != null
2907 && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
2908 mDisplayMagnifier.onWindowTransitionLocked(win, transit);
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07002909 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002910 }
2911 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002912
Craig Mautnerbf08af32012-05-16 19:43:42 -07002913 outSurface.release();
2914 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002915 }
2916
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002917 if (focusMayChange) {
2918 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
Jeff Brown3a22cd92011-01-21 13:59:04 -08002919 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2920 false /*updateInputWindows*/)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002921 imMayMove = false;
2922 }
2923 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2924 }
Romain Guy06882f82009-06-10 13:36:04 -07002925
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002926 // updateFocusedWindowLocked() already assigned layers so we only need to
2927 // reassign them at this point if the IM window state gets shuffled
Craig Mautnerb5eb5502013-01-10 17:29:30 -08002928 if (imMayMove && (moveInputMethodWindowsIfNeededLocked(false) || toBeDisplayed)) {
2929 // Little hack here -- we -should- be able to rely on the
2930 // function to return true if the IME has moved and needs
2931 // its layer recomputed. However, if the IME was hidden
2932 // and isn't actually moved in the list, its layer may be
2933 // out of data so we make sure to recompute it.
2934 assignLayersLocked(win.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002935 }
Craig Mautnerb5eb5502013-01-10 17:29:30 -08002936
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002937 if (wallpaperMayMove) {
Craig Mautnerae446592012-12-06 19:05:05 -08002938 getDefaultDisplayContentLocked().pendingLayoutChanges |=
2939 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002940 }
Romain Guy06882f82009-06-10 13:36:04 -07002941
Craig Mautner19d59bc2012-09-04 11:15:56 -07002942 win.mDisplayContent.layoutNeeded = true;
Jeff Brown98365d72012-08-19 20:30:52 -07002943 win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002944 configChanged = updateOrientationFromAppTokensLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002945 performLayoutAndPlaceSurfacesLocked();
Craig Mautnerbf08af32012-05-16 19:43:42 -07002946 if (toBeDisplayed && win.mIsWallpaper) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07002947 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Jeff Brownfa25bf52012-07-23 19:26:30 -07002948 updateWallpaperOffsetLocked(win,
Craig Mautner59c00972012-07-30 12:10:24 -07002949 displayInfo.appWidth, displayInfo.appHeight, false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002950 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002951 if (win.mAppToken != null) {
2952 win.mAppToken.updateReportedVisibilityLocked();
2953 }
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002954 outFrame.set(win.mCompatFrame);
Dianne Hackbornc4aad012013-02-22 15:05:25 -08002955 outOverscanInsets.set(win.mOverscanInsets);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002956 outContentInsets.set(win.mContentInsets);
2957 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002958 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002959 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002960 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002961 + ", requestedHeight=" + requestedHeight
2962 + ", viewVisibility=" + viewVisibility
2963 + "\nRelayout returning frame=" + outFrame
2964 + ", surface=" + outSurface);
2965
Joe Onorato8a9b2202010-02-26 18:56:32 -08002966 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002967 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
2968
2969 inTouchMode = mInTouchMode;
Dianne Hackborn12d3a942012-04-27 14:16:30 -07002970 animating = mAnimator.mAnimating;
2971 if (animating && !mRelayoutWhileAnimating.contains(win)) {
2972 mRelayoutWhileAnimating.add(win);
2973 }
2974
Jeff Brown2e44b072011-01-24 15:21:56 -08002975 mInputMonitor.updateInputWindowsLw(true /*force*/);
Chet Haased5d11af2012-10-31 08:57:17 -07002976
2977 if (DEBUG_LAYOUT) {
2978 Slog.v(TAG, "Relayout complete " + win + ": outFrame=" + outFrame.toShortString());
2979 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002980 }
2981
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002982 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002983 sendNewConfiguration();
2984 }
Romain Guy06882f82009-06-10 13:36:04 -07002985
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002986 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002987
Jeff Brown98365d72012-08-19 20:30:52 -07002988 return (inTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0)
2989 | (toBeDisplayed ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0)
2990 | (surfaceChanged ? WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED : 0)
2991 | (animating ? WindowManagerGlobal.RELAYOUT_RES_ANIMATING : 0);
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002992 }
2993
2994 public void performDeferredDestroyWindow(Session session, IWindow client) {
2995 long origId = Binder.clearCallingIdentity();
2996
2997 try {
Craig Mautnerae446592012-12-06 19:05:05 -08002998 synchronized (mWindowMap) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002999 WindowState win = windowForClientLocked(session, client, false);
3000 if (win == null) {
3001 return;
3002 }
Craig Mautner96868332012-12-04 14:29:11 -08003003 win.mWinAnimator.destroyDeferredSurfaceLocked();
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003004 }
3005 } finally {
3006 Binder.restoreCallingIdentity(origId);
3007 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003008 }
3009
Dianne Hackborn64825172011-03-02 21:32:58 -08003010 public boolean outOfMemoryWindow(Session session, IWindow client) {
3011 long origId = Binder.clearCallingIdentity();
3012
3013 try {
Craig Mautnerae446592012-12-06 19:05:05 -08003014 synchronized (mWindowMap) {
Dianne Hackborn64825172011-03-02 21:32:58 -08003015 WindowState win = windowForClientLocked(session, client, false);
3016 if (win == null) {
3017 return false;
3018 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003019 return reclaimSomeSurfaceMemoryLocked(win.mWinAnimator, "from-client", false);
Dianne Hackborn64825172011-03-02 21:32:58 -08003020 }
3021 } finally {
3022 Binder.restoreCallingIdentity(origId);
3023 }
3024 }
3025
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003026 public void finishDrawingWindow(Session session, IWindow client) {
3027 final long origId = Binder.clearCallingIdentity();
Craig Mautneref655012013-01-03 11:20:24 -08003028 try {
3029 synchronized (mWindowMap) {
3030 WindowState win = windowForClientLocked(session, client, false);
3031 if (win != null && win.mWinAnimator.finishDrawingLocked()) {
3032 if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
3033 getDefaultDisplayContentLocked().pendingLayoutChanges |=
3034 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
3035 }
3036 win.mDisplayContent.layoutNeeded = true;
3037 requestTraversalLocked();
Dianne Hackborn759a39e2009-08-09 17:20:27 -07003038 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003039 }
Craig Mautneref655012013-01-03 11:20:24 -08003040 } finally {
3041 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003042 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003043 }
3044
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003045 @Override
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07003046 public void getWindowFrame(IBinder token, Rect outBounds) {
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003047 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
3048 "getWindowInfo()")) {
3049 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
3050 }
3051 synchronized (mWindowMap) {
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07003052 WindowState windowState = mWindowMap.get(token);
3053 if (windowState != null) {
3054 outBounds.set(windowState.mFrame);
3055 } else {
3056 outBounds.setEmpty();
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003057 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003058 }
3059 }
3060
3061 @Override
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003062 public void setMagnificationSpec(MagnificationSpec spec) {
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07003063 if (!checkCallingPermission(android.Manifest.permission.MAGNIFY_DISPLAY,
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003064 "setMagnificationSpec()")) {
3065 throw new SecurityException("Requires MAGNIFY_DISPLAY permission.");
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003066 }
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003067 synchronized (mWindowMap) {
3068 if (mDisplayMagnifier != null) {
3069 mDisplayMagnifier.setMagnificationSpecLocked(spec);
3070 } else {
3071 throw new IllegalStateException("Magnification callbacks not set!");
3072 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003073 }
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003074 if (Binder.getCallingPid() != android.os.Process.myPid()) {
3075 spec.recycle();
3076 }
3077 }
3078
3079 @Override
3080 public MagnificationSpec getCompatibleMagnificationSpecForWindow(IBinder windowToken) {
3081 if (!checkCallingPermission(android.Manifest.permission.MAGNIFY_DISPLAY,
3082 "getCompatibleMagnificationSpecForWindow()")) {
3083 throw new SecurityException("Requires MAGNIFY_DISPLAY permission.");
3084 }
3085 synchronized (mWindowMap) {
3086 WindowState windowState = mWindowMap.get(windowToken);
3087 if (windowState == null) {
3088 return null;
3089 }
3090 MagnificationSpec spec = null;
3091 if (mDisplayMagnifier != null) {
3092 spec = mDisplayMagnifier.getMagnificationSpecForWindowLocked(windowState);
3093 }
3094 if ((spec == null || spec.isNop()) && windowState.mGlobalScale == 1.0f) {
3095 return null;
3096 }
3097 spec = (spec == null) ? MagnificationSpec.obtain() : MagnificationSpec.obtain(spec);
3098 spec.scale *= windowState.mGlobalScale;
3099 return spec;
3100 }
3101 }
3102
3103 @Override
3104 public void setMagnificationCallbacks(IMagnificationCallbacks callbacks) {
3105 if (!checkCallingPermission(android.Manifest.permission.MAGNIFY_DISPLAY,
3106 "setMagnificationCallbacks()")) {
3107 throw new SecurityException("Requires MAGNIFY_DISPLAY permission.");
3108 }
3109 synchronized (mWindowMap) {
3110 if (mDisplayMagnifier == null) {
3111 mDisplayMagnifier = new DisplayMagnifier(this, callbacks);
3112 } else {
3113 if (callbacks == null) {
Svetoslavcb9a61b2013-01-22 18:11:42 -08003114 if (mDisplayMagnifier != null) {
3115 mDisplayMagnifier.destroyLocked();
3116 mDisplayMagnifier = null;
3117 }
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003118 } else {
3119 throw new IllegalStateException("Magnification callbacks already set!");
3120 }
3121 }
3122 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003123 }
3124
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003125 private boolean applyAnimationLocked(AppWindowToken atoken,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07003126 WindowManager.LayoutParams lp, int transit, boolean enter) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003127 // Only apply an animation if the display isn't frozen. If it is
3128 // frozen, there is no reason to animate and it can cause strange
3129 // artifacts when we unfreeze the display if some different animation
3130 // is running.
Craig Mautner2fb98b12012-03-20 17:24:00 -07003131 if (okToDisplay()) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003132 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Craig Mautner9339c402012-11-30 11:23:56 -08003133 final int width = displayInfo.appWidth;
3134 final int height = displayInfo.appHeight;
Craig Mautner164d4bb2012-11-26 13:51:23 -08003135 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "applyAnimation: atoken="
3136 + atoken);
Craig Mautner9339c402012-11-30 11:23:56 -08003137 Animation a = mAppTransition.loadAnimation(lp, transit, enter, width, height);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003138 if (a != null) {
3139 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003140 RuntimeException e = null;
3141 if (!HIDE_STACK_CRAWLS) {
3142 e = new RuntimeException();
3143 e.fillInStackTrace();
3144 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003145 Slog.v(TAG, "Loaded animation " + a + " for " + atoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003146 }
Craig Mautner9339c402012-11-30 11:23:56 -08003147 atoken.mAppAnimator.setAnimation(a, width, height);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003148 }
3149 } else {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003150 atoken.mAppAnimator.clearAnimation();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003151 }
3152
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003153 return atoken.mAppAnimator.animation != null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003154 }
3155
3156 // -------------------------------------------------------------
3157 // Application Window Tokens
3158 // -------------------------------------------------------------
3159
Craig Mautner2ad92072013-02-25 16:19:24 -08003160 public void validateAppTokens(List<IBinder> tokens) {
3161 int v = tokens.size()-1;
3162 int m = mAppTokens.size()-1;
3163 while (v >= 0 && m >= 0) {
3164 AppWindowToken atoken = mAppTokens.get(m);
3165 if (atoken.removed) {
3166 m--;
3167 continue;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08003168 }
Craig Mautner2ad92072013-02-25 16:19:24 -08003169 if (tokens.get(v) != atoken.token) {
3170 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
3171 + " @ " + v + ", internal is " + atoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003172 }
Craig Mautner2ad92072013-02-25 16:19:24 -08003173 v--;
3174 m--;
3175 }
3176 while (v >= 0) {
3177 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
3178 v--;
3179 }
3180 while (m >= 0) {
3181 AppWindowToken atoken = mAppTokens.get(m);
3182 if (!atoken.removed) {
3183 Slog.w(TAG, "Invalid internal atoken: " + atoken.token + " @ " + m);
Craig Mautner343ad712013-02-13 22:37:26 -08003184 }
Craig Mautner2ad92072013-02-25 16:19:24 -08003185 m--;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003186 }
3187 }
3188
3189 boolean checkCallingPermission(String permission, String func) {
3190 // Quick check: if the calling permission is me, it's all okay.
3191 if (Binder.getCallingPid() == Process.myPid()) {
3192 return true;
3193 }
Romain Guy06882f82009-06-10 13:36:04 -07003194
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003195 if (mContext.checkCallingPermission(permission)
3196 == PackageManager.PERMISSION_GRANTED) {
3197 return true;
3198 }
3199 String msg = "Permission Denial: " + func + " from pid="
3200 + Binder.getCallingPid()
3201 + ", uid=" + Binder.getCallingUid()
3202 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003203 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003204 return false;
3205 }
Craig Mautner9e809442012-06-22 17:13:04 -07003206
Craig Mautner2fb98b12012-03-20 17:24:00 -07003207 boolean okToDisplay() {
3208 return !mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully();
3209 }
Romain Guy06882f82009-06-10 13:36:04 -07003210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003211 AppWindowToken findAppWindowToken(IBinder token) {
3212 WindowToken wtoken = mTokenMap.get(token);
3213 if (wtoken == null) {
3214 return null;
3215 }
3216 return wtoken.appWindowToken;
3217 }
Romain Guy06882f82009-06-10 13:36:04 -07003218
Craig Mautnercf8cbbe2012-03-25 21:54:36 -07003219 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003220 public void addWindowToken(IBinder token, int type) {
3221 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3222 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003223 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003224 }
Romain Guy06882f82009-06-10 13:36:04 -07003225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003226 synchronized(mWindowMap) {
3227 WindowToken wtoken = mTokenMap.get(token);
3228 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003229 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003230 return;
3231 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003232 wtoken = new WindowToken(this, token, type, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003233 mTokenMap.put(token, wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003234 if (type == TYPE_WALLPAPER) {
3235 mWallpaperTokens.add(wtoken);
3236 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003237 }
3238 }
Romain Guy06882f82009-06-10 13:36:04 -07003239
Craig Mautner9e809442012-06-22 17:13:04 -07003240 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003241 public void removeWindowToken(IBinder token) {
3242 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3243 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003244 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003245 }
3246
3247 final long origId = Binder.clearCallingIdentity();
3248 synchronized(mWindowMap) {
3249 WindowToken wtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003250 if (wtoken != null) {
3251 boolean delayed = false;
3252 if (!wtoken.hidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003253 final int N = wtoken.windows.size();
3254 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003256 for (int i=0; i<N; i++) {
3257 WindowState win = wtoken.windows.get(i);
3258
Craig Mautnera2c77052012-03-26 12:14:43 -07003259 if (win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003260 delayed = true;
3261 }
Romain Guy06882f82009-06-10 13:36:04 -07003262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003263 if (win.isVisibleNow()) {
Craig Mautner59c00972012-07-30 12:10:24 -07003264 win.mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT,
3265 false);
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003266 //TODO (multidisplay): Magnification is supported only for the default
Craig Mautner2ad92072013-02-25 16:19:24 -08003267 if (mDisplayMagnifier != null
3268 && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003269 mDisplayMagnifier.onWindowTransitionLocked(win,
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07003270 WindowManagerPolicy.TRANSIT_EXIT);
3271 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003272 changed = true;
Craig Mautner2ad92072013-02-25 16:19:24 -08003273 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003274 }
3275 }
3276
Craig Mautner4b5aa782012-10-02 18:11:25 -07003277 wtoken.hidden = true;
3278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003279 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003280 performLayoutAndPlaceSurfacesLocked();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003281 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
3282 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003283 }
Romain Guy06882f82009-06-10 13:36:04 -07003284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003285 if (delayed) {
Craig Mautner2ad92072013-02-25 16:19:24 -08003286 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003287 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3288 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003289 }
3290 }
Romain Guy06882f82009-06-10 13:36:04 -07003291
Jeff Brown2e44b072011-01-24 15:21:56 -08003292 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003293 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003294 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003295 }
3296 }
3297 Binder.restoreCallingIdentity(origId);
3298 }
3299
Craig Mautner2ad92072013-02-25 16:19:24 -08003300 /**
3301 * Find the location to insert a new AppWindowToken into the window-ordered app token list.
3302 * Note that mAppTokens.size() == mAnimatingAppTokens.size() + 1.
3303 * @param addPos The location the token was inserted into in mAppTokens.
3304 * @param atoken The token to insert.
3305 */
3306 private void addAppTokenToAnimating(final int addPos, final AppWindowToken atoken) {
3307 if (addPos == 0 || addPos == mAnimatingAppTokens.size()) {
3308 // It was inserted into the beginning or end of mAppTokens. Honor that.
3309 mAnimatingAppTokens.add(addPos, atoken);
3310 return;
3311 }
3312 // Find the item immediately above the mAppTokens insertion point and put the token
3313 // immediately below that one in mAnimatingAppTokens.
3314 final AppWindowToken aboveAnchor = mAppTokens.get(addPos + 1);
3315 mAnimatingAppTokens.add(mAnimatingAppTokens.indexOf(aboveAnchor), atoken);
3316 }
3317
Craig Mautneref25d7a2012-05-15 23:01:47 -07003318 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003319 public void addAppToken(int addPos, IApplicationToken token,
Craig Mautner2ad92072013-02-25 16:19:24 -08003320 int groupId, int requestedOrientation, boolean fullscreen, boolean showWhenLocked) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003321 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3322 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003323 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003324 }
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07003325
Jeff Brown349703e2010-06-22 01:27:15 -07003326 // Get the dispatching timeout here while we are not holding any locks so that it
3327 // can be cached by the AppWindowToken. The timeout value is used later by the
3328 // input dispatcher in code that does hold locks. If we did not cache the value
3329 // here we would run the chance of introducing a deadlock between the window manager
3330 // (which holds locks while updating the input dispatcher state) and the activity manager
3331 // (which holds locks while querying the application token).
3332 long inputDispatchingTimeoutNanos;
3333 try {
3334 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3335 } catch (RemoteException ex) {
3336 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3337 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3338 }
Romain Guy06882f82009-06-10 13:36:04 -07003339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003340 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003341 AppWindowToken atoken = findAppWindowToken(token.asBinder());
3342 if (atoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003343 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003344 return;
3345 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003346 atoken = new AppWindowToken(this, token);
3347 atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
Craig Mautner2ad92072013-02-25 16:19:24 -08003348 atoken.groupId = groupId;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003349 atoken.appFullscreen = fullscreen;
Craig Mautner5962b122012-10-05 14:45:52 -07003350 atoken.showWhenLocked = showWhenLocked;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003351 atoken.requestedOrientation = requestedOrientation;
3352 if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + atoken
Craig Mautner06a94f72012-05-29 10:46:00 -07003353 + " at " + addPos);
Craig Mautner2ad92072013-02-25 16:19:24 -08003354 mAppTokens.add(addPos, atoken);
3355 addAppTokenToAnimating(addPos, atoken);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003356 mTokenMap.put(token.asBinder(), atoken);
Romain Guy06882f82009-06-10 13:36:04 -07003357
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003358 // Application tokens start out hidden.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003359 atoken.hidden = true;
3360 atoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003361
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003362 //dump();
3363 }
3364 }
Romain Guy06882f82009-06-10 13:36:04 -07003365
Craig Mautner9e809442012-06-22 17:13:04 -07003366 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003367 public void setAppGroupId(IBinder token, int groupId) {
3368 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner6fbda632012-07-03 09:26:39 -07003369 "setAppGroupId()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003370 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003371 }
3372
3373 synchronized(mWindowMap) {
Craig Mautner2ad92072013-02-25 16:19:24 -08003374 AppWindowToken atoken = findAppWindowToken(token);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003375 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003376 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003377 return;
3378 }
Craig Mautner2ad92072013-02-25 16:19:24 -08003379 atoken.groupId = groupId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003380 }
3381 }
Romain Guy06882f82009-06-10 13:36:04 -07003382
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003383 public int getOrientationFromWindowsLocked() {
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003384 if (mDisplayFrozen || mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
3385 // If the display is frozen, some activities may be in the middle
3386 // of restarting, and thus have removed their old window. If the
3387 // window has the flag to hide the lock screen, then the lock screen
3388 // can re-appear and inflict its own orientation on us. Keep the
3389 // orientation stable until this all settles down.
3390 return mLastWindowForcedOrientation;
3391 }
3392
Craig Mautner59c00972012-07-30 12:10:24 -07003393 // TODO(multidisplay): Change to the correct display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003394 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07003395 int pos = windows.size() - 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003396 while (pos >= 0) {
Craig Mautnere8552142012-11-07 13:55:47 -08003397 WindowState win = windows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003398 pos--;
Craig Mautnere8552142012-11-07 13:55:47 -08003399 if (win.mAppToken != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003400 // We hit an application window. so the orientation will be determined by the
3401 // app window. No point in continuing further.
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003402 return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003403 }
Craig Mautnere8552142012-11-07 13:55:47 -08003404 if (!win.isVisibleLw() || !win.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003405 continue;
3406 }
Craig Mautnere8552142012-11-07 13:55:47 -08003407 int req = win.mAttrs.screenOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003408 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3409 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3410 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003411 }
Craig Mautner9e809442012-06-22 17:13:04 -07003412
Craig Mautnere8552142012-11-07 13:55:47 -08003413 if (DEBUG_ORIENTATION) Slog.v(TAG, win + " forcing orientation to " + req);
Craig Mautner9e809442012-06-22 17:13:04 -07003414 return (mLastWindowForcedOrientation=req);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003415 }
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003416 return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003417 }
Romain Guy06882f82009-06-10 13:36:04 -07003418
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003419 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003420 int curGroup = 0;
3421 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3422 boolean findingBehind = false;
3423 boolean haveGroup = false;
3424 boolean lastFullscreen = false;
Craig Mautner2ad92072013-02-25 16:19:24 -08003425 for (int pos = mAppTokens.size() - 1; pos >= 0; pos--) {
3426 AppWindowToken atoken = mAppTokens.get(pos);
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003427
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003428 if (DEBUG_APP_ORIENTATION) Slog.v(TAG, "Checking app orientation: " + atoken);
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003429
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003430 // if we're about to tear down this window and not seek for
3431 // the behind activity, don't use it for orientation
3432 if (!findingBehind
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003433 && (!atoken.hidden && atoken.hiddenRequested)) {
3434 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003435 + " -- going to hide");
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003436 continue;
3437 }
3438
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003439 if (haveGroup == true && curGroup != atoken.groupId) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003440 // If we have hit a new application group, and the bottom
3441 // of the previous group didn't explicitly say to use
3442 // the orientation behind it, and the last app was
3443 // full screen, then we'll stick with the
3444 // user's orientation.
3445 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3446 && lastFullscreen) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003447 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003448 + " -- end of group, return " + lastOrientation);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003449 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003450 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003451 }
p134510445bc62012-04-18 15:13:26 +09003452
3453 // We ignore any hidden applications on the top.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003454 if (atoken.hiddenRequested || atoken.willBeHidden) {
3455 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
p134510445bc62012-04-18 15:13:26 +09003456 + " -- hidden on top");
3457 continue;
3458 }
3459
3460 if (!haveGroup) {
3461 haveGroup = true;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003462 curGroup = atoken.groupId;
3463 lastOrientation = atoken.requestedOrientation;
Craig Mautner918b53b2012-07-09 14:15:54 -07003464 }
p134510445bc62012-04-18 15:13:26 +09003465
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003466 int or = atoken.requestedOrientation;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003467 // If this application is fullscreen, and didn't explicitly say
3468 // to use the orientation behind it, then just take whatever
3469 // orientation it has and ignores whatever is under it.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003470 lastFullscreen = atoken.appFullscreen;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003471 if (lastFullscreen
3472 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003473 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003474 + " -- full screen, return " + or);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003475 return or;
3476 }
3477 // If this application has requested an explicit orientation,
3478 // then use it.
Dianne Hackborne5439f22010-10-02 16:53:50 -07003479 if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
3480 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003481 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003482 + " -- explicitly set, return " + or);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003483 return or;
3484 }
3485 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3486 }
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003487 if (DEBUG_ORIENTATION) Slog.v(TAG, "No app is requesting an orientation");
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003488 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003489 }
Romain Guy06882f82009-06-10 13:36:04 -07003490
Craig Mautner711f90a2012-07-03 18:43:52 -07003491 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003492 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003493 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003494 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3495 "updateOrientationFromAppTokens()")) {
3496 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3497 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003498
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003499 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003500 long ident = Binder.clearCallingIdentity();
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003501
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003502 synchronized(mWindowMap) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003503 config = updateOrientationFromAppTokensLocked(currentConfig,
3504 freezeThisOneIfNeeded);
3505 }
3506
3507 Binder.restoreCallingIdentity(ident);
3508 return config;
3509 }
3510
3511 private Configuration updateOrientationFromAppTokensLocked(
3512 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
3513 Configuration config = null;
3514
3515 if (updateOrientationFromAppTokensLocked(false)) {
3516 if (freezeThisOneIfNeeded != null) {
Craig Mautner2268e7e2012-12-13 15:40:00 -08003517 AppWindowToken atoken = findAppWindowToken(freezeThisOneIfNeeded);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003518 if (atoken != null) {
Craig Mautner2268e7e2012-12-13 15:40:00 -08003519 startAppFreezingScreenLocked(atoken, ActivityInfo.CONFIG_ORIENTATION);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003520 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003521 }
3522 config = computeNewConfigurationLocked();
3523
3524 } else if (currentConfig != null) {
3525 // No obvious action we need to take, but if our current
3526 // state mismatches the activity manager's, update it,
3527 // disregarding font scale, which should remain set to
3528 // the value of the previous configuration.
3529 mTempConfiguration.setToDefaults();
3530 mTempConfiguration.fontScale = currentConfig.fontScale;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08003531 if (computeScreenConfigurationLocked(mTempConfiguration)) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003532 if (currentConfig.diff(mTempConfiguration) != 0) {
3533 mWaitingForConfig = true;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003534 getDefaultDisplayContentLocked().layoutNeeded = true;
Craig Mautner3c174372013-02-21 17:54:37 -08003535 int anim[] = new int[2];
3536 if (mAnimator.isDimmingLocked(Display.DEFAULT_DISPLAY)) {
3537 anim[0] = anim[1] = 0;
3538 } else {
3539 mPolicy.selectRotationAnimationLw(anim);
3540 }
3541 startFreezingDisplayLocked(false, anim[0], anim[1]);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003542 config = new Configuration(mTempConfiguration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003543 }
3544 }
3545 }
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003546
Dianne Hackborncfaef692009-06-15 14:24:44 -07003547 return config;
3548 }
3549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003550 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003551 * Determine the new desired orientation of the display, returning
3552 * a non-null new Configuration if it has changed from the current
3553 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3554 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3555 * SCREEN. This will typically be done for you if you call
3556 * sendNewConfiguration().
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003557 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003558 * The orientation is computed from non-application windows first. If none of
3559 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003560 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003561 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3562 * android.os.IBinder)
3563 */
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003564 boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003565 long ident = Binder.clearCallingIdentity();
3566 try {
Craig Mautner2268e7e2012-12-13 15:40:00 -08003567 int req = getOrientationFromWindowsLocked();
3568 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3569 req = getOrientationFromAppTokensLocked();
3570 }
Romain Guy06882f82009-06-10 13:36:04 -07003571
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003572 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003573 mForcedAppOrientation = req;
3574 //send a message to Policy indicating orientation change to take
3575 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003576 mPolicy.setCurrentOrientationLw(req);
Jeff Brown01a98dd2011-09-20 15:08:29 -07003577 if (updateRotationUncheckedLocked(inTransaction)) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003578 // changed
3579 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003580 }
3581 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003582
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003583 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003584 } finally {
3585 Binder.restoreCallingIdentity(ident);
3586 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003587 }
Romain Guy06882f82009-06-10 13:36:04 -07003588
Craig Mautner918b53b2012-07-09 14:15:54 -07003589 @Override
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003590 public void setNewConfiguration(Configuration config) {
3591 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3592 "setNewConfiguration()")) {
3593 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3594 }
3595
3596 synchronized(mWindowMap) {
3597 mCurConfiguration = new Configuration(config);
Dianne Hackborna57c6952013-03-29 14:46:40 -07003598 if (mWaitingForConfig) {
3599 mWaitingForConfig = false;
3600 mLastFinishedFreezeSource = "new-config";
3601 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003602 performLayoutAndPlaceSurfacesLocked();
3603 }
3604 }
Craig Mautner918b53b2012-07-09 14:15:54 -07003605
3606 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003607 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3608 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3609 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003610 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003611 }
Romain Guy06882f82009-06-10 13:36:04 -07003612
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003613 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003614 AppWindowToken atoken = findAppWindowToken(token.asBinder());
3615 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003616 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003617 return;
3618 }
Romain Guy06882f82009-06-10 13:36:04 -07003619
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003620 atoken.requestedOrientation = requestedOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003621 }
3622 }
Romain Guy06882f82009-06-10 13:36:04 -07003623
Craig Mautner76a71652012-09-03 23:23:58 -07003624 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003625 public int getAppOrientation(IApplicationToken token) {
3626 synchronized(mWindowMap) {
3627 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3628 if (wtoken == null) {
3629 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3630 }
Romain Guy06882f82009-06-10 13:36:04 -07003631
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003632 return wtoken.requestedOrientation;
3633 }
3634 }
Romain Guy06882f82009-06-10 13:36:04 -07003635
Craig Mautner76a71652012-09-03 23:23:58 -07003636 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003637 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3638 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3639 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003640 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003641 }
3642
3643 synchronized(mWindowMap) {
3644 boolean changed = false;
3645 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003646 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003647 changed = mFocusedApp != null;
3648 mFocusedApp = null;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003649 if (changed) {
3650 mInputMonitor.setFocusedAppLw(null);
Jeff Brown349703e2010-06-22 01:27:15 -07003651 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003652 } else {
3653 AppWindowToken newFocus = findAppWindowToken(token);
3654 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003655 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003656 return;
3657 }
3658 changed = mFocusedApp != newFocus;
3659 mFocusedApp = newFocus;
Craig Mautner812d2ca2012-09-27 15:35:34 -07003660 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp
3661 + " moveFocusNow=" + moveFocusNow);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003662 if (changed) {
3663 mInputMonitor.setFocusedAppLw(newFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07003664 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003665 }
3666
3667 if (moveFocusNow && changed) {
3668 final long origId = Binder.clearCallingIdentity();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003669 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003670 Binder.restoreCallingIdentity(origId);
3671 }
3672 }
3673 }
3674
Craig Mautner76a71652012-09-03 23:23:58 -07003675 @Override
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003676 public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003677 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3678 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003679 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003680 }
Romain Guy06882f82009-06-10 13:36:04 -07003681
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003682 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003683 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003684 TAG, "Prepare app transition: transit=" + transit
Craig Mautner164d4bb2012-11-26 13:51:23 -08003685 + " " + mAppTransition
Craig Mautner1d961d42012-05-27 12:02:11 -07003686 + " alwaysKeepCurrent=" + alwaysKeepCurrent
Craig Mautneref25d7a2012-05-15 23:01:47 -07003687 + " Callers=" + Debug.getCallers(3));
Craig Mautner2fb98b12012-03-20 17:24:00 -07003688 if (okToDisplay()) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003689 if (!mAppTransition.isTransitionSet() || mAppTransition.isTransitionNone()) {
3690 mAppTransition.setAppTransition(transit);
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003691 } else if (!alwaysKeepCurrent) {
Craig Mautner4b71aa12012-12-27 17:20:01 -08003692 if (transit == AppTransition.TRANSIT_TASK_OPEN
Craig Mautner164d4bb2012-11-26 13:51:23 -08003693 && mAppTransition.isTransitionEqual(
Craig Mautner4b71aa12012-12-27 17:20:01 -08003694 AppTransition.TRANSIT_TASK_CLOSE)) {
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003695 // Opening a new task always supersedes a close for the anim.
Craig Mautner164d4bb2012-11-26 13:51:23 -08003696 mAppTransition.setAppTransition(transit);
Craig Mautner4b71aa12012-12-27 17:20:01 -08003697 } else if (transit == AppTransition.TRANSIT_ACTIVITY_OPEN
Craig Mautner164d4bb2012-11-26 13:51:23 -08003698 && mAppTransition.isTransitionEqual(
Craig Mautner4b71aa12012-12-27 17:20:01 -08003699 AppTransition.TRANSIT_ACTIVITY_CLOSE)) {
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003700 // Opening a new activity always supersedes a close for the anim.
Craig Mautner164d4bb2012-11-26 13:51:23 -08003701 mAppTransition.setAppTransition(transit);
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003702 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003703 }
Craig Mautner164d4bb2012-11-26 13:51:23 -08003704 mAppTransition.prepare();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003705 mStartingIconInTransition = false;
3706 mSkipAppTransitionAnimation = false;
3707 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
You Kimcb6291c2012-12-04 23:22:28 +09003708 mH.sendEmptyMessageDelayed(H.APP_TRANSITION_TIMEOUT, 5000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003709 }
3710 }
3711 }
3712
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003713 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003714 public int getPendingAppTransition() {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003715 return mAppTransition.getAppTransition();
Dianne Hackborn84375872012-06-01 19:03:50 -07003716 }
3717
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003718 @Override
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003719 public void overridePendingAppTransition(String packageName,
Dianne Hackborn84375872012-06-01 19:03:50 -07003720 int enterAnim, int exitAnim, IRemoteCallback startedCallback) {
3721 synchronized(mWindowMap) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003722 mAppTransition.overridePendingAppTransition(packageName, enterAnim, exitAnim,
3723 startedCallback);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003724 }
3725 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003726
Craig Mautnera91f9e22012-09-14 16:22:08 -07003727 @Override
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003728 public void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
3729 int startHeight) {
Dianne Hackborn84375872012-06-01 19:03:50 -07003730 synchronized(mWindowMap) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003731 mAppTransition.overridePendingAppTransitionScaleUp(startX, startY, startWidth,
3732 startHeight);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003733 }
3734 }
3735
Craig Mautnera91f9e22012-09-14 16:22:08 -07003736 @Override
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003737 public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX,
Michael Jurka832cb222012-04-13 09:32:47 -07003738 int startY, IRemoteCallback startedCallback, boolean scaleUp) {
Dianne Hackborn84375872012-06-01 19:03:50 -07003739 synchronized(mWindowMap) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003740 mAppTransition.overridePendingAppTransitionThumb(srcThumb, startX, startY,
3741 startedCallback, scaleUp);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003742 }
3743 }
3744
Craig Mautnera91f9e22012-09-14 16:22:08 -07003745 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003746 public void executeAppTransition() {
3747 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3748 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003749 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003750 }
Romain Guy06882f82009-06-10 13:36:04 -07003751
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003752 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003753 if (DEBUG_APP_TRANSITIONS) {
3754 RuntimeException e = new RuntimeException("here");
3755 e.fillInStackTrace();
Craig Mautner164d4bb2012-11-26 13:51:23 -08003756 Slog.w(TAG, "Execute app transition: " + mAppTransition, e);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003757 }
Craig Mautner164d4bb2012-11-26 13:51:23 -08003758 if (mAppTransition.isTransitionSet()) {
Craig Mautnerae446592012-12-06 19:05:05 -08003759 mAppTransition.setReady();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003760 final long origId = Binder.clearCallingIdentity();
3761 performLayoutAndPlaceSurfacesLocked();
3762 Binder.restoreCallingIdentity(origId);
3763 }
3764 }
3765 }
3766
Craig Mautnere6f7d5052012-10-08 10:34:17 -07003767 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003768 public void setAppStartingWindow(IBinder token, String pkg,
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07003769 int theme, CompatibilityInfo compatInfo,
3770 CharSequence nonLocalizedLabel, int labelRes, int icon,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003771 int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003772 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner6fbda632012-07-03 09:26:39 -07003773 "setAppStartingWindow()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003774 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003775 }
3776
3777 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003778 if (DEBUG_STARTING_WINDOW) Slog.v(
Craig Mautner8863cca2012-09-18 15:04:34 -07003779 TAG, "setAppStartingWindow: token=" + token + " pkg=" + pkg
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003780 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003782 AppWindowToken wtoken = findAppWindowToken(token);
3783 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003784 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003785 return;
3786 }
3787
3788 // If the display is frozen, we won't do anything until the
3789 // actual window is displayed so there is no reason to put in
3790 // the starting window.
Craig Mautner2fb98b12012-03-20 17:24:00 -07003791 if (!okToDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003792 return;
3793 }
Romain Guy06882f82009-06-10 13:36:04 -07003794
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003795 if (wtoken.startingData != null) {
3796 return;
3797 }
Romain Guy06882f82009-06-10 13:36:04 -07003798
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003799 if (transferFrom != null) {
3800 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3801 if (ttoken != null) {
3802 WindowState startingWindow = ttoken.startingWindow;
3803 if (startingWindow != null) {
3804 if (mStartingIconInTransition) {
3805 // In this case, the starting icon has already
3806 // been displayed, so start letting windows get
3807 // shown immediately without any more transitions.
3808 mSkipAppTransitionAnimation = true;
3809 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003810 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
Craig Mautner8863cca2012-09-18 15:04:34 -07003811 "Moving existing starting " + startingWindow + " from " + ttoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003812 + " to " + wtoken);
3813 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003814
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003815 // Transfer the starting window over to the new
3816 // token.
3817 wtoken.startingData = ttoken.startingData;
3818 wtoken.startingView = ttoken.startingView;
Craig Mautnerf4120952012-06-21 18:25:39 -07003819 wtoken.startingDisplayed = ttoken.startingDisplayed;
Craig Mautner8863cca2012-09-18 15:04:34 -07003820 ttoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003821 wtoken.startingWindow = startingWindow;
Craig Mautnerf4120952012-06-21 18:25:39 -07003822 wtoken.reportedVisible = ttoken.reportedVisible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003823 ttoken.startingData = null;
3824 ttoken.startingView = null;
3825 ttoken.startingWindow = null;
3826 ttoken.startingMoved = true;
3827 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003828 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003829 startingWindow.mAppToken = wtoken;
Craig Mautner8863cca2012-09-18 15:04:34 -07003830 startingWindow.mWinAnimator.mAppAnimator = wtoken.mAppAnimator;
3831
Craig Mautner6fbda632012-07-03 09:26:39 -07003832 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) {
3833 Slog.v(TAG, "Removing starting window: " + startingWindow);
3834 }
Craig Mautner59c00972012-07-30 12:10:24 -07003835 startingWindow.getWindowList().remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07003836 mWindowsChanged = true;
Craig Mautner6fbda632012-07-03 09:26:39 -07003837 if (DEBUG_ADD_REMOVE) Slog.v(TAG,
3838 "Removing starting " + startingWindow + " from " + ttoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003839 ttoken.windows.remove(startingWindow);
3840 ttoken.allAppWindows.remove(startingWindow);
3841 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003842
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003843 // Propagate other interesting state between the
3844 // tokens. If the old token is displayed, we should
3845 // immediately force the new one to be displayed. If
3846 // it is animating, we need to move that animation to
3847 // the new one.
3848 if (ttoken.allDrawn) {
3849 wtoken.allDrawn = true;
Craig Mautner7636dfb2012-11-16 15:24:11 -08003850 wtoken.deferClearAllDrawn = ttoken.deferClearAllDrawn;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003851 }
3852 if (ttoken.firstWindowDrawn) {
3853 wtoken.firstWindowDrawn = true;
3854 }
3855 if (!ttoken.hidden) {
3856 wtoken.hidden = false;
3857 wtoken.hiddenRequested = false;
3858 wtoken.willBeHidden = false;
3859 }
3860 if (wtoken.clientHidden != ttoken.clientHidden) {
3861 wtoken.clientHidden = ttoken.clientHidden;
3862 wtoken.sendAppVisibilityToClients();
3863 }
Craig Mautner59431632012-04-04 11:56:44 -07003864 final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
3865 final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
3866 if (tAppAnimator.animation != null) {
3867 wAppAnimator.animation = tAppAnimator.animation;
3868 wAppAnimator.animating = tAppAnimator.animating;
3869 wAppAnimator.animLayerAdjustment = tAppAnimator.animLayerAdjustment;
3870 tAppAnimator.animation = null;
3871 tAppAnimator.animLayerAdjustment = 0;
3872 wAppAnimator.updateLayers();
3873 tAppAnimator.updateLayers();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003874 }
Romain Guy06882f82009-06-10 13:36:04 -07003875
Jeff Brown3a22cd92011-01-21 13:59:04 -08003876 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
3877 true /*updateInputWindows*/);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003878 getDefaultDisplayContentLocked().layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003879 performLayoutAndPlaceSurfacesLocked();
3880 Binder.restoreCallingIdentity(origId);
3881 return;
3882 } else if (ttoken.startingData != null) {
3883 // The previous app was getting ready to show a
3884 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08003885 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003886 "Moving pending starting from " + ttoken
3887 + " to " + wtoken);
3888 wtoken.startingData = ttoken.startingData;
3889 ttoken.startingData = null;
3890 ttoken.startingMoved = true;
3891 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3892 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3893 // want to process the message ASAP, before any other queued
3894 // messages.
3895 mH.sendMessageAtFrontOfQueue(m);
3896 return;
3897 }
Craig Mautner59431632012-04-04 11:56:44 -07003898 final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
3899 final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
3900 if (tAppAnimator.thumbnail != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003901 // The old token is animating with a thumbnail, transfer
3902 // that to the new token.
Craig Mautner59431632012-04-04 11:56:44 -07003903 if (wAppAnimator.thumbnail != null) {
3904 wAppAnimator.thumbnail.destroy();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003905 }
Craig Mautner59431632012-04-04 11:56:44 -07003906 wAppAnimator.thumbnail = tAppAnimator.thumbnail;
3907 wAppAnimator.thumbnailX = tAppAnimator.thumbnailX;
3908 wAppAnimator.thumbnailY = tAppAnimator.thumbnailY;
3909 wAppAnimator.thumbnailLayer = tAppAnimator.thumbnailLayer;
3910 wAppAnimator.thumbnailAnimation = tAppAnimator.thumbnailAnimation;
3911 tAppAnimator.thumbnail = null;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003912 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003913 }
3914 }
3915
3916 // There is no existing starting window, and the caller doesn't
3917 // want us to create one, so that's it!
3918 if (!createIfNeeded) {
3919 return;
3920 }
Romain Guy06882f82009-06-10 13:36:04 -07003921
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003922 // If this is a translucent window, then don't
Dianne Hackborn284ac932009-08-28 10:34:25 -07003923 // show a starting window -- the current effect (a full-screen
3924 // opaque starting window that fades away to the real contents
3925 // when it is ready) does not work for this.
Craig Mautner6fbda632012-07-03 09:26:39 -07003926 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Checking theme of starting window: 0x"
3927 + Integer.toHexString(theme));
Dianne Hackborn284ac932009-08-28 10:34:25 -07003928 if (theme != 0) {
3929 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
Amith Yamasani4befbec2013-07-10 16:18:01 -07003930 com.android.internal.R.styleable.Window, mCurrentUserId);
Dianne Hackborn0b800192012-06-21 15:29:36 -07003931 if (ent == null) {
3932 // Whoops! App doesn't exist. Um. Okay. We'll just
3933 // pretend like we didn't see that.
3934 return;
3935 }
Craig Mautner6fbda632012-07-03 09:26:39 -07003936 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Translucent="
3937 + ent.array.getBoolean(
3938 com.android.internal.R.styleable.Window_windowIsTranslucent, false)
3939 + " Floating="
3940 + ent.array.getBoolean(
3941 com.android.internal.R.styleable.Window_windowIsFloating, false)
3942 + " ShowWallpaper="
3943 + ent.array.getBoolean(
3944 com.android.internal.R.styleable.Window_windowShowWallpaper, false));
Dianne Hackborn284ac932009-08-28 10:34:25 -07003945 if (ent.array.getBoolean(
3946 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
3947 return;
3948 }
3949 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07003950 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
3951 return;
3952 }
3953 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07003954 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003955 if (mWallpaperTarget == null) {
3956 // If this theme is requesting a wallpaper, and the wallpaper
3957 // is not curently visible, then this effectively serves as
3958 // an opaque window and our starting window transition animation
3959 // can still work. We just need to make sure the starting window
3960 // is also showing the wallpaper.
Craig Mautner65d11b32012-10-01 13:59:52 -07003961 windowFlags |= FLAG_SHOW_WALLPAPER;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003962 } else {
3963 return;
3964 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07003965 }
3966 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003967
Craig Mautner6fbda632012-07-03 09:26:39 -07003968 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Creating StartingData");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003969 mStartingIconInTransition = true;
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07003970 wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003971 labelRes, icon, windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003972 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3973 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3974 // want to process the message ASAP, before any other queued
3975 // messages.
Craig Mautner6fbda632012-07-03 09:26:39 -07003976 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Enqueueing ADD_STARTING");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003977 mH.sendMessageAtFrontOfQueue(m);
3978 }
3979 }
3980
Craig Mautner312eac42012-11-13 10:56:22 -08003981 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003982 public void setAppWillBeHidden(IBinder token) {
3983 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3984 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003985 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003986 }
3987
3988 AppWindowToken wtoken;
3989
3990 synchronized(mWindowMap) {
3991 wtoken = findAppWindowToken(token);
3992 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003993 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 -08003994 return;
3995 }
3996 wtoken.willBeHidden = true;
3997 }
3998 }
Romain Guy06882f82009-06-10 13:36:04 -07003999
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004000 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004001 boolean visible, int transit, boolean performLayout) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004002 boolean delayed = false;
4003
4004 if (wtoken.clientHidden == visible) {
4005 wtoken.clientHidden = !visible;
4006 wtoken.sendAppVisibilityToClients();
4007 }
Romain Guy06882f82009-06-10 13:36:04 -07004008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004009 wtoken.willBeHidden = false;
4010 if (wtoken.hidden == visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004011 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004012 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004013 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
4014 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07004015
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004016 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07004017
Craig Mautner4b71aa12012-12-27 17:20:01 -08004018 if (transit != AppTransition.TRANSIT_UNSET) {
Craig Mautnerfbf378c2012-04-23 17:24:21 -07004019 if (wtoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) {
Craig Mautner59431632012-04-04 11:56:44 -07004020 wtoken.mAppAnimator.animation = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004021 }
Craig Mautnerf20588f2012-04-11 17:06:21 -07004022 if (applyAnimationLocked(wtoken, lp, transit, visible)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004023 delayed = runningAppAnimation = true;
4024 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07004025 WindowState window = wtoken.findMainWindow();
Svetoslav Ganov545252f2012-12-10 18:29:24 -08004026 //TODO (multidisplay): Magnification is supported only for the default display.
4027 if (window != null && mDisplayMagnifier != null
4028 && window.getDisplayId() == Display.DEFAULT_DISPLAY) {
Craig Mautner4b71aa12012-12-27 17:20:01 -08004029 mDisplayMagnifier.onAppWindowTransitionLocked(window, transit);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07004030 }
Craig Mautnerf20588f2012-04-11 17:06:21 -07004031 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004032 }
Romain Guy06882f82009-06-10 13:36:04 -07004033
Craig Mautnerf20588f2012-04-11 17:06:21 -07004034 final int N = wtoken.allAppWindows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004035 for (int i=0; i<N; i++) {
4036 WindowState win = wtoken.allAppWindows.get(i);
4037 if (win == wtoken.startingWindow) {
4038 continue;
4039 }
4040
Joe Onorato8a9b2202010-02-26 18:56:32 -08004041 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004042 //win.dump(" ");
4043 if (visible) {
4044 if (!win.isVisibleNow()) {
4045 if (!runningAppAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07004046 win.mWinAnimator.applyAnimationLocked(
4047 WindowManagerPolicy.TRANSIT_ENTER, true);
Svetoslav Ganov545252f2012-12-10 18:29:24 -08004048 //TODO (multidisplay): Magnification is supported only for the default
4049 if (mDisplayMagnifier != null
4050 && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
4051 mDisplayMagnifier.onWindowTransitionLocked(win,
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07004052 WindowManagerPolicy.TRANSIT_ENTER);
4053 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004054 }
4055 changed = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07004056 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004057 }
4058 } else if (win.isVisibleNow()) {
4059 if (!runningAppAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07004060 win.mWinAnimator.applyAnimationLocked(
4061 WindowManagerPolicy.TRANSIT_EXIT, false);
Svetoslav Ganov545252f2012-12-10 18:29:24 -08004062 //TODO (multidisplay): Magnification is supported only for the default
4063 if (mDisplayMagnifier != null
4064 && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
4065 mDisplayMagnifier.onWindowTransitionLocked(win,
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07004066 WindowManagerPolicy.TRANSIT_EXIT);
4067 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004068 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004069 changed = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07004070 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004071 }
4072 }
4073
4074 wtoken.hidden = wtoken.hiddenRequested = !visible;
4075 if (!visible) {
4076 unsetAppFreezingScreenLocked(wtoken, true, true);
4077 } else {
4078 // If we are being set visible, and the starting window is
4079 // not yet displayed, then make sure it doesn't get displayed.
4080 WindowState swin = wtoken.startingWindow;
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07004081 if (swin != null && !swin.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004082 swin.mPolicyVisibility = false;
4083 swin.mPolicyVisibilityAfterAnim = false;
4084 }
4085 }
Romain Guy06882f82009-06-10 13:36:04 -07004086
Joe Onorato8a9b2202010-02-26 18:56:32 -08004087 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004088 + ": hidden=" + wtoken.hidden + " hiddenRequested="
4089 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07004090
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004091 if (changed) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08004092 mInputMonitor.setUpdateInputWindowsNeededLw();
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004093 if (performLayout) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08004094 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4095 false /*updateInputWindows*/);
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004096 performLayoutAndPlaceSurfacesLocked();
4097 }
Jeff Brown2e44b072011-01-24 15:21:56 -08004098 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004099 }
4100 }
4101
Craig Mautner59431632012-04-04 11:56:44 -07004102 if (wtoken.mAppAnimator.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004103 delayed = true;
4104 }
Romain Guy06882f82009-06-10 13:36:04 -07004105
Craig Mautnerf20588f2012-04-11 17:06:21 -07004106 for (int i = wtoken.allAppWindows.size() - 1; i >= 0 && !delayed; i--) {
4107 if (wtoken.allAppWindows.get(i).mWinAnimator.isWindowAnimating()) {
4108 delayed = true;
4109 }
4110 }
4111
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004112 return delayed;
4113 }
4114
Craig Mautner312eac42012-11-13 10:56:22 -08004115 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004116 public void setAppVisibility(IBinder token, boolean visible) {
4117 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4118 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004119 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004120 }
4121
4122 AppWindowToken wtoken;
4123
4124 synchronized(mWindowMap) {
4125 wtoken = findAppWindowToken(token);
4126 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004127 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004128 return;
4129 }
4130
4131 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004132 RuntimeException e = null;
4133 if (!HIDE_STACK_CRAWLS) {
4134 e = new RuntimeException();
4135 e.fillInStackTrace();
4136 }
Craig Mautner0afddcb2012-05-08 15:38:00 -07004137 Slog.v(TAG, "setAppVisibility(" + token + ", visible=" + visible
Craig Mautner164d4bb2012-11-26 13:51:23 -08004138 + "): " + mAppTransition
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004139 + " hidden=" + wtoken.hidden
4140 + " hiddenRequested=" + wtoken.hiddenRequested, e);
4141 }
Romain Guy06882f82009-06-10 13:36:04 -07004142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004143 // If we are preparing an app transition, then delay changing
4144 // the visibility of this token until we execute that transition.
Craig Mautner164d4bb2012-11-26 13:51:23 -08004145 if (okToDisplay() && mAppTransition.isTransitionSet()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004146 // Already in requested state, don't do anything more.
4147 if (wtoken.hiddenRequested != visible) {
4148 return;
4149 }
4150 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07004151
Craig Mautnerf4120952012-06-21 18:25:39 -07004152 if (!wtoken.startingDisplayed) {
Craig Mautner8863cca2012-09-18 15:04:34 -07004153 if (DEBUG_APP_TRANSITIONS) Slog.v(
4154 TAG, "Setting dummy animation on: " + wtoken);
Craig Mautnerf4120952012-06-21 18:25:39 -07004155 wtoken.mAppAnimator.setDummyAnimation();
4156 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004157 mOpeningApps.remove(wtoken);
4158 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004159 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004160 wtoken.inPendingTransaction = true;
4161 if (visible) {
4162 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004163 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004164
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004165 // If the token is currently hidden (should be the
4166 // common case), then we need to set up to wait for
4167 // its windows to be ready.
4168 if (wtoken.hidden) {
4169 wtoken.allDrawn = false;
Craig Mautner7636dfb2012-11-16 15:24:11 -08004170 wtoken.deferClearAllDrawn = false;
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004171 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004172
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004173 if (wtoken.clientHidden) {
4174 // In the case where we are making an app visible
4175 // but holding off for a transition, we still need
4176 // to tell the client to make its windows visible so
4177 // they get drawn. Otherwise, we will wait on
4178 // performing the transition until all windows have
4179 // been drawn, they never will be, and we are sad.
4180 wtoken.clientHidden = false;
4181 wtoken.sendAppVisibilityToClients();
4182 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004183 }
4184 } else {
4185 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004186
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004187 // If the token is currently visible (should be the
4188 // common case), then set up to wait for it to be hidden.
4189 if (!wtoken.hidden) {
4190 wtoken.waitingToHide = true;
4191 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004192 }
4193 return;
4194 }
Romain Guy06882f82009-06-10 13:36:04 -07004195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004196 final long origId = Binder.clearCallingIdentity();
Craig Mautner4b71aa12012-12-27 17:20:01 -08004197 setTokenVisibilityLocked(wtoken, null, visible, AppTransition.TRANSIT_UNSET,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004198 true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004199 wtoken.updateReportedVisibilityLocked();
4200 Binder.restoreCallingIdentity(origId);
4201 }
4202 }
4203
4204 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
4205 boolean unfreezeSurfaceNow, boolean force) {
Craig Mautner59431632012-04-04 11:56:44 -07004206 if (wtoken.mAppAnimator.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004207 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004208 + " force=" + force);
4209 final int N = wtoken.allAppWindows.size();
4210 boolean unfrozeWindows = false;
4211 for (int i=0; i<N; i++) {
4212 WindowState w = wtoken.allAppWindows.get(i);
4213 if (w.mAppFreezing) {
4214 w.mAppFreezing = false;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07004215 if (w.mHasSurface && !w.mOrientationChanging) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07004216 if (DEBUG_ORIENTATION) Slog.v(TAG, "set mOrientationChanging of " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004217 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07004218 mInnerFields.mOrientationChangeComplete = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004219 }
Dianne Hackborna57c6952013-03-29 14:46:40 -07004220 w.mLastFreezeDuration = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004221 unfrozeWindows = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07004222 w.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004223 }
4224 }
4225 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004226 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
Craig Mautner59431632012-04-04 11:56:44 -07004227 wtoken.mAppAnimator.freezingScreen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07004228 wtoken.mAppAnimator.lastFreezeDuration = (int)(SystemClock.elapsedRealtime()
4229 - mDisplayFreezeTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004230 mAppsFreezingScreen--;
Dianne Hackborna57c6952013-03-29 14:46:40 -07004231 mLastFinishedFreezeSource = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004232 }
4233 if (unfreezeSurfaceNow) {
4234 if (unfrozeWindows) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004235 performLayoutAndPlaceSurfacesLocked();
4236 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004237 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004238 }
4239 }
4240 }
Romain Guy06882f82009-06-10 13:36:04 -07004241
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004242 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
4243 int configChanges) {
4244 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004245 RuntimeException e = null;
4246 if (!HIDE_STACK_CRAWLS) {
4247 e = new RuntimeException();
4248 e.fillInStackTrace();
4249 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004250 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004251 + ": hidden=" + wtoken.hidden + " freezing="
Craig Mautner59431632012-04-04 11:56:44 -07004252 + wtoken.mAppAnimator.freezingScreen, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004253 }
4254 if (!wtoken.hiddenRequested) {
Craig Mautner59431632012-04-04 11:56:44 -07004255 if (!wtoken.mAppAnimator.freezingScreen) {
4256 wtoken.mAppAnimator.freezingScreen = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -07004257 wtoken.mAppAnimator.lastFreezeDuration = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004258 mAppsFreezingScreen++;
4259 if (mAppsFreezingScreen == 1) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07004260 startFreezingDisplayLocked(false, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004261 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
You Kimcb6291c2012-12-04 23:22:28 +09004262 mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 5000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004263 }
4264 }
4265 final int N = wtoken.allAppWindows.size();
4266 for (int i=0; i<N; i++) {
4267 WindowState w = wtoken.allAppWindows.get(i);
4268 w.mAppFreezing = true;
4269 }
4270 }
4271 }
Romain Guy06882f82009-06-10 13:36:04 -07004272
Craig Mautner312eac42012-11-13 10:56:22 -08004273 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004274 public void startAppFreezingScreen(IBinder token, int configChanges) {
4275 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4276 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004277 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004278 }
4279
4280 synchronized(mWindowMap) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07004281 if (configChanges == 0 && okToDisplay()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004282 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004283 return;
4284 }
Romain Guy06882f82009-06-10 13:36:04 -07004285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004286 AppWindowToken wtoken = findAppWindowToken(token);
4287 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004288 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004289 return;
4290 }
4291 final long origId = Binder.clearCallingIdentity();
4292 startAppFreezingScreenLocked(wtoken, configChanges);
4293 Binder.restoreCallingIdentity(origId);
4294 }
4295 }
Romain Guy06882f82009-06-10 13:36:04 -07004296
Craig Mautner312eac42012-11-13 10:56:22 -08004297 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004298 public void stopAppFreezingScreen(IBinder token, boolean force) {
4299 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4300 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004301 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004302 }
4303
4304 synchronized(mWindowMap) {
4305 AppWindowToken wtoken = findAppWindowToken(token);
4306 if (wtoken == null || wtoken.appToken == null) {
4307 return;
4308 }
4309 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004310 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
Craig Mautner59431632012-04-04 11:56:44 -07004311 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.mAppAnimator.freezingScreen);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004312 unsetAppFreezingScreenLocked(wtoken, true, force);
4313 Binder.restoreCallingIdentity(origId);
4314 }
4315 }
Romain Guy06882f82009-06-10 13:36:04 -07004316
Craig Mautnerae446592012-12-06 19:05:05 -08004317 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004318 public void removeAppToken(IBinder token) {
4319 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4320 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004321 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004322 }
4323
4324 AppWindowToken wtoken = null;
4325 AppWindowToken startingToken = null;
4326 boolean delayed = false;
4327
4328 final long origId = Binder.clearCallingIdentity();
4329 synchronized(mWindowMap) {
4330 WindowToken basewtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004331 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004332 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004333 delayed = setTokenVisibilityLocked(wtoken, null, false,
Craig Mautner4b71aa12012-12-27 17:20:01 -08004334 AppTransition.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004335 wtoken.inPendingTransaction = false;
4336 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004337 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004338 if (mClosingApps.contains(wtoken)) {
4339 delayed = true;
Craig Mautner164d4bb2012-11-26 13:51:23 -08004340 } else if (mAppTransition.isTransitionSet()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004341 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004342 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004343 delayed = true;
4344 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004345 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004346 TAG, "Removing app " + wtoken + " delayed=" + delayed
Craig Mautner59431632012-04-04 11:56:44 -07004347 + " animation=" + wtoken.mAppAnimator.animation
4348 + " animating=" + wtoken.mAppAnimator.animating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004349 if (delayed) {
4350 // set the token aside because it has an active animation to be finished
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004351 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4352 "removeAppToken make exiting: " + wtoken);
Craig Mautner2ad92072013-02-25 16:19:24 -08004353 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004354 } else {
4355 // Make sure there is no animation running on this token,
4356 // so any windows associated with it will be removed as
4357 // soon as their animations are complete
Craig Mautner59431632012-04-04 11:56:44 -07004358 wtoken.mAppAnimator.clearAnimation();
4359 wtoken.mAppAnimator.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004360 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004361 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4362 "removeAppToken: " + wtoken);
Craig Mautner2ad92072013-02-25 16:19:24 -08004363 mAppTokens.remove(wtoken);
4364 mAnimatingAppTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004365 wtoken.removed = true;
4366 if (wtoken.startingData != null) {
4367 startingToken = wtoken;
4368 }
4369 unsetAppFreezingScreenLocked(wtoken, true, true);
4370 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004371 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004372 mFocusedApp = null;
Jeff Brown3a22cd92011-01-21 13:59:04 -08004373 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004374 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004375 }
4376 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004377 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004378 }
Romain Guy06882f82009-06-10 13:36:04 -07004379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004380 if (!delayed && wtoken != null) {
4381 wtoken.updateReportedVisibilityLocked();
4382 }
4383 }
4384 Binder.restoreCallingIdentity(origId);
4385
4386 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004387 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004388 + startingToken + ": app token removed");
4389 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
4390 mH.sendMessage(m);
4391 }
4392 }
4393
4394 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
4395 final int NW = token.windows.size();
Craig Mautneref25d7a2012-05-15 23:01:47 -07004396 if (NW > 0) {
4397 mWindowsChanged = true;
4398 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004399 for (int i=0; i<NW; i++) {
4400 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004401 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
Craig Mautner59c00972012-07-30 12:10:24 -07004402 win.getWindowList().remove(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004403 int j = win.mChildWindows.size();
4404 while (j > 0) {
4405 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004406 WindowState cwin = win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004407 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004408 "Tmp removing child window " + cwin);
Craig Mautner59c00972012-07-30 12:10:24 -07004409 cwin.getWindowList().remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004410 }
4411 }
4412 return NW > 0;
4413 }
4414
4415 void dumpAppTokensLocked() {
Craig Mautner2ad92072013-02-25 16:19:24 -08004416 for (int i=mAppTokens.size()-1; i>=0; i--) {
4417 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
4418 }
4419 }
4420
4421 void dumpAnimatingAppTokensLocked() {
4422 for (int i=mAnimatingAppTokens.size()-1; i>=0; i--) {
4423 Slog.v(TAG, " #" + i + ": " + mAnimatingAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004424 }
4425 }
Romain Guy06882f82009-06-10 13:36:04 -07004426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004427 void dumpWindowsLocked() {
Craig Mautner59c00972012-07-30 12:10:24 -07004428 int i = 0;
Craig Mautner7c6be102013-07-16 12:30:28 -07004429 final int numDisplays = mDisplayContents.size();
4430 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
4431 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
4432 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
4433 final WindowState w = windows.get(winNdx);
4434 Slog.v(TAG, " #" + i++ + ": " + w);
4435 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004436 }
4437 }
Romain Guy06882f82009-06-10 13:36:04 -07004438
Craig Mautner2ad92072013-02-25 16:19:24 -08004439 private int findWindowOffsetLocked(WindowList windows, int tokenPos) {
Craig Mautner926f3832013-02-13 11:56:07 -08004440 final int NW = windows.size();
4441
Craig Mautner2ad92072013-02-25 16:19:24 -08004442 if (tokenPos >= mAnimatingAppTokens.size()) {
4443 int i = NW;
4444 while (i > 0) {
4445 i--;
4446 WindowState win = windows.get(i);
4447 if (win.getAppToken() != null) {
4448 return i+1;
4449 }
Craig Mautner926f3832013-02-13 11:56:07 -08004450 }
4451 }
4452
Craig Mautner2ad92072013-02-25 16:19:24 -08004453 while (tokenPos > 0) {
Craig Mautner926f3832013-02-13 11:56:07 -08004454 // Find the first app token below the new position that has
4455 // a window displayed.
Craig Mautner2ad92072013-02-25 16:19:24 -08004456 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
4457 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
4458 + tokenPos + " -- " + wtoken.token);
Craig Mautner926f3832013-02-13 11:56:07 -08004459 if (wtoken.sendingToBottom) {
Craig Mautner2ad92072013-02-25 16:19:24 -08004460 if (DEBUG_REORDER) Slog.v(TAG,
4461 "Skipping token -- currently sending to bottom");
4462 tokenPos--;
Craig Mautner926f3832013-02-13 11:56:07 -08004463 continue;
4464 }
Craig Mautner2ad92072013-02-25 16:19:24 -08004465 int i = wtoken.windows.size();
4466 while (i > 0) {
4467 i--;
Craig Mautner926f3832013-02-13 11:56:07 -08004468 WindowState win = wtoken.windows.get(i);
Craig Mautner2ad92072013-02-25 16:19:24 -08004469 int j = win.mChildWindows.size();
4470 while (j > 0) {
4471 j--;
Craig Mautner926f3832013-02-13 11:56:07 -08004472 WindowState cwin = win.mChildWindows.get(j);
4473 if (cwin.mSubLayer >= 0) {
Craig Mautner2ad92072013-02-25 16:19:24 -08004474 for (int pos=NW-1; pos>=0; pos--) {
Craig Mautner926f3832013-02-13 11:56:07 -08004475 if (windows.get(pos) == cwin) {
4476 if (DEBUG_REORDER) Slog.v(TAG,
Craig Mautner2ad92072013-02-25 16:19:24 -08004477 "Found child win @" + (pos+1));
4478 return pos+1;
Craig Mautner926f3832013-02-13 11:56:07 -08004479 }
4480 }
4481 }
4482 }
Craig Mautner2ad92072013-02-25 16:19:24 -08004483 for (int pos=NW-1; pos>=0; pos--) {
Craig Mautner926f3832013-02-13 11:56:07 -08004484 if (windows.get(pos) == win) {
Craig Mautner2ad92072013-02-25 16:19:24 -08004485 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
4486 return pos+1;
Craig Mautner926f3832013-02-13 11:56:07 -08004487 }
4488 }
4489 }
Craig Mautner2ad92072013-02-25 16:19:24 -08004490 tokenPos--;
Craig Mautner926f3832013-02-13 11:56:07 -08004491 }
4492
4493 return 0;
4494 }
4495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004496 private final int reAddWindowLocked(int index, WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -07004497 final WindowList windows = win.getWindowList();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004498 final int NCW = win.mChildWindows.size();
4499 boolean added = false;
4500 for (int j=0; j<NCW; j++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004501 WindowState cwin = win.mChildWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004502 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004503 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004504 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004505 win.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004506 windows.add(index, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004507 index++;
4508 added = true;
4509 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004510 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004511 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004512 cwin.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004513 windows.add(index, cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004514 index++;
4515 }
4516 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004517 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004518 + index + ": " + win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004519 win.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004520 windows.add(index, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004521 index++;
4522 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004523 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004524 return index;
4525 }
Romain Guy06882f82009-06-10 13:36:04 -07004526
Craig Mautner59c00972012-07-30 12:10:24 -07004527 private final int reAddAppWindowsLocked(final DisplayContent displayContent, int index,
4528 WindowToken token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004529 final int NW = token.windows.size();
4530 for (int i=0; i<NW; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07004531 final WindowState win = token.windows.get(i);
4532 if (win.mDisplayContent == displayContent) {
Craig Mautner69b08182012-09-05 13:07:13 -07004533 index = reAddWindowLocked(index, win);
Craig Mautner59c00972012-07-30 12:10:24 -07004534 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004535 }
4536 return index;
4537 }
4538
Craig Mautner2ad92072013-02-25 16:19:24 -08004539 @Override
4540 public void moveAppToken(int index, IBinder token) {
4541 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4542 "moveAppToken()")) {
4543 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004544 }
Craig Mautner926f3832013-02-13 11:56:07 -08004545
Craig Mautner2ad92072013-02-25 16:19:24 -08004546 synchronized(mWindowMap) {
4547 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
4548 if (DEBUG_REORDER) dumpAppTokensLocked();
4549 final AppWindowToken wtoken = findAppWindowToken(token);
4550 final int oldIndex = mAppTokens.indexOf(wtoken);
4551 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
4552 "Start moving token " + wtoken + " initially at "
4553 + oldIndex);
4554 if (oldIndex > index && mAppTransition.isTransitionSet()) {
4555 // animation towards back has not started, copy old list for duration of animation.
4556 mAnimatingAppTokens.clear();
4557 mAnimatingAppTokens.addAll(mAppTokens);
4558 }
4559 if (wtoken == null || !mAppTokens.remove(wtoken)) {
4560 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
4561 + token + " (" + wtoken + ")");
4562 return;
4563 }
4564 mAppTokens.add(index, wtoken);
4565 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
4566 else if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "Moved " + token + " to " + index);
4567 if (DEBUG_REORDER) dumpAppTokensLocked();
4568 if (!mAppTransition.isTransitionSet()) {
4569 // Not animating, bring animating app list in line with mAppTokens.
4570 mAnimatingAppTokens.clear();
4571 mAnimatingAppTokens.addAll(mAppTokens);
Craig Mautner926f3832013-02-13 11:56:07 -08004572
Craig Mautner2ad92072013-02-25 16:19:24 -08004573 // Bring window ordering, window focus and input window in line with new app token
4574 final long origId = Binder.clearCallingIdentity();
4575 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
4576 if (DEBUG_REORDER) dumpWindowsLocked();
4577 if (tmpRemoveAppWindowsLocked(wtoken)) {
4578 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
4579 if (DEBUG_REORDER) dumpWindowsLocked();
Craig Mautner7c6be102013-07-16 12:30:28 -07004580 final int numDisplays = mDisplayContents.size();
4581 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
4582 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautner2ad92072013-02-25 16:19:24 -08004583 final WindowList windows = displayContent.getWindowList();
4584 final int pos = findWindowOffsetLocked(windows, index);
4585 final int newPos = reAddAppWindowsLocked(displayContent, pos, wtoken);
4586 if (pos != newPos) {
4587 displayContent.layoutNeeded = true;
4588 }
4589 }
4590 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
4591 if (DEBUG_REORDER) dumpWindowsLocked();
4592 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4593 false /*updateInputWindows*/);
4594 mInputMonitor.setUpdateInputWindowsNeededLw();
4595 performLayoutAndPlaceSurfacesLocked();
4596 mInputMonitor.updateInputWindowsLw(false /*force*/);
4597 }
4598 Binder.restoreCallingIdentity(origId);
4599 }
4600 }
4601 }
4602
4603 private void removeAppTokensLocked(List<IBinder> tokens) {
4604 // XXX This should be done more efficiently!
4605 // (take advantage of the fact that both lists should be
4606 // ordered in the same way.)
4607 int N = tokens.size();
4608 for (int i=0; i<N; i++) {
4609 IBinder token = tokens.get(i);
4610 final AppWindowToken wtoken = findAppWindowToken(token);
4611 if (DEBUG_REORDER || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4612 "Temporarily removing " + wtoken + " from " + mAppTokens.indexOf(wtoken));
4613 if (!mAppTokens.remove(wtoken)) {
4614 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
4615 + token + " (" + wtoken + ")");
4616 i--;
4617 N--;
4618 }
4619 }
4620 }
4621
4622 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
Craig Mautner926f3832013-02-13 11:56:07 -08004623 // First remove all of the windows from the list.
Craig Mautner2ad92072013-02-25 16:19:24 -08004624 final int N = tokens.size();
4625 int i;
4626 for (i=0; i<N; i++) {
4627 WindowToken token = mTokenMap.get(tokens.get(i));
4628 if (token != null) {
4629 tmpRemoveAppWindowsLocked(token);
4630 }
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004631 }
Craig Mautner926f3832013-02-13 11:56:07 -08004632
4633 // And now add them back at the correct place.
Craig Mautner7c6be102013-07-16 12:30:28 -07004634 final int numDisplays = mDisplayContents.size();
4635 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
4636 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautner2ad92072013-02-25 16:19:24 -08004637 final WindowList windows = displayContent.getWindowList();
4638 // Where to start adding?
4639 int pos = findWindowOffsetLocked(windows, tokenPos);
4640 for (i=0; i<N; i++) {
4641 WindowToken token = mTokenMap.get(tokens.get(i));
4642 if (token != null) {
4643 final int newPos = reAddAppWindowsLocked(displayContent, pos, token);
4644 if (newPos != pos) {
4645 displayContent.layoutNeeded = true;
4646 }
4647 pos = newPos;
Craig Mautner926f3832013-02-13 11:56:07 -08004648 }
Craig Mautner2ad92072013-02-25 16:19:24 -08004649 }
4650 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4651 false /*updateInputWindows*/)) {
4652 assignLayersLocked(windows);
Craig Mautner926f3832013-02-13 11:56:07 -08004653 }
4654 }
Craig Mautner926f3832013-02-13 11:56:07 -08004655
Craig Mautner926f3832013-02-13 11:56:07 -08004656 mInputMonitor.setUpdateInputWindowsNeededLw();
Craig Mautner2ad92072013-02-25 16:19:24 -08004657
4658 // Note that the above updateFocusedWindowLocked used to sit here.
4659
Craig Mautner926f3832013-02-13 11:56:07 -08004660 performLayoutAndPlaceSurfacesLocked();
4661 mInputMonitor.updateInputWindowsLw(false /*force*/);
4662
4663 //dump();
4664 }
4665
Craig Mautner2ad92072013-02-25 16:19:24 -08004666 @Override
4667 public void moveAppTokensToTop(List<IBinder> tokens) {
4668 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4669 "moveAppTokensToTop()")) {
4670 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
Craig Mautner926f3832013-02-13 11:56:07 -08004671 }
Craig Mautner2ad92072013-02-25 16:19:24 -08004672
4673 final long origId = Binder.clearCallingIdentity();
4674 synchronized(mWindowMap) {
4675 removeAppTokensLocked(tokens);
4676 final int N = tokens.size();
4677 for (int i=0; i<N; i++) {
4678 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4679 if (wt != null) {
4680 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
4681 "Adding next to top: " + wt);
4682 mAppTokens.add(wt);
4683 if (mAppTransition.isTransitionSet()) {
4684 wt.sendingToBottom = false;
4685 }
4686 }
4687 }
4688
4689 mAnimatingAppTokens.clear();
4690 mAnimatingAppTokens.addAll(mAppTokens);
4691 moveAppWindowsLocked(tokens, mAppTokens.size());
4692 }
4693 Binder.restoreCallingIdentity(origId);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004694 }
4695
Craig Mautner2ad92072013-02-25 16:19:24 -08004696 @Override
4697 public void moveAppTokensToBottom(List<IBinder> tokens) {
4698 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4699 "moveAppTokensToBottom()")) {
4700 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004701 }
Craig Mautner2ad92072013-02-25 16:19:24 -08004702
4703 final long origId = Binder.clearCallingIdentity();
4704 synchronized(mWindowMap) {
4705 final int N = tokens.size();
4706 if (N > 0) {
4707 // animating towards back, hang onto old list for duration of animation.
4708 mAnimatingAppTokens.clear();
4709 mAnimatingAppTokens.addAll(mAppTokens);
4710 }
4711 removeAppTokensLocked(tokens);
4712 int pos = 0;
4713 for (int i=0; i<N; i++) {
4714 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4715 if (wt != null) {
4716 if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4717 "Adding next to bottom: " + wt + " at " + pos);
4718 mAppTokens.add(pos, wt);
4719 if (mAppTransition.isTransitionSet()) {
4720 wt.sendingToBottom = true;
4721 }
4722 pos++;
4723 }
4724 }
4725
4726 mAnimatingAppTokens.clear();
4727 mAnimatingAppTokens.addAll(mAppTokens);
4728 moveAppWindowsLocked(tokens, 0);
4729 }
4730 Binder.restoreCallingIdentity(origId);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004731 }
4732
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004733 // -------------------------------------------------------------
4734 // Misc IWindowSession methods
4735 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004736
Craig Mautner5642a482012-08-23 12:16:53 -07004737 @Override
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07004738 public void startFreezingScreen(int exitAnim, int enterAnim) {
4739 if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
4740 "startFreezingScreen()")) {
4741 throw new SecurityException("Requires FREEZE_SCREEN permission");
4742 }
4743
4744 synchronized(mWindowMap) {
4745 if (!mClientFreezingScreen) {
4746 mClientFreezingScreen = true;
4747 final long origId = Binder.clearCallingIdentity();
4748 try {
4749 startFreezingDisplayLocked(false, exitAnim, enterAnim);
4750 mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
You Kimcb6291c2012-12-04 23:22:28 +09004751 mH.sendEmptyMessageDelayed(H.CLIENT_FREEZE_TIMEOUT, 5000);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07004752 } finally {
4753 Binder.restoreCallingIdentity(origId);
4754 }
4755 }
4756 }
4757 }
4758
4759 @Override
4760 public void stopFreezingScreen() {
4761 if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
4762 "stopFreezingScreen()")) {
4763 throw new SecurityException("Requires FREEZE_SCREEN permission");
4764 }
4765
4766 synchronized(mWindowMap) {
4767 if (mClientFreezingScreen) {
4768 mClientFreezingScreen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07004769 mLastFinishedFreezeSource = "client";
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07004770 final long origId = Binder.clearCallingIdentity();
4771 try {
4772 stopFreezingDisplayLocked();
4773 } finally {
4774 Binder.restoreCallingIdentity(origId);
4775 }
4776 }
4777 }
4778 }
4779
4780 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004781 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004782 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004783 != PackageManager.PERMISSION_GRANTED) {
4784 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4785 }
Jim Millerd6b57052010-06-07 17:52:42 -07004786
Craig Mautner5642a482012-08-23 12:16:53 -07004787 mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage(
4788 KeyguardDisableHandler.KEYGUARD_DISABLE, new Pair<IBinder, String>(token, tag)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004789 }
4790
Craig Mautner5642a482012-08-23 12:16:53 -07004791 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004792 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004793 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004794 != PackageManager.PERMISSION_GRANTED) {
4795 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4796 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004797
Craig Mautner5642a482012-08-23 12:16:53 -07004798 mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage(
4799 KeyguardDisableHandler.KEYGUARD_REENABLE, token));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004800 }
4801
4802 /**
4803 * @see android.app.KeyguardManager#exitKeyguardSecurely
4804 */
Craig Mautner2268e7e2012-12-13 15:40:00 -08004805 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004806 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004807 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004808 != PackageManager.PERMISSION_GRANTED) {
4809 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4810 }
4811 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
Craig Mautner2268e7e2012-12-13 15:40:00 -08004812 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004813 public void onKeyguardExitResult(boolean success) {
4814 try {
4815 callback.onKeyguardExitResult(success);
4816 } catch (RemoteException e) {
4817 // Client has died, we don't care.
4818 }
4819 }
4820 });
4821 }
4822
Craig Mautner2268e7e2012-12-13 15:40:00 -08004823 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004824 public boolean inKeyguardRestrictedInputMode() {
4825 return mPolicy.inKeyguardRestrictedKeyInputMode();
4826 }
Romain Guy06882f82009-06-10 13:36:04 -07004827
Craig Mautner2268e7e2012-12-13 15:40:00 -08004828 @Override
Mike Lockwood520d8bc2011-02-18 13:23:13 -05004829 public boolean isKeyguardLocked() {
4830 return mPolicy.isKeyguardLocked();
4831 }
4832
Craig Mautner2268e7e2012-12-13 15:40:00 -08004833 @Override
Mike Lockwood520d8bc2011-02-18 13:23:13 -05004834 public boolean isKeyguardSecure() {
4835 return mPolicy.isKeyguardSecure();
4836 }
4837
Craig Mautner2268e7e2012-12-13 15:40:00 -08004838 @Override
Dianne Hackborn90c52de2011-09-23 12:57:44 -07004839 public void dismissKeyguard() {
4840 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
4841 != PackageManager.PERMISSION_GRANTED) {
4842 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4843 }
4844 synchronized(mWindowMap) {
4845 mPolicy.dismissKeyguardLw();
4846 }
4847 }
4848
Craig Mautner0bf6ec92012-12-18 08:33:27 -08004849 @Override
Dianne Hackbornffa42482009-09-23 22:20:11 -07004850 public void closeSystemDialogs(String reason) {
4851 synchronized(mWindowMap) {
Craig Mautner7c6be102013-07-16 12:30:28 -07004852 final int numDisplays = mDisplayContents.size();
4853 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
4854 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
4855 final int numWindows = windows.size();
4856 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
4857 final WindowState w = windows.get(winNdx);
4858 if (w.mHasSurface) {
4859 try {
4860 w.mClient.closeSystemDialogs(reason);
4861 } catch (RemoteException e) {
4862 }
Dianne Hackbornffa42482009-09-23 22:20:11 -07004863 }
4864 }
4865 }
4866 }
4867 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004868
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004869 static float fixScale(float scale) {
4870 if (scale < 0) scale = 0;
4871 else if (scale > 20) scale = 20;
4872 return Math.abs(scale);
4873 }
Romain Guy06882f82009-06-10 13:36:04 -07004874
Craig Mautner0bf6ec92012-12-18 08:33:27 -08004875 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004876 public void setAnimationScale(int which, float scale) {
4877 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4878 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004879 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004880 }
4881
4882 if (scale < 0) scale = 0;
4883 else if (scale > 20) scale = 20;
4884 scale = Math.abs(scale);
4885 switch (which) {
4886 case 0: mWindowAnimationScale = fixScale(scale); break;
4887 case 1: mTransitionAnimationScale = fixScale(scale); break;
Chet Haasec38fa1f2012-02-01 16:37:46 -08004888 case 2: mAnimatorDurationScale = fixScale(scale); break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004889 }
Romain Guy06882f82009-06-10 13:36:04 -07004890
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004891 // Persist setting
You Kimcb6291c2012-12-04 23:22:28 +09004892 mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004893 }
Romain Guy06882f82009-06-10 13:36:04 -07004894
Craig Mautner4b71aa12012-12-27 17:20:01 -08004895 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004896 public void setAnimationScales(float[] scales) {
4897 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4898 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004899 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004900 }
4901
4902 if (scales != null) {
4903 if (scales.length >= 1) {
4904 mWindowAnimationScale = fixScale(scales[0]);
4905 }
4906 if (scales.length >= 2) {
4907 mTransitionAnimationScale = fixScale(scales[1]);
4908 }
Chet Haasec38fa1f2012-02-01 16:37:46 -08004909 if (scales.length >= 3) {
Jeff Brownff7e6ef2012-08-15 02:05:18 -07004910 setAnimatorDurationScale(fixScale(scales[2]));
Chet Haasec38fa1f2012-02-01 16:37:46 -08004911 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004912 }
Romain Guy06882f82009-06-10 13:36:04 -07004913
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004914 // Persist setting
You Kimcb6291c2012-12-04 23:22:28 +09004915 mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004916 }
Romain Guy06882f82009-06-10 13:36:04 -07004917
Jeff Brownff7e6ef2012-08-15 02:05:18 -07004918 private void setAnimatorDurationScale(float scale) {
4919 mAnimatorDurationScale = scale;
4920 ValueAnimator.setDurationScale(scale);
4921 }
4922
Craig Mautner4b71aa12012-12-27 17:20:01 -08004923 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004924 public float getAnimationScale(int which) {
4925 switch (which) {
4926 case 0: return mWindowAnimationScale;
4927 case 1: return mTransitionAnimationScale;
Chet Haasec38fa1f2012-02-01 16:37:46 -08004928 case 2: return mAnimatorDurationScale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004929 }
4930 return 0;
4931 }
Romain Guy06882f82009-06-10 13:36:04 -07004932
Craig Mautner4b71aa12012-12-27 17:20:01 -08004933 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004934 public float[] getAnimationScales() {
Chet Haasec38fa1f2012-02-01 16:37:46 -08004935 return new float[] { mWindowAnimationScale, mTransitionAnimationScale,
4936 mAnimatorDurationScale };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004937 }
Romain Guy06882f82009-06-10 13:36:04 -07004938
Jeff Brownac143512012-04-05 18:57:33 -07004939 // Called by window manager policy. Not exposed externally.
4940 @Override
4941 public int getLidState() {
Jeff Brownc458ce92012-04-30 14:58:40 -07004942 int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY,
4943 InputManagerService.SW_LID);
Jeff Brownac143512012-04-05 18:57:33 -07004944 if (sw > 0) {
Jeff Brown27fd3422012-04-09 11:05:16 -07004945 // Switch state: AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL.
Jeff Brownac143512012-04-05 18:57:33 -07004946 return LID_CLOSED;
Jeff Brown27fd3422012-04-09 11:05:16 -07004947 } else if (sw == 0) {
4948 // Switch state: AKEY_STATE_UP.
4949 return LID_OPEN;
Jeff Brownac143512012-04-05 18:57:33 -07004950 } else {
Jeff Brown27fd3422012-04-09 11:05:16 -07004951 // Switch state: AKEY_STATE_UNKNOWN.
Jeff Brownac143512012-04-05 18:57:33 -07004952 return LID_ABSENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004953 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004954 }
Romain Guy06882f82009-06-10 13:36:04 -07004955
Jeff Brownac143512012-04-05 18:57:33 -07004956 // Called by window manager policy. Not exposed externally.
4957 @Override
Jeff Browna41ca772010-08-11 14:46:32 -07004958 public InputChannel monitorInput(String inputChannelName) {
Jeff Browna41ca772010-08-11 14:46:32 -07004959 return mInputManager.monitorInput(inputChannelName);
4960 }
4961
Jeff Brown7304c342012-05-11 18:42:42 -07004962 // Called by window manager policy. Not exposed externally.
4963 @Override
Jeff Browncf39bdf2012-05-18 14:41:19 -07004964 public void switchKeyboardLayout(int deviceId, int direction) {
4965 mInputManager.switchKeyboardLayout(deviceId, direction);
4966 }
4967
4968 // Called by window manager policy. Not exposed externally.
4969 @Override
Jeff Brown9a538ee2012-08-20 14:56:57 -07004970 public void shutdown(boolean confirm) {
4971 ShutdownThread.shutdown(mContext, confirm);
Jeff Brown7304c342012-05-11 18:42:42 -07004972 }
4973
4974 // Called by window manager policy. Not exposed externally.
4975 @Override
Jeff Brown9a538ee2012-08-20 14:56:57 -07004976 public void rebootSafeMode(boolean confirm) {
4977 ShutdownThread.rebootSafeMode(mContext, confirm);
Jeff Brown7304c342012-05-11 18:42:42 -07004978 }
4979
Craig Mautner6cfa7292013-01-15 09:05:42 -08004980 @Override
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07004981 public void setInputFilter(IInputFilter filter) {
4982 if (!checkCallingPermission(android.Manifest.permission.FILTER_EVENTS, "setInputFilter()")) {
4983 throw new SecurityException("Requires FILTER_EVENTS permission");
4984 }
Jeff Brown0029c662011-03-30 02:25:18 -07004985 mInputManager.setInputFilter(filter);
4986 }
4987
Craig Mautnerf1b67412012-09-19 13:18:29 -07004988 public void setCurrentUser(final int newUserId) {
4989 synchronized (mWindowMap) {
4990 mCurrentUserId = newUserId;
Amith Yamasani4befbec2013-07-10 16:18:01 -07004991 mAppTransition.setCurrentUser(newUserId);
Craig Mautnerf1b67412012-09-19 13:18:29 -07004992 mPolicy.setCurrentUserLw(newUserId);
Craig Mautner88400d32012-09-30 12:35:45 -07004993
4994 // Hide windows that should not be seen by the new user.
Craig Mautner7c6be102013-07-16 12:30:28 -07004995 final int numDisplays = mDisplayContents.size();
4996 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
4997 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
4998 final WindowList windows = displayContent.getWindowList();
Craig Mautner88400d32012-09-30 12:35:45 -07004999 for (int i = 0; i < windows.size(); i++) {
5000 final WindowState win = windows.get(i);
Craig Mautner5962b122012-10-05 14:45:52 -07005001 if (win.isHiddenFromUserLocked()) {
Craig Mautner88400d32012-09-30 12:35:45 -07005002 Slog.w(TAG, "current user violation " + newUserId + " hiding "
5003 + win + ", attrs=" + win.mAttrs.type + ", belonging to "
5004 + win.mOwnerUid);
5005 win.hideLw(false);
5006 }
5007 }
5008 }
5009 performLayoutAndPlaceSurfacesLocked();
Craig Mautnerf1b67412012-09-19 13:18:29 -07005010 }
5011 }
5012
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005013 public void enableScreenAfterBoot() {
5014 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005015 if (DEBUG_BOOT) {
5016 RuntimeException here = new RuntimeException("here");
5017 here.fillInStackTrace();
5018 Slog.i(TAG, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled
5019 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5020 + " mShowingBootMessages=" + mShowingBootMessages
5021 + " mSystemBooted=" + mSystemBooted, here);
5022 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005023 if (mSystemBooted) {
5024 return;
5025 }
5026 mSystemBooted = true;
Dianne Hackborn661cd522011-08-22 00:26:20 -07005027 hideBootMessagesLocked();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005028 // If the screen still doesn't come up after 30 seconds, give
5029 // up and turn it on.
You Kimcb6291c2012-12-04 23:22:28 +09005030 mH.sendEmptyMessageDelayed(H.BOOT_TIMEOUT, 30*1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005031 }
Romain Guy06882f82009-06-10 13:36:04 -07005032
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07005033 mPolicy.systemBooted();
5034
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005035 performEnableScreen();
5036 }
Romain Guy06882f82009-06-10 13:36:04 -07005037
Dianne Hackborn661cd522011-08-22 00:26:20 -07005038 void enableScreenIfNeededLocked() {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005039 if (DEBUG_BOOT) {
5040 RuntimeException here = new RuntimeException("here");
5041 here.fillInStackTrace();
5042 Slog.i(TAG, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled
5043 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5044 + " mShowingBootMessages=" + mShowingBootMessages
5045 + " mSystemBooted=" + mSystemBooted, here);
5046 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005047 if (mDisplayEnabled) {
5048 return;
5049 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005050 if (!mSystemBooted && !mShowingBootMessages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005051 return;
5052 }
You Kimcb6291c2012-12-04 23:22:28 +09005053 mH.sendEmptyMessage(H.ENABLE_SCREEN);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005054 }
Romain Guy06882f82009-06-10 13:36:04 -07005055
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005056 public void performBootTimeout() {
5057 synchronized(mWindowMap) {
Mike Lockwoodd747dc82011-09-13 16:28:22 -04005058 if (mDisplayEnabled || mHeadless) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005059 return;
5060 }
5061 Slog.w(TAG, "***** BOOT TIMEOUT: forcing display enabled");
5062 mForceDisplayEnabled = true;
5063 }
5064 performEnableScreen();
5065 }
5066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005067 public void performEnableScreen() {
5068 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005069 if (DEBUG_BOOT) {
5070 RuntimeException here = new RuntimeException("here");
5071 here.fillInStackTrace();
5072 Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
5073 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5074 + " mShowingBootMessages=" + mShowingBootMessages
Jeff Brown780c46f2012-06-24 12:15:38 -07005075 + " mSystemBooted=" + mSystemBooted
5076 + " mOnlyCore=" + mOnlyCore, here);
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005077 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005078 if (mDisplayEnabled) {
5079 return;
5080 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005081 if (!mSystemBooted && !mShowingBootMessages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005082 return;
5083 }
Romain Guy06882f82009-06-10 13:36:04 -07005084
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005085 if (!mForceDisplayEnabled) {
5086 // Don't enable the screen until all existing windows
5087 // have been drawn.
5088 boolean haveBootMsg = false;
5089 boolean haveApp = false;
Justin Mattson4233f262012-04-09 18:23:16 -07005090 // if the wallpaper service is disabled on the device, we're never going to have
5091 // wallpaper, don't bother waiting for it
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005092 boolean haveWallpaper = false;
Justin Mattson4233f262012-04-09 18:23:16 -07005093 boolean wallpaperEnabled = mContext.getResources().getBoolean(
Jeff Brown780c46f2012-06-24 12:15:38 -07005094 com.android.internal.R.bool.config_enableWallpaperService)
5095 && !mOnlyCore;
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005096 boolean haveKeyguard = true;
Craig Mautner59c00972012-07-30 12:10:24 -07005097 // TODO(multidisplay): Expand to all displays?
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005098 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07005099 final int N = windows.size();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005100 for (int i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07005101 WindowState w = windows.get(i);
Craig Mautner65d11b32012-10-01 13:59:52 -07005102 if (w.mAttrs.type == TYPE_KEYGUARD) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005103 // Only if there is a keyguard attached to the window manager
5104 // will we consider ourselves as having a keyguard. If it
5105 // isn't attached, we don't know if it wants to be shown or
5106 // hidden. If it is attached, we will say we have a keyguard
5107 // if the window doesn't want to be visible, because in that
5108 // case it explicitly doesn't want to be shown so we should
5109 // not delay turning the screen on for it.
5110 boolean vis = w.mViewVisibility == View.VISIBLE
5111 && w.mPolicyVisibility;
5112 haveKeyguard = !vis;
5113 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005114 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
5115 return;
5116 }
5117 if (w.isDrawnLw()) {
Craig Mautner65d11b32012-10-01 13:59:52 -07005118 if (w.mAttrs.type == TYPE_BOOT_PROGRESS) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005119 haveBootMsg = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005120 } else if (w.mAttrs.type == TYPE_APPLICATION) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005121 haveApp = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005122 } else if (w.mAttrs.type == TYPE_WALLPAPER) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005123 haveWallpaper = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005124 } else if (w.mAttrs.type == TYPE_KEYGUARD) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005125 haveKeyguard = true;
5126 }
5127 }
5128 }
5129
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005130 if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005131 Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
5132 + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
Justin Mattson4233f262012-04-09 18:23:16 -07005133 + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled
5134 + " haveKeyguard=" + haveKeyguard);
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005135 }
5136
5137 // If we are turning on the screen to show the boot message,
5138 // don't do it until the boot message is actually displayed.
5139 if (!mSystemBooted && !haveBootMsg) {
5140 return;
5141 }
Craig Mautner312eac42012-11-13 10:56:22 -08005142
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005143 // If we are turning on the screen after the boot is completed
5144 // normally, don't do so until we have the application and
5145 // wallpaper.
Justin Mattson4233f262012-04-09 18:23:16 -07005146 if (mSystemBooted && ((!haveApp && !haveKeyguard) ||
5147 (wallpaperEnabled && !haveWallpaper))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005148 return;
5149 }
5150 }
Romain Guy06882f82009-06-10 13:36:04 -07005151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005152 mDisplayEnabled = true;
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005153 if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005154 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005155 StringWriter sw = new StringWriter();
5156 PrintWriter pw = new PrintWriter(sw);
5157 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005158 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005159 }
5160 try {
5161 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
5162 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005163 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005164 Parcel data = Parcel.obtain();
5165 data.writeInterfaceToken("android.ui.ISurfaceComposer");
Jeff Brownc042ee22012-05-08 13:03:42 -07005166 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005167 data, null, 0);
5168 data.recycle();
5169 }
5170 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005171 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005172 }
Jeff Brown08a746a2012-06-24 12:14:49 -07005173
5174 // Enable input dispatch.
5175 mInputMonitor.setEventDispatchingLw(mEventDispatchingEnabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005176 }
Romain Guy06882f82009-06-10 13:36:04 -07005177
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005178 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07005179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005180 // Make sure the last requested orientation has been applied.
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005181 updateRotationUnchecked(false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005182 }
Romain Guy06882f82009-06-10 13:36:04 -07005183
Dianne Hackborn661cd522011-08-22 00:26:20 -07005184 public void showBootMessage(final CharSequence msg, final boolean always) {
5185 boolean first = false;
5186 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005187 if (DEBUG_BOOT) {
5188 RuntimeException here = new RuntimeException("here");
5189 here.fillInStackTrace();
5190 Slog.i(TAG, "showBootMessage: msg=" + msg + " always=" + always
5191 + " mAllowBootMessages=" + mAllowBootMessages
5192 + " mShowingBootMessages=" + mShowingBootMessages
5193 + " mSystemBooted=" + mSystemBooted, here);
5194 }
Dianne Hackborn58f42a52011-10-10 13:46:34 -07005195 if (!mAllowBootMessages) {
5196 return;
5197 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005198 if (!mShowingBootMessages) {
5199 if (!always) {
5200 return;
5201 }
5202 first = true;
5203 }
5204 if (mSystemBooted) {
5205 return;
5206 }
5207 mShowingBootMessages = true;
5208 mPolicy.showBootMessage(msg, always);
5209 }
5210 if (first) {
5211 performEnableScreen();
5212 }
5213 }
5214
5215 public void hideBootMessagesLocked() {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005216 if (DEBUG_BOOT) {
5217 RuntimeException here = new RuntimeException("here");
5218 here.fillInStackTrace();
5219 Slog.i(TAG, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled
5220 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5221 + " mShowingBootMessages=" + mShowingBootMessages
5222 + " mSystemBooted=" + mSystemBooted, here);
5223 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005224 if (mShowingBootMessages) {
5225 mShowingBootMessages = false;
5226 mPolicy.hideBootMessages();
5227 }
5228 }
5229
Craig Mautner6cfa7292013-01-15 09:05:42 -08005230 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005231 public void setInTouchMode(boolean mode) {
5232 synchronized(mWindowMap) {
5233 mInTouchMode = mode;
5234 }
5235 }
5236
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005237 // TODO: more accounting of which pid(s) turned it on, keep count,
5238 // only allow disables from pids which have count on, etc.
Craig Mautner0447a812012-05-22 16:01:31 -07005239 @Override
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005240 public void showStrictModeViolation(boolean on) {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07005241 if (mHeadless) return;
Chris Craik3198ef32012-10-10 14:52:30 -07005242 int pid = Binder.getCallingPid();
5243 mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, on ? 1 : 0, pid));
Craig Mautner0447a812012-05-22 16:01:31 -07005244 }
Mike Lockwood3a74bd32011-08-12 13:55:22 -07005245
Chris Craik3198ef32012-10-10 14:52:30 -07005246 private void showStrictModeViolation(int arg, int pid) {
Craig Mautner0447a812012-05-22 16:01:31 -07005247 final boolean on = arg != 0;
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005248 synchronized(mWindowMap) {
5249 // Ignoring requests to enable the red border from clients
5250 // which aren't on screen. (e.g. Broadcast Receivers in
5251 // the background..)
5252 if (on) {
5253 boolean isVisible = false;
Craig Mautner7c6be102013-07-16 12:30:28 -07005254 final int numDisplays = mDisplayContents.size();
5255 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
5256 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
5257 final int numWindows = windows.size();
5258 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
5259 final WindowState ws = windows.get(winNdx);
5260 if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
5261 isVisible = true;
5262 break;
5263 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005264 }
5265 }
5266 if (!isVisible) {
5267 return;
5268 }
5269 }
5270
Dianne Hackborn36991742011-10-11 21:35:26 -07005271 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
5272 ">>> OPEN TRANSACTION showStrictModeViolation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -08005273 SurfaceControl.openTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005274 try {
Jeff Browne215f262012-09-10 16:01:14 -07005275 // TODO(multi-display): support multiple displays
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005276 if (mStrictModeFlash == null) {
Jeff Browne215f262012-09-10 16:01:14 -07005277 mStrictModeFlash = new StrictModeFlash(
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005278 getDefaultDisplayContentLocked().getDisplay(), mFxSession);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005279 }
5280 mStrictModeFlash.setVisibility(on);
5281 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -08005282 SurfaceControl.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -07005283 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
5284 "<<< CLOSE TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005285 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005286 }
5287 }
5288
Craig Mautner6cfa7292013-01-15 09:05:42 -08005289 @Override
Brad Fitzpatrickc1a968a2010-11-24 08:56:40 -08005290 public void setStrictModeVisualIndicatorPreference(String value) {
5291 SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
5292 }
5293
Jim Millere70d5062011-03-08 21:38:39 -08005294 /**
5295 * Takes a snapshot of the screen. In landscape mode this grabs the whole screen.
5296 * In portrait mode, it grabs the upper region of the screen based on the vertical dimension
5297 * of the target image.
Craig Mautner312eac42012-11-13 10:56:22 -08005298 *
Craig Mautner59c00972012-07-30 12:10:24 -07005299 * @param displayId the Display to take a screenshot of.
Jim Millere70d5062011-03-08 21:38:39 -08005300 * @param width the width of the target bitmap
5301 * @param height the height of the target bitmap
5302 */
Craig Mautner2d5618c2012-10-18 13:55:47 -07005303 @Override
Craig Mautner59c00972012-07-30 12:10:24 -07005304 public Bitmap screenshotApplications(IBinder appToken, int displayId, int width, int height) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005305 if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5306 "screenshotApplications()")) {
5307 throw new SecurityException("Requires READ_FRAME_BUFFER permission");
5308 }
5309
Craig Mautner24d887472013-03-20 15:40:36 -07005310 Bitmap rawss = null;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005311
Dianne Hackbornd2835932010-12-13 16:28:46 -08005312 int maxLayer = 0;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005313 final Rect frame = new Rect();
5314
Craig Mautner24d887472013-03-20 15:40:36 -07005315 float scale = 0;
Jim Millere70d5062011-03-08 21:38:39 -08005316 int dw, dh;
Craig Mautner24d887472013-03-20 15:40:36 -07005317 int rot = Surface.ROTATION_0;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005318
Craig Mautner24d887472013-03-20 15:40:36 -07005319 boolean screenshotReady;
5320 int minLayer;
5321 if (appToken == null) {
5322 screenshotReady = true;
5323 minLayer = 0;
5324 } else {
5325 screenshotReady = false;
5326 minLayer = Integer.MAX_VALUE;
5327 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005328
Craig Mautner24d887472013-03-20 15:40:36 -07005329 int retryCount = 0;
5330 WindowState appWin = null;
5331
5332 do {
5333 if (retryCount++ > 0) {
5334 try {
5335 Thread.sleep(100);
5336 } catch (InterruptedException e) {
5337 }
Craig Mautner2d5618c2012-10-18 13:55:47 -07005338 }
Craig Mautner24d887472013-03-20 15:40:36 -07005339 synchronized(mWindowMap) {
5340 final DisplayContent displayContent = getDisplayContentLocked(displayId);
5341 if (displayContent == null) {
5342 return null;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005343 }
Craig Mautner24d887472013-03-20 15:40:36 -07005344 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
5345 dw = displayInfo.logicalWidth;
5346 dh = displayInfo.logicalHeight;
5347
5348 int aboveAppLayer = mPolicy.windowTypeToLayerLw(TYPE_APPLICATION)
5349 * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
5350 aboveAppLayer += TYPE_LAYER_MULTIPLIER;
5351
5352 boolean isImeTarget = mInputMethodTarget != null
5353 && mInputMethodTarget.mAppToken != null
5354 && mInputMethodTarget.mAppToken.appToken != null
5355 && mInputMethodTarget.mAppToken.appToken.asBinder() == appToken;
5356
5357 // Figure out the part of the screen that is actually the app.
5358 boolean including = false;
5359 appWin = null;
5360 final WindowList windows = displayContent.getWindowList();
5361 for (int i = windows.size() - 1; i >= 0; i--) {
5362 WindowState ws = windows.get(i);
5363 if (!ws.mHasSurface) {
5364 continue;
5365 }
5366 if (ws.mLayer >= aboveAppLayer) {
5367 continue;
5368 }
5369 // When we will skip windows: when we are not including
5370 // ones behind a window we didn't skip, and we are actually
5371 // taking a screenshot of a specific app.
5372 if (!including && appToken != null) {
5373 // Also, we can possibly skip this window if it is not
5374 // an IME target or the application for the screenshot
5375 // is not the current IME target.
5376 if (!ws.mIsImWindow || !isImeTarget) {
5377 // And finally, this window is of no interest if it
5378 // is not associated with the screenshot app.
5379 if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
5380 continue;
5381 }
5382 appWin = ws;
5383 }
5384 }
5385
5386 // We keep on including windows until we go past a full-screen
5387 // window.
5388 boolean fullscreen = ws.isFullscreen(dw, dh);
5389 including = !ws.mIsImWindow && !fullscreen;
5390
5391 final WindowStateAnimator winAnim = ws.mWinAnimator;
5392 if (maxLayer < winAnim.mSurfaceLayer) {
5393 maxLayer = winAnim.mSurfaceLayer;
5394 }
Craig Mautner4238e3e2013-03-28 15:28:55 -07005395 if (minLayer > winAnim.mSurfaceLayer) {
5396 minLayer = winAnim.mSurfaceLayer;
5397 }
Craig Mautner24d887472013-03-20 15:40:36 -07005398
5399 // Don't include wallpaper in bounds calculation
5400 if (!ws.mIsWallpaper) {
5401 final Rect wf = ws.mFrame;
5402 final Rect cr = ws.mContentInsets;
5403 int left = wf.left + cr.left;
5404 int top = wf.top + cr.top;
5405 int right = wf.right - cr.right;
5406 int bottom = wf.bottom - cr.bottom;
5407 frame.union(left, top, right, bottom);
5408 }
5409
Craig Mautner4238e3e2013-03-28 15:28:55 -07005410 if (ws.mAppToken != null && ws.mAppToken.token == appToken &&
5411 ws.isDisplayedLw()) {
5412 screenshotReady = true;
5413 }
5414
5415 if (fullscreen) {
5416 // No point in continuing down through windows.
5417 break;
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005418 }
5419 }
5420
Craig Mautner24d887472013-03-20 15:40:36 -07005421 if (appToken != null && appWin == null) {
5422 // Can't find a window to snapshot.
5423 if (DEBUG_SCREENSHOT) Slog.i(TAG,
5424 "Screenshot: Couldn't find a surface matching " + appToken);
5425 return null;
5426 }
5427 if (!screenshotReady) {
5428 // Delay and hope that window gets drawn.
5429 if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot: No image ready for " + appToken
5430 + ", " + appWin + " drawState=" + appWin.mWinAnimator.mDrawState);
5431 continue;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005432 }
Craig Mautner312eac42012-11-13 10:56:22 -08005433
Craig Mautner24d887472013-03-20 15:40:36 -07005434 // Constrain frame to the screen size.
5435 frame.intersect(0, 0, dw, dh);
5436
5437 if (frame.isEmpty() || maxLayer == 0) {
5438 if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot of " + appToken
5439 + ": returning null frame=" + frame.toShortString() + " maxLayer="
5440 + maxLayer);
5441 return null;
Jim Miller2aded182011-03-08 15:32:42 -08005442 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005443
Craig Mautner24d887472013-03-20 15:40:36 -07005444 // The screenshot API does not apply the current screen rotation.
5445 rot = getDefaultDisplayContentLocked().getDisplay().getRotation();
5446 int fw = frame.width();
5447 int fh = frame.height();
Jim Millere70d5062011-03-08 21:38:39 -08005448
Craig Mautner24d887472013-03-20 15:40:36 -07005449 // Constrain thumbnail to smaller of screen width or height. Assumes aspect
5450 // of thumbnail is the same as the screen (in landscape) or square.
5451 float targetWidthScale = width / (float) fw;
5452 float targetHeightScale = height / (float) fh;
5453 if (dw <= dh) {
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005454 scale = targetWidthScale;
Craig Mautner24d887472013-03-20 15:40:36 -07005455 // If aspect of thumbnail is the same as the screen (in landscape),
5456 // select the slightly larger value so we fill the entire bitmap
5457 if (targetHeightScale > scale && (int) (targetHeightScale * fw) == width) {
5458 scale = targetHeightScale;
5459 }
5460 } else {
5461 scale = targetHeightScale;
5462 // If aspect of thumbnail is the same as the screen (in landscape),
5463 // select the slightly larger value so we fill the entire bitmap
5464 if (targetWidthScale > scale && (int) (targetWidthScale * fh) == height) {
5465 scale = targetWidthScale;
5466 }
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005467 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005468
Craig Mautner24d887472013-03-20 15:40:36 -07005469 // The screen shot will contain the entire screen.
5470 dw = (int)(dw*scale);
5471 dh = (int)(dh*scale);
5472 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
5473 int tmp = dw;
5474 dw = dh;
5475 dh = tmp;
5476 rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -07005477 }
Craig Mautner24d887472013-03-20 15:40:36 -07005478 if (DEBUG_SCREENSHOT) {
5479 Slog.i(TAG, "Screenshot: " + dw + "x" + dh + " from " + minLayer + " to "
5480 + maxLayer + " appToken=" + appToken);
5481 for (int i = 0; i < windows.size(); i++) {
5482 WindowState win = windows.get(i);
5483 Slog.i(TAG, win + ": " + win.mLayer
5484 + " animLayer=" + win.mWinAnimator.mAnimLayer
5485 + " surfaceLayer=" + win.mWinAnimator.mSurfaceLayer);
5486 }
5487 }
5488 rawss = SurfaceControl.screenshot(dw, dh, minLayer, maxLayer);
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -07005489 }
Craig Mautner24d887472013-03-20 15:40:36 -07005490 } while (!screenshotReady && retryCount <= MAX_SCREENSHOT_RETRIES);
Craig Mautner4238e3e2013-03-28 15:28:55 -07005491 if (retryCount > MAX_SCREENSHOT_RETRIES) Slog.i(TAG, "Screenshot max retries " +
5492 retryCount + " of " + appToken + " appWin=" + (appWin == null ?
5493 "null" : (appWin + " drawState=" + appWin.mWinAnimator.mDrawState)));
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005494
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005495 if (rawss == null) {
Craig Mautner4238e3e2013-03-28 15:28:55 -07005496 Slog.w(TAG, "Screenshot failure taking screenshot for (" + dw + "x" + dh
Dianne Hackborn88b03bd2010-12-16 11:15:18 -08005497 + ") to layer " + maxLayer);
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005498 return null;
5499 }
Jim Millere70d5062011-03-08 21:38:39 -08005500
5501 Bitmap bm = Bitmap.createBitmap(width, height, rawss.getConfig());
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005502 Matrix matrix = new Matrix();
5503 ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
Michael Jurka4accb6a2012-03-26 09:18:46 -07005504 matrix.postTranslate(-FloatMath.ceil(frame.left*scale), -FloatMath.ceil(frame.top*scale));
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005505 Canvas canvas = new Canvas(bm);
Dianne Hackbornca46b872013-04-17 18:06:22 -07005506 canvas.drawColor(0xFF000000);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005507 canvas.drawBitmap(rawss, matrix, null);
Dianne Hackborn6311d0a2011-08-02 16:37:58 -07005508 canvas.setBitmap(null);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005509
Craig Mautner4238e3e2013-03-28 15:28:55 -07005510 if (true || DEBUG_SCREENSHOT) {
Craig Mautner24d887472013-03-20 15:40:36 -07005511 // TEST IF IT's ALL BLACK
5512 int[] buffer = new int[bm.getWidth() * bm.getHeight()];
5513 bm.getPixels(buffer, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm.getHeight());
5514 boolean allBlack = true;
5515 for (int i = 0; i < buffer.length; i++) {
5516 if (buffer[i] != Color.BLACK) {
5517 allBlack = false;
5518 break;
5519 }
5520 }
5521 if (allBlack) {
5522 Slog.i(TAG, "Screenshot " + appWin + " was all black! mSurfaceLayer=" +
Craig Mautner4238e3e2013-03-28 15:28:55 -07005523 (appWin != null ? appWin.mWinAnimator.mSurfaceLayer : "null") +
5524 " minLayer=" + minLayer + " maxLayer=" + maxLayer);
Craig Mautner24d887472013-03-20 15:40:36 -07005525 }
5526 }
5527
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005528 rawss.recycle();
5529 return bm;
5530 }
5531
Jeff Brown01a98dd2011-09-20 15:08:29 -07005532 /**
5533 * Freeze rotation changes. (Enable "rotation lock".)
5534 * Persists across reboots.
Jeff Brown4dfce202011-10-05 12:00:10 -07005535 * @param rotation The desired rotation to freeze to, or -1 to use the
5536 * current rotation.
Jeff Brown01a98dd2011-09-20 15:08:29 -07005537 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005538 @Override
Jeff Brown4dfce202011-10-05 12:00:10 -07005539 public void freezeRotation(int rotation) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005540 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005541 "freezeRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005542 throw new SecurityException("Requires SET_ORIENTATION permission");
5543 }
Jeff Brown4dfce202011-10-05 12:00:10 -07005544 if (rotation < -1 || rotation > Surface.ROTATION_270) {
5545 throw new IllegalArgumentException("Rotation argument must be -1 or a valid "
5546 + "rotation constant.");
5547 }
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005548
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005549 if (DEBUG_ORIENTATION) Slog.v(TAG, "freezeRotation: mRotation=" + mRotation);
5550
Daniel Sandler3de830b2013-02-20 15:23:52 -05005551 long origId = Binder.clearCallingIdentity();
5552 try {
5553 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED,
5554 rotation == -1 ? mRotation : rotation);
5555 } finally {
5556 Binder.restoreCallingIdentity(origId);
5557 }
5558
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005559 updateRotationUnchecked(false, false);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005560 }
5561
Jeff Brown01a98dd2011-09-20 15:08:29 -07005562 /**
5563 * Thaw rotation changes. (Disable "rotation lock".)
5564 * Persists across reboots.
5565 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005566 @Override
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005567 public void thawRotation() {
5568 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005569 "thawRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005570 throw new SecurityException("Requires SET_ORIENTATION permission");
5571 }
5572
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005573 if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation);
5574
Daniel Sandler3de830b2013-02-20 15:23:52 -05005575 long origId = Binder.clearCallingIdentity();
5576 try {
5577 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE,
5578 777); // rot not used
5579 } finally {
5580 Binder.restoreCallingIdentity(origId);
5581 }
5582
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005583 updateRotationUnchecked(false, false);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005584 }
5585
Jeff Brown01a98dd2011-09-20 15:08:29 -07005586 /**
5587 * Recalculate the current rotation.
5588 *
5589 * Called by the window manager policy whenever the state of the system changes
5590 * such that the current rotation might need to be updated, such as when the
5591 * device is docked or rotated into a new posture.
5592 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005593 @Override
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005594 public void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
5595 updateRotationUnchecked(alwaysSendConfiguration, forceRelayout);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005596 }
5597
5598 /**
5599 * Temporarily pauses rotation changes until resumed.
5600 *
5601 * This can be used to prevent rotation changes from occurring while the user is
5602 * performing certain operations, such as drag and drop.
5603 *
Craig Mautner6cfa7292013-01-15 09:05:42 -08005604 * This call nests and must be matched by an equal number of calls to
5605 * {@link #resumeRotationLocked}.
Jeff Brown01a98dd2011-09-20 15:08:29 -07005606 */
5607 void pauseRotationLocked() {
5608 mDeferredRotationPauseCount += 1;
5609 }
5610
5611 /**
5612 * Resumes normal rotation changes after being paused.
5613 */
5614 void resumeRotationLocked() {
5615 if (mDeferredRotationPauseCount > 0) {
5616 mDeferredRotationPauseCount -= 1;
5617 if (mDeferredRotationPauseCount == 0) {
5618 boolean changed = updateRotationUncheckedLocked(false);
5619 if (changed) {
5620 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
5621 }
5622 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005623 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005624 }
Romain Guy06882f82009-06-10 13:36:04 -07005625
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005626 public void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005627 if(DEBUG_ORIENTATION) Slog.v(TAG, "updateRotationUnchecked("
5628 + "alwaysSendConfiguration=" + alwaysSendConfiguration + ")");
Romain Guy06882f82009-06-10 13:36:04 -07005629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005630 long origId = Binder.clearCallingIdentity();
5631 boolean changed;
5632 synchronized(mWindowMap) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005633 changed = updateRotationUncheckedLocked(false);
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005634 if (!changed || forceRelayout) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005635 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005636 performLayoutAndPlaceSurfacesLocked();
5637 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005638 }
Romain Guy06882f82009-06-10 13:36:04 -07005639
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005640 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005641 sendNewConfiguration();
5642 }
Romain Guy06882f82009-06-10 13:36:04 -07005643
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005644 Binder.restoreCallingIdentity(origId);
5645 }
Romain Guy06882f82009-06-10 13:36:04 -07005646
Craig Mautner59c00972012-07-30 12:10:24 -07005647 // TODO(multidisplay): Rotate any display?
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005648 /**
Jeff Brown01a98dd2011-09-20 15:08:29 -07005649 * Updates the current rotation.
5650 *
5651 * Returns true if the rotation has been changed. In this case YOU
5652 * MUST CALL sendNewConfiguration() TO UNFREEZE THE SCREEN.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005653 */
Jeff Brown01a98dd2011-09-20 15:08:29 -07005654 public boolean updateRotationUncheckedLocked(boolean inTransaction) {
5655 if (mDeferredRotationPauseCount > 0) {
5656 // Rotation updates have been paused temporarily. Defer the update until
5657 // updates have been resumed.
5658 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, rotation is paused.");
Christopher Tateccd24de2011-01-12 15:02:55 -08005659 return false;
5660 }
5661
Craig Mautnera91f9e22012-09-14 16:22:08 -07005662 ScreenRotationAnimation screenRotationAnimation =
5663 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
5664 if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005665 // Rotation updates cannot be performed while the previous rotation change
5666 // animation is still in progress. Skip this update. We will try updating
5667 // again after the animation is finished and the display is unfrozen.
5668 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, animation in progress.");
5669 return false;
5670 }
5671
5672 if (!mDisplayEnabled) {
5673 // No point choosing a rotation if the display is not enabled.
5674 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, display is not enabled.");
5675 return false;
5676 }
5677
5678 // TODO: Implement forced rotation changes.
5679 // Set mAltOrientation to indicate that the application is receiving
5680 // an orientation that has different metrics than it expected.
5681 // eg. Portrait instead of Landscape.
5682
5683 int rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, mRotation);
5684 boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
5685 mForcedAppOrientation, rotation);
5686
5687 if (DEBUG_ORIENTATION) {
5688 Slog.v(TAG, "Application requested orientation "
5689 + mForcedAppOrientation + ", got rotation " + rotation
5690 + " which has " + (altOrientation ? "incompatible" : "compatible")
5691 + " metrics");
5692 }
5693
5694 if (mRotation == rotation && mAltOrientation == altOrientation) {
5695 // No change.
5696 return false;
5697 }
5698
5699 if (DEBUG_ORIENTATION) {
5700 Slog.v(TAG,
5701 "Rotation changed to " + rotation + (altOrientation ? " (alt)" : "")
5702 + " from " + mRotation + (mAltOrientation ? " (alt)" : "")
5703 + ", forceApp=" + mForcedAppOrientation);
5704 }
5705
5706 mRotation = rotation;
5707 mAltOrientation = altOrientation;
Jeff Brownc0347aa2011-09-23 17:26:09 -07005708 mPolicy.setRotationLw(mRotation);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005709
5710 mWindowsFreezingScreen = true;
5711 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
Craig Mautner0bf6ec92012-12-18 08:33:27 -08005712 mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT, WINDOW_FREEZE_TIMEOUT_DURATION);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005713 mWaitingForConfig = true;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005714 getDefaultDisplayContentLocked().layoutNeeded = true;
Craig Mautner3c174372013-02-21 17:54:37 -08005715 final int[] anim = new int[2];
5716 if (mAnimator.isDimmingLocked(Display.DEFAULT_DISPLAY)) {
5717 anim[0] = anim[1] = 0;
5718 } else {
5719 mPolicy.selectRotationAnimationLw(anim);
5720 }
5721 startFreezingDisplayLocked(inTransaction, anim[0], anim[1]);
Craig Mautnera91f9e22012-09-14 16:22:08 -07005722 // startFreezingDisplayLocked can reset the ScreenRotationAnimation.
5723 screenRotationAnimation =
5724 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005725
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08005726 // We need to update our screen size information to match the new
5727 // rotation. Note that this is redundant with the later call to
5728 // sendNewConfiguration() that must be called after this function
5729 // returns... however we need to do the screen size part of that
Jeff Brown4ed8fe72012-08-30 18:18:29 -07005730 // before then so we have the correct size to use when initializing
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08005731 // the rotation animation for the new rotation.
5732 computeScreenConfigurationLocked(null);
5733
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005734 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07005735 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07005736 if (!inTransaction) {
5737 if (SHOW_TRANSACTIONS) {
5738 Slog.i(TAG, ">>> OPEN TRANSACTION setRotationUnchecked");
5739 }
Mathias Agopian3866f0d2013-02-11 22:08:48 -08005740 SurfaceControl.openTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07005741 }
Jamie Gennise2909e12011-10-10 15:48:06 -07005742 try {
5743 // NOTE: We disable the rotation in the emulator because
5744 // it doesn't support hardware OpenGL emulation yet.
Craig Mautnera91f9e22012-09-14 16:22:08 -07005745 if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
5746 && screenRotationAnimation.hasScreenshot()) {
5747 if (screenRotationAnimation.setRotationInTransaction(
Jeff Brown4ed8fe72012-08-30 18:18:29 -07005748 rotation, mFxSession,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08005749 MAX_ANIMATION_DURATION, mTransitionAnimationScale,
Craig Mautner59c00972012-07-30 12:10:24 -07005750 displayInfo.logicalWidth, displayInfo.logicalHeight)) {
Craig Mautner96868332012-12-04 14:29:11 -08005751 scheduleAnimationLocked();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08005752 }
Jamie Gennise2909e12011-10-10 15:48:06 -07005753 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07005754
5755 mDisplayManagerService.performTraversalInTransactionFromWindowManager();
Jamie Gennise2909e12011-10-10 15:48:06 -07005756 } finally {
5757 if (!inTransaction) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -08005758 SurfaceControl.closeTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07005759 if (SHOW_LIGHT_TRANSACTIONS) {
5760 Slog.i(TAG, "<<< CLOSE TRANSACTION setRotationUnchecked");
5761 }
Jamie Gennise2909e12011-10-10 15:48:06 -07005762 }
5763 }
5764
Craig Mautner59c00972012-07-30 12:10:24 -07005765 final WindowList windows = displayContent.getWindowList();
5766 for (int i = windows.size() - 1; i >= 0; i--) {
5767 WindowState w = windows.get(i);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07005768 if (w.mHasSurface) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07005769 if (DEBUG_ORIENTATION) Slog.v(TAG, "Set mOrientationChanging of " + w);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005770 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07005771 mInnerFields.mOrientationChangeComplete = false;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005772 }
Dianne Hackborna57c6952013-03-29 14:46:40 -07005773 w.mLastFreezeDuration = 0;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005774 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07005775
Jeff Brown01a98dd2011-09-20 15:08:29 -07005776 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
5777 try {
5778 mRotationWatchers.get(i).onRotationChanged(rotation);
5779 } catch (RemoteException e) {
5780 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005781 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07005782
Svetoslav Ganov545252f2012-12-10 18:29:24 -08005783 //TODO (multidisplay): Magnification is supported only for the default display.
5784 if (mDisplayMagnifier != null
5785 && displayContent.getDisplayId() == Display.DEFAULT_DISPLAY) {
5786 mDisplayMagnifier.onRotationChangedLocked(getDefaultDisplayContentLocked(), rotation);
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07005787 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07005788
Jeff Brown01a98dd2011-09-20 15:08:29 -07005789 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005790 }
Romain Guy06882f82009-06-10 13:36:04 -07005791
Craig Mautner0bf6ec92012-12-18 08:33:27 -08005792 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005793 public int getRotation() {
5794 return mRotation;
5795 }
5796
Craig Mautner0bf6ec92012-12-18 08:33:27 -08005797 @Override
Svetoslav Ganov80943d82013-01-02 10:25:37 -08005798 public boolean isRotationFrozen() {
5799 return mPolicy.getUserRotationMode() == WindowManagerPolicy.USER_ROTATION_LOCKED;
5800 }
5801
5802 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005803 public int watchRotation(IRotationWatcher watcher) {
5804 final IBinder watcherBinder = watcher.asBinder();
5805 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
Craig Mautner0bf6ec92012-12-18 08:33:27 -08005806 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005807 public void binderDied() {
5808 synchronized (mWindowMap) {
5809 for (int i=0; i<mRotationWatchers.size(); i++) {
5810 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07005811 IRotationWatcher removed = mRotationWatchers.remove(i);
5812 if (removed != null) {
5813 removed.asBinder().unlinkToDeath(this, 0);
5814 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005815 i--;
5816 }
5817 }
5818 }
5819 }
5820 };
Romain Guy06882f82009-06-10 13:36:04 -07005821
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005822 synchronized (mWindowMap) {
5823 try {
5824 watcher.asBinder().linkToDeath(dr, 0);
5825 mRotationWatchers.add(watcher);
5826 } catch (RemoteException e) {
5827 // Client died, no cleanup needed.
5828 }
Romain Guy06882f82009-06-10 13:36:04 -07005829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005830 return mRotation;
5831 }
5832 }
5833
Brian Colonnab1b9a8a2013-03-29 11:52:42 -04005834 @Override
5835 public void removeRotationWatcher(IRotationWatcher watcher) {
5836 final IBinder watcherBinder = watcher.asBinder();
5837 synchronized (mWindowMap) {
5838 for (int i=0; i<mRotationWatchers.size(); i++) {
5839 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
5840 mRotationWatchers.remove(i);
5841 i--;
5842 }
5843 }
5844 }
5845 }
5846
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005847 /**
Adam Powelldfee59a2011-08-05 20:48:30 -07005848 * Apps that use the compact menu panel (as controlled by the panelMenuIsCompact
5849 * theme attribute) on devices that feature a physical options menu key attempt to position
5850 * their menu panel window along the edge of the screen nearest the physical menu key.
5851 * This lowers the travel distance between invoking the menu panel and selecting
5852 * a menu option.
5853 *
5854 * This method helps control where that menu is placed. Its current implementation makes
5855 * assumptions about the menu key and its relationship to the screen based on whether
5856 * the device's natural orientation is portrait (width < height) or landscape.
5857 *
5858 * The menu key is assumed to be located along the bottom edge of natural-portrait
5859 * devices and along the right edge of natural-landscape devices. If these assumptions
5860 * do not hold for the target device, this method should be changed to reflect that.
5861 *
5862 * @return A {@link Gravity} value for placing the options menu window
5863 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005864 @Override
Adam Powelldfee59a2011-08-05 20:48:30 -07005865 public int getPreferredOptionsPanelGravity() {
5866 synchronized (mWindowMap) {
5867 final int rotation = getRotation();
5868
Craig Mautner59c00972012-07-30 12:10:24 -07005869 // TODO(multidisplay): Assume that such devices physical keys are on the main screen.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005870 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07005871 if (displayContent.mInitialDisplayWidth < displayContent.mInitialDisplayHeight) {
Adam Powelldfee59a2011-08-05 20:48:30 -07005872 // On devices with a natural orientation of portrait
5873 switch (rotation) {
5874 default:
5875 case Surface.ROTATION_0:
5876 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
5877 case Surface.ROTATION_90:
Adam Powell67ed6c72011-08-28 13:21:56 -07005878 return Gravity.RIGHT | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07005879 case Surface.ROTATION_180:
Adam Powell67ed6c72011-08-28 13:21:56 -07005880 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07005881 case Surface.ROTATION_270:
Fabrice Di Meglioaac0d4e2012-07-19 19:21:26 -07005882 return Gravity.START | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07005883 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08005884 }
5885
5886 // On devices with a natural orientation of landscape
5887 switch (rotation) {
5888 default:
5889 case Surface.ROTATION_0:
5890 return Gravity.RIGHT | Gravity.BOTTOM;
5891 case Surface.ROTATION_90:
5892 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
5893 case Surface.ROTATION_180:
5894 return Gravity.START | Gravity.BOTTOM;
5895 case Surface.ROTATION_270:
5896 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07005897 }
5898 }
5899 }
5900
5901 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005902 * Starts the view server on the specified port.
5903 *
5904 * @param port The port to listener to.
5905 *
5906 * @return True if the server was successfully started, false otherwise.
5907 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08005908 * @see com.android.server.wm.ViewServer
5909 * @see com.android.server.wm.ViewServer#VIEW_SERVER_DEFAULT_PORT
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005910 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005911 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005912 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07005913 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005914 return false;
5915 }
5916
5917 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
5918 return false;
5919 }
5920
5921 if (port < 1024) {
5922 return false;
5923 }
5924
5925 if (mViewServer != null) {
5926 if (!mViewServer.isRunning()) {
5927 try {
5928 return mViewServer.start();
5929 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005930 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005931 }
5932 }
5933 return false;
5934 }
5935
5936 try {
5937 mViewServer = new ViewServer(this, port);
5938 return mViewServer.start();
5939 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005940 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005941 }
5942 return false;
5943 }
5944
Romain Guy06882f82009-06-10 13:36:04 -07005945 private boolean isSystemSecure() {
5946 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
5947 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5948 }
5949
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005950 /**
5951 * Stops the view server if it exists.
5952 *
5953 * @return True if the server stopped, false if it wasn't started or
5954 * couldn't be stopped.
5955 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08005956 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005957 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005958 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005959 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07005960 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005961 return false;
5962 }
5963
5964 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
5965 return false;
5966 }
5967
5968 if (mViewServer != null) {
5969 return mViewServer.stop();
5970 }
5971 return false;
5972 }
5973
5974 /**
5975 * Indicates whether the view server is running.
5976 *
5977 * @return True if the server is running, false otherwise.
5978 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08005979 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005980 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005981 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005982 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07005983 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005984 return false;
5985 }
5986
5987 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
5988 return false;
5989 }
5990
5991 return mViewServer != null && mViewServer.isRunning();
5992 }
5993
5994 /**
5995 * Lists all availble windows in the system. The listing is written in the
5996 * specified Socket's output stream with the following syntax:
5997 * windowHashCodeInHexadecimal windowName
5998 * Each line of the ouput represents a different window.
5999 *
6000 * @param client The remote client to send the listing to.
6001 * @return False if an error occured, true otherwise.
6002 */
6003 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07006004 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006005 return false;
6006 }
6007
6008 boolean result = true;
6009
Craig Mautner59c00972012-07-30 12:10:24 -07006010 WindowList windows = new WindowList();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006011 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006012 //noinspection unchecked
Craig Mautner7c6be102013-07-16 12:30:28 -07006013 final int numDisplays = mDisplayContents.size();
6014 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
6015 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
6016 windows.addAll(displayContent.getWindowList());
Craig Mautner59c00972012-07-30 12:10:24 -07006017 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006018 }
6019
6020 BufferedWriter out = null;
6021
6022 // Any uncaught exception will crash the system process
6023 try {
6024 OutputStream clientStream = client.getOutputStream();
6025 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
6026
Craig Mautner59c00972012-07-30 12:10:24 -07006027 final int count = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006028 for (int i = 0; i < count; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07006029 final WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006030 out.write(Integer.toHexString(System.identityHashCode(w)));
6031 out.write(' ');
6032 out.append(w.mAttrs.getTitle());
6033 out.write('\n');
6034 }
6035
6036 out.write("DONE.\n");
6037 out.flush();
6038 } catch (Exception e) {
6039 result = false;
6040 } finally {
6041 if (out != null) {
6042 try {
6043 out.close();
6044 } catch (IOException e) {
6045 result = false;
6046 }
6047 }
6048 }
6049
6050 return result;
6051 }
6052
Craig Mautner59c00972012-07-30 12:10:24 -07006053 // TODO(multidisplay): Extend to multiple displays.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006054 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07006055 * Returns the focused window in the following format:
6056 * windowHashCodeInHexadecimal windowName
6057 *
6058 * @param client The remote client to send the listing to.
6059 * @return False if an error occurred, true otherwise.
6060 */
6061 boolean viewServerGetFocusedWindow(Socket client) {
6062 if (isSystemSecure()) {
6063 return false;
6064 }
6065
6066 boolean result = true;
6067
6068 WindowState focusedWindow = getFocusedWindow();
6069
6070 BufferedWriter out = null;
6071
6072 // Any uncaught exception will crash the system process
6073 try {
6074 OutputStream clientStream = client.getOutputStream();
6075 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
6076
6077 if(focusedWindow != null) {
6078 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
6079 out.write(' ');
6080 out.append(focusedWindow.mAttrs.getTitle());
6081 }
6082 out.write('\n');
6083 out.flush();
6084 } catch (Exception e) {
6085 result = false;
6086 } finally {
6087 if (out != null) {
6088 try {
6089 out.close();
6090 } catch (IOException e) {
6091 result = false;
6092 }
6093 }
6094 }
6095
6096 return result;
6097 }
6098
6099 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006100 * Sends a command to a target window. The result of the command, if any, will be
6101 * written in the output stream of the specified socket.
6102 *
6103 * The parameters must follow this syntax:
6104 * windowHashcode extra
6105 *
6106 * Where XX is the length in characeters of the windowTitle.
6107 *
6108 * The first parameter is the target window. The window with the specified hashcode
6109 * will be the target. If no target can be found, nothing happens. The extra parameters
6110 * will be delivered to the target window and as parameters to the command itself.
6111 *
6112 * @param client The remote client to sent the result, if any, to.
6113 * @param command The command to execute.
6114 * @param parameters The command parameters.
6115 *
6116 * @return True if the command was successfully delivered, false otherwise. This does
6117 * not indicate whether the command itself was successful.
6118 */
6119 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07006120 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006121 return false;
6122 }
6123
6124 boolean success = true;
6125 Parcel data = null;
6126 Parcel reply = null;
6127
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006128 BufferedWriter out = null;
6129
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006130 // Any uncaught exception will crash the system process
6131 try {
6132 // Find the hashcode of the window
6133 int index = parameters.indexOf(' ');
6134 if (index == -1) {
6135 index = parameters.length();
6136 }
6137 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08006138 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006139
6140 // Extract the command's parameter after the window description
6141 if (index < parameters.length()) {
6142 parameters = parameters.substring(index + 1);
6143 } else {
6144 parameters = "";
6145 }
6146
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006147 final WindowState window = findWindow(hashCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006148 if (window == null) {
6149 return false;
6150 }
6151
6152 data = Parcel.obtain();
6153 data.writeInterfaceToken("android.view.IWindow");
6154 data.writeString(command);
6155 data.writeString(parameters);
6156 data.writeInt(1);
6157 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
6158
6159 reply = Parcel.obtain();
6160
6161 final IBinder binder = window.mClient.asBinder();
6162 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
6163 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
6164
6165 reply.readException();
6166
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006167 if (!client.isOutputShutdown()) {
6168 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
6169 out.write("DONE\n");
6170 out.flush();
6171 }
6172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006173 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006174 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006175 success = false;
6176 } finally {
6177 if (data != null) {
6178 data.recycle();
6179 }
6180 if (reply != null) {
6181 reply.recycle();
6182 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006183 if (out != null) {
6184 try {
6185 out.close();
6186 } catch (IOException e) {
6187
6188 }
6189 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006190 }
6191
6192 return success;
6193 }
6194
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07006195 public void addWindowChangeListener(WindowChangeListener listener) {
6196 synchronized(mWindowMap) {
6197 mWindowChangeListeners.add(listener);
6198 }
6199 }
6200
6201 public void removeWindowChangeListener(WindowChangeListener listener) {
6202 synchronized(mWindowMap) {
6203 mWindowChangeListeners.remove(listener);
6204 }
6205 }
6206
6207 private void notifyWindowsChanged() {
6208 WindowChangeListener[] windowChangeListeners;
6209 synchronized(mWindowMap) {
6210 if(mWindowChangeListeners.isEmpty()) {
6211 return;
6212 }
6213 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
6214 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
6215 }
6216 int N = windowChangeListeners.length;
6217 for(int i = 0; i < N; i++) {
6218 windowChangeListeners[i].windowsChanged();
6219 }
6220 }
6221
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07006222 private void notifyFocusChanged() {
6223 WindowChangeListener[] windowChangeListeners;
6224 synchronized(mWindowMap) {
6225 if(mWindowChangeListeners.isEmpty()) {
6226 return;
6227 }
6228 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
6229 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
6230 }
6231 int N = windowChangeListeners.length;
6232 for(int i = 0; i < N; i++) {
6233 windowChangeListeners[i].focusChanged();
6234 }
6235 }
6236
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006237 private WindowState findWindow(int hashCode) {
6238 if (hashCode == -1) {
Craig Mautner59c00972012-07-30 12:10:24 -07006239 // TODO(multidisplay): Extend to multiple displays.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006240 return getFocusedWindow();
6241 }
6242
6243 synchronized (mWindowMap) {
Craig Mautner7c6be102013-07-16 12:30:28 -07006244 final int numDisplays = mDisplayContents.size();
6245 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
6246 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
6247 final int numWindows = windows.size();
6248 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
6249 final WindowState w = windows.get(winNdx);
6250 if (System.identityHashCode(w) == hashCode) {
6251 return w;
6252 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006253 }
6254 }
6255 }
6256
6257 return null;
6258 }
6259
6260 /*
6261 * Instruct the Activity Manager to fetch the current configuration and broadcast
6262 * that to config-changed listeners if appropriate.
6263 */
6264 void sendNewConfiguration() {
6265 try {
6266 mActivityManager.updateConfiguration(null);
6267 } catch (RemoteException e) {
6268 }
6269 }
Romain Guy06882f82009-06-10 13:36:04 -07006270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006271 public Configuration computeNewConfiguration() {
6272 synchronized (mWindowMap) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006273 Configuration config = computeNewConfigurationLocked();
6274 if (config == null && mWaitingForConfig) {
6275 // Nothing changed but we are waiting for something... stop that!
6276 mWaitingForConfig = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07006277 mLastFinishedFreezeSource = "new-config";
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006278 performLayoutAndPlaceSurfacesLocked();
6279 }
6280 return config;
Dianne Hackbornc485a602009-03-24 22:39:49 -07006281 }
6282 }
Romain Guy06882f82009-06-10 13:36:04 -07006283
Dianne Hackbornc485a602009-03-24 22:39:49 -07006284 Configuration computeNewConfigurationLocked() {
6285 Configuration config = new Configuration();
Dianne Hackborn09e5b9d2011-10-04 16:32:01 -07006286 config.fontScale = 0;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006287 if (!computeScreenConfigurationLocked(config)) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07006288 return null;
6289 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07006290 return config;
6291 }
Romain Guy06882f82009-06-10 13:36:04 -07006292
Craig Mautner59c00972012-07-30 12:10:24 -07006293 private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation, int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006294 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006295 final int width = mPolicy.getConfigDisplayWidth(dw, dh, rotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006296 if (width < displayInfo.smallestNominalAppWidth) {
6297 displayInfo.smallestNominalAppWidth = width;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006298 }
Craig Mautner59c00972012-07-30 12:10:24 -07006299 if (width > displayInfo.largestNominalAppWidth) {
6300 displayInfo.largestNominalAppWidth = width;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006301 }
6302 final int height = mPolicy.getConfigDisplayHeight(dw, dh, rotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006303 if (height < displayInfo.smallestNominalAppHeight) {
6304 displayInfo.smallestNominalAppHeight = height;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006305 }
Craig Mautner59c00972012-07-30 12:10:24 -07006306 if (height > displayInfo.largestNominalAppHeight) {
6307 displayInfo.largestNominalAppHeight = height;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006308 }
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006309 }
6310
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006311 private int reduceConfigLayout(int curLayout, int rotation, float density,
6312 int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006313 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006314 // Get the app screen size at this rotation.
6315 int w = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
6316 int h = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
6317
6318 // Compute the screen layout size class for this rotation.
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006319 int longSize = w;
6320 int shortSize = h;
6321 if (longSize < shortSize) {
6322 int tmp = longSize;
6323 longSize = shortSize;
6324 shortSize = tmp;
6325 }
6326 longSize = (int)(longSize/density);
6327 shortSize = (int)(shortSize/density);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006328 return Configuration.reduceScreenLayout(curLayout, longSize, shortSize);
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006329 }
6330
Craig Mautner59c00972012-07-30 12:10:24 -07006331 private void computeSizeRangesAndScreenLayout(DisplayInfo displayInfo, boolean rotated,
6332 int dw, int dh, float density, Configuration outConfig) {
Craig Mautner69b08182012-09-05 13:07:13 -07006333 // TODO: Multidisplay: for now only use with default display.
6334
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006335 // We need to determine the smallest width that will occur under normal
6336 // operation. To this, start with the base screen size and compute the
6337 // width under the different possible rotations. We need to un-rotate
6338 // the current screen dimensions before doing this.
6339 int unrotDw, unrotDh;
6340 if (rotated) {
6341 unrotDw = dh;
6342 unrotDh = dw;
6343 } else {
6344 unrotDw = dw;
6345 unrotDh = dh;
6346 }
Craig Mautner59c00972012-07-30 12:10:24 -07006347 displayInfo.smallestNominalAppWidth = 1<<30;
6348 displayInfo.smallestNominalAppHeight = 1<<30;
6349 displayInfo.largestNominalAppWidth = 0;
6350 displayInfo.largestNominalAppHeight = 0;
6351 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, unrotDw, unrotDh);
6352 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, unrotDh, unrotDw);
6353 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, unrotDw, unrotDh);
6354 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, unrotDh, unrotDw);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006355 int sl = Configuration.resetScreenLayout(outConfig.screenLayout);
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006356 sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh);
6357 sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw);
6358 sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh);
6359 sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw);
Craig Mautner59c00972012-07-30 12:10:24 -07006360 outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006361 outConfig.screenLayout = sl;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006362 }
6363
Dianne Hackborn48a76512011-06-08 21:51:44 -07006364 private int reduceCompatConfigWidthSize(int curSize, int rotation, DisplayMetrics dm,
6365 int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006366 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn1f903c32011-09-13 19:18:06 -07006367 dm.noncompatWidthPixels = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
6368 dm.noncompatHeightPixels = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006369 float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
Dianne Hackborn2b31d532011-06-23 11:58:50 -07006370 int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006371 if (curSize == 0 || size < curSize) {
6372 curSize = size;
6373 }
6374 return curSize;
6375 }
6376
6377 private int computeCompatSmallestWidth(boolean rotated, DisplayMetrics dm, int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006378 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn48a76512011-06-08 21:51:44 -07006379 mTmpDisplayMetrics.setTo(dm);
Craig Mautner69b08182012-09-05 13:07:13 -07006380 final DisplayMetrics tmpDm = mTmpDisplayMetrics;
6381 final int unrotDw, unrotDh;
Dianne Hackborn48a76512011-06-08 21:51:44 -07006382 if (rotated) {
6383 unrotDw = dh;
6384 unrotDh = dw;
6385 } else {
6386 unrotDw = dw;
6387 unrotDh = dh;
6388 }
Craig Mautner69b08182012-09-05 13:07:13 -07006389 int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, tmpDm, unrotDw, unrotDh);
6390 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, tmpDm, unrotDh, unrotDw);
6391 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, tmpDm, unrotDw, unrotDh);
6392 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, tmpDm, unrotDh, unrotDw);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006393 return sw;
6394 }
6395
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006396 boolean computeScreenConfigurationLocked(Configuration config) {
Jeff Browne215f262012-09-10 16:01:14 -07006397 if (!mDisplayReady) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07006398 return false;
6399 }
Christopher Tateb696aee2010-04-02 19:08:30 -07006400
Craig Mautner59c00972012-07-30 12:10:24 -07006401 // TODO(multidisplay): For now, apply Configuration to main screen only.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006402 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07006403
Christopher Tateb696aee2010-04-02 19:08:30 -07006404 // Use the effective "visual" dimensions based on current rotation
6405 final boolean rotated = (mRotation == Surface.ROTATION_90
6406 || mRotation == Surface.ROTATION_270);
Craig Mautner59c00972012-07-30 12:10:24 -07006407 final int realdw = rotated ?
6408 displayContent.mBaseDisplayHeight : displayContent.mBaseDisplayWidth;
6409 final int realdh = rotated ?
6410 displayContent.mBaseDisplayWidth : displayContent.mBaseDisplayHeight;
Jeff Brownfa25bf52012-07-23 19:26:30 -07006411 int dw = realdw;
6412 int dh = realdh;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006413
Jeff Brownfa25bf52012-07-23 19:26:30 -07006414 if (mAltOrientation) {
6415 if (realdw > realdh) {
6416 // Turn landscape into portrait.
6417 int maxw = (int)(realdh/1.3f);
6418 if (maxw < realdw) {
6419 dw = maxw;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006420 }
6421 } else {
Jeff Brownfa25bf52012-07-23 19:26:30 -07006422 // Turn portrait into landscape.
6423 int maxh = (int)(realdw/1.3f);
6424 if (maxh < realdh) {
6425 dh = maxh;
6426 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006427 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006428 }
6429
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006430 if (config != null) {
Jeff Browne215f262012-09-10 16:01:14 -07006431 config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
6432 Configuration.ORIENTATION_LANDSCAPE;
Dianne Hackbornc485a602009-03-24 22:39:49 -07006433 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006434
Jeff Brownbc68a592011-07-25 12:58:12 -07006435 // Update application display metrics.
Dianne Hackborn1fbee792011-11-30 11:29:58 -08006436 final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation);
6437 final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006438 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
6439 synchronized(displayContent.mDisplaySizeLock) {
6440 displayInfo.rotation = mRotation;
6441 displayInfo.logicalWidth = dw;
6442 displayInfo.logicalHeight = dh;
Dianne Hackborndde331c2012-08-03 14:01:57 -07006443 displayInfo.logicalDensityDpi = displayContent.mBaseDisplayDensity;
Craig Mautner59c00972012-07-30 12:10:24 -07006444 displayInfo.appWidth = appWidth;
6445 displayInfo.appHeight = appHeight;
6446 displayInfo.getLogicalMetrics(mRealDisplayMetrics, null);
6447 displayInfo.getAppMetrics(mDisplayMetrics, null);
Jeff Brownbd6e1502012-08-28 03:27:37 -07006448 mDisplayManagerService.setDisplayInfoOverrideFromWindowManager(
6449 displayContent.getDisplayId(), displayInfo);
Dianne Hackborn1fbee792011-11-30 11:29:58 -08006450 }
Dianne Hackborn36991742011-10-11 21:35:26 -07006451 if (false) {
Jeff Brownfa25bf52012-07-23 19:26:30 -07006452 Slog.i(TAG, "Set app display size: " + appWidth + " x " + appHeight);
Dianne Hackborn36991742011-10-11 21:35:26 -07006453 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006454
Jeff Brownfa25bf52012-07-23 19:26:30 -07006455 final DisplayMetrics dm = mDisplayMetrics;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006456 mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm,
6457 mCompatDisplayMetrics);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006458
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006459 if (config != null) {
6460 config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation)
6461 / dm.density);
6462 config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation)
6463 / dm.density);
Craig Mautner59c00972012-07-30 12:10:24 -07006464 computeSizeRangesAndScreenLayout(displayInfo, rotated, dw, dh, dm.density, config);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006465
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006466 config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
6467 config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
6468 config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dm, dw, dh);
Dianne Hackborndde331c2012-08-03 14:01:57 -07006469 config.densityDpi = displayContent.mBaseDisplayDensity;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006470
Jeff Browndaa37532012-05-01 15:54:03 -07006471 // Update the configuration based on available input devices, lid switch,
6472 // and platform configuration.
6473 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
6474 config.keyboard = Configuration.KEYBOARD_NOKEYS;
6475 config.navigation = Configuration.NAVIGATION_NONAV;
6476
6477 int keyboardPresence = 0;
6478 int navigationPresence = 0;
Craig Mautner1d961d42012-05-27 12:02:11 -07006479 final InputDevice[] devices = mInputManager.getInputDevices();
6480 final int len = devices.length;
6481 for (int i = 0; i < len; i++) {
6482 InputDevice device = devices[i];
Jeff Browndaa37532012-05-01 15:54:03 -07006483 if (!device.isVirtual()) {
6484 final int sources = device.getSources();
6485 final int presenceFlag = device.isExternal() ?
6486 WindowManagerPolicy.PRESENCE_EXTERNAL :
6487 WindowManagerPolicy.PRESENCE_INTERNAL;
6488
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -07006489 if (mIsTouchDevice) {
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006490 if ((sources & InputDevice.SOURCE_TOUCHSCREEN) ==
6491 InputDevice.SOURCE_TOUCHSCREEN) {
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -07006492 config.touchscreen = Configuration.TOUCHSCREEN_FINGER;
6493 }
6494 } else {
6495 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
Jeff Browndaa37532012-05-01 15:54:03 -07006496 }
6497
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006498 if ((sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) {
Jeff Browndaa37532012-05-01 15:54:03 -07006499 config.navigation = Configuration.NAVIGATION_TRACKBALL;
6500 navigationPresence |= presenceFlag;
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006501 } else if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD
Jeff Browndaa37532012-05-01 15:54:03 -07006502 && config.navigation == Configuration.NAVIGATION_NONAV) {
6503 config.navigation = Configuration.NAVIGATION_DPAD;
6504 navigationPresence |= presenceFlag;
6505 }
6506
6507 if (device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) {
6508 config.keyboard = Configuration.KEYBOARD_QWERTY;
6509 keyboardPresence |= presenceFlag;
6510 }
6511 }
6512 }
6513
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006514 // Determine whether a hard keyboard is available and enabled.
6515 boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
6516 if (hardKeyboardAvailable != mHardKeyboardAvailable) {
6517 mHardKeyboardAvailable = hardKeyboardAvailable;
6518 mHardKeyboardEnabled = hardKeyboardAvailable;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006519 mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
6520 mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
6521 }
6522 if (!mHardKeyboardEnabled) {
6523 config.keyboard = Configuration.KEYBOARD_NOKEYS;
6524 }
6525
Jeff Browndaa37532012-05-01 15:54:03 -07006526 // Let the policy update hidden states.
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006527 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
6528 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
6529 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO;
Jeff Browndaa37532012-05-01 15:54:03 -07006530 mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence);
Jeff Brown2992ea72011-01-28 22:04:14 -08006531 }
Jeff Brown597eec82011-01-31 17:12:25 -08006532
Dianne Hackbornc485a602009-03-24 22:39:49 -07006533 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006534 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006535
Jeff Brown2992ea72011-01-28 22:04:14 -08006536 public boolean isHardKeyboardAvailable() {
6537 synchronized (mWindowMap) {
6538 return mHardKeyboardAvailable;
6539 }
6540 }
6541
6542 public boolean isHardKeyboardEnabled() {
6543 synchronized (mWindowMap) {
6544 return mHardKeyboardEnabled;
6545 }
6546 }
6547
6548 public void setHardKeyboardEnabled(boolean enabled) {
6549 synchronized (mWindowMap) {
6550 if (mHardKeyboardEnabled != enabled) {
6551 mHardKeyboardEnabled = enabled;
6552 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
6553 }
6554 }
6555 }
6556
6557 public void setOnHardKeyboardStatusChangeListener(
6558 OnHardKeyboardStatusChangeListener listener) {
6559 synchronized (mWindowMap) {
6560 mHardKeyboardStatusChangeListener = listener;
6561 }
6562 }
6563
6564 void notifyHardKeyboardStatusChange() {
6565 final boolean available, enabled;
6566 final OnHardKeyboardStatusChangeListener listener;
6567 synchronized (mWindowMap) {
6568 listener = mHardKeyboardStatusChangeListener;
6569 available = mHardKeyboardAvailable;
6570 enabled = mHardKeyboardEnabled;
6571 }
6572 if (listener != null) {
6573 listener.onHardKeyboardStatusChange(available, enabled);
6574 }
6575 }
6576
Christopher Tatea53146c2010-09-07 11:57:52 -07006577 // -------------------------------------------------------------
6578 // Drag and drop
6579 // -------------------------------------------------------------
6580
6581 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006582 int flags, int width, int height, Surface outSurface) {
Christopher Tatea53146c2010-09-07 11:57:52 -07006583 if (DEBUG_DRAG) {
6584 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006585 + " flags=" + Integer.toHexString(flags) + " win=" + window
Christopher Tatea53146c2010-09-07 11:57:52 -07006586 + " asbinder=" + window.asBinder());
6587 }
6588
6589 final int callerPid = Binder.getCallingPid();
6590 final long origId = Binder.clearCallingIdentity();
6591 IBinder token = null;
6592
6593 try {
6594 synchronized (mWindowMap) {
6595 try {
Christopher Tatea53146c2010-09-07 11:57:52 -07006596 if (mDragState == null) {
Jeff Browne215f262012-09-10 16:01:14 -07006597 // TODO(multi-display): support other displays
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006598 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07006599 final Display display = displayContent.getDisplay();
Mathias Agopian3866f0d2013-02-11 22:08:48 -08006600 SurfaceControl surface = new SurfaceControl(session, "drag surface",
6601 width, height, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
Jeff Browne215f262012-09-10 16:01:14 -07006602 surface.setLayerStack(display.getLayerStack());
Dianne Hackbornac1471a2011-02-03 13:46:06 -08006603 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DRAG "
6604 + surface + ": CREATE");
Christopher Tatea53146c2010-09-07 11:57:52 -07006605 outSurface.copyFrom(surface);
Chris Tate7b362e42010-11-04 16:02:52 -07006606 final IBinder winBinder = window.asBinder();
Christopher Tatea53146c2010-09-07 11:57:52 -07006607 token = new Binder();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006608 mDragState = new DragState(this, token, surface, /*flags*/ 0, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07006609 token = mDragState.mToken = new Binder();
6610
6611 // 5 second timeout for this window to actually begin the drag
Chris Tate7b362e42010-11-04 16:02:52 -07006612 mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
6613 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07006614 mH.sendMessageDelayed(msg, 5000);
6615 } else {
6616 Slog.w(TAG, "Drag already in progress");
6617 }
Mathias Agopian3866f0d2013-02-11 22:08:48 -08006618 } catch (SurfaceControl.OutOfResourcesException e) {
Christopher Tatea53146c2010-09-07 11:57:52 -07006619 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
6620 if (mDragState != null) {
6621 mDragState.reset();
6622 mDragState = null;
6623 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006624 }
6625 }
6626 } finally {
6627 Binder.restoreCallingIdentity(origId);
6628 }
6629
6630 return token;
6631 }
6632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006633 // -------------------------------------------------------------
6634 // Input Events and Focus Management
6635 // -------------------------------------------------------------
Craig Mautner6cfa7292013-01-15 09:05:42 -08006636
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006637 final InputMonitor mInputMonitor = new InputMonitor(this);
Jeff Brown08a746a2012-06-24 12:14:49 -07006638 private boolean mEventDispatchingEnabled;
6639
Craig Mautner6cfa7292013-01-15 09:05:42 -08006640 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006641 public void pauseKeyDispatching(IBinder _token) {
6642 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6643 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006644 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006645 }
6646
6647 synchronized (mWindowMap) {
6648 WindowToken token = mTokenMap.get(_token);
6649 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006650 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006651 }
6652 }
6653 }
6654
Craig Mautner6cfa7292013-01-15 09:05:42 -08006655 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006656 public void resumeKeyDispatching(IBinder _token) {
6657 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6658 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006659 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006660 }
6661
6662 synchronized (mWindowMap) {
6663 WindowToken token = mTokenMap.get(_token);
6664 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006665 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006666 }
6667 }
6668 }
6669
Craig Mautner6cfa7292013-01-15 09:05:42 -08006670 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006671 public void setEventDispatching(boolean enabled) {
6672 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner3d7b7d52012-05-24 11:28:26 -07006673 "setEventDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006674 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006675 }
6676
6677 synchronized (mWindowMap) {
Jeff Brown08a746a2012-06-24 12:14:49 -07006678 mEventDispatchingEnabled = enabled;
6679 if (mDisplayEnabled) {
6680 mInputMonitor.setEventDispatchingLw(enabled);
6681 }
Craig Mautner3d7b7d52012-05-24 11:28:26 -07006682 sendScreenStatusToClientsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006683 }
6684 }
Romain Guy06882f82009-06-10 13:36:04 -07006685
Craig Mautner6cfa7292013-01-15 09:05:42 -08006686 @Override
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07006687 public IBinder getFocusedWindowToken() {
6688 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
6689 "getFocusedWindowToken()")) {
6690 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
6691 }
Svetoslav Ganove15ccb92012-05-16 15:48:55 -07006692 synchronized (mWindowMap) {
6693 WindowState windowState = getFocusedWindowLocked();
6694 if (windowState != null) {
6695 return windowState.mClient.asBinder();
6696 }
6697 return null;
6698 }
6699 }
6700
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006701 private WindowState getFocusedWindow() {
6702 synchronized (mWindowMap) {
6703 return getFocusedWindowLocked();
6704 }
6705 }
6706
6707 private WindowState getFocusedWindowLocked() {
6708 return mCurrentFocus;
6709 }
Romain Guy06882f82009-06-10 13:36:04 -07006710
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006711 public boolean detectSafeMode() {
Jeff Brownb09abc12011-01-13 21:08:27 -08006712 if (!mInputMonitor.waitForInputDevicesReady(
6713 INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
6714 Slog.w(TAG, "Devices still not ready after waiting "
Jeff Brownac143512012-04-05 18:57:33 -07006715 + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
6716 + " milliseconds before attempting to detect safe mode.");
Jeff Brownb09abc12011-01-13 21:08:27 -08006717 }
6718
Jeff Brownac143512012-04-05 18:57:33 -07006719 int menuState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
6720 KeyEvent.KEYCODE_MENU);
6721 int sState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, KeyEvent.KEYCODE_S);
6722 int dpadState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD,
6723 KeyEvent.KEYCODE_DPAD_CENTER);
6724 int trackballState = mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL,
Jeff Brownc458ce92012-04-30 14:58:40 -07006725 InputManagerService.BTN_MOUSE);
Jeff Brownac143512012-04-05 18:57:33 -07006726 int volumeDownState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
6727 KeyEvent.KEYCODE_VOLUME_DOWN);
6728 mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
6729 || volumeDownState > 0;
Dianne Hackborn19caadc2012-04-20 17:49:10 -07006730 try {
6731 if (SystemProperties.getInt(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, 0) != 0) {
6732 mSafeMode = true;
6733 SystemProperties.set(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, "");
6734 }
6735 } catch (IllegalArgumentException e) {
6736 }
Jeff Brownac143512012-04-05 18:57:33 -07006737 if (mSafeMode) {
6738 Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
6739 + " dpad=" + dpadState + " trackball=" + trackballState + ")");
6740 } else {
6741 Log.i(TAG, "SAFE MODE not enabled");
6742 }
6743 mPolicy.setSafeMode(mSafeMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006744 return mSafeMode;
6745 }
Romain Guy06882f82009-06-10 13:36:04 -07006746
Dianne Hackborn661cd522011-08-22 00:26:20 -07006747 public void displayReady() {
Jeff Browne215f262012-09-10 16:01:14 -07006748 displayReady(Display.DEFAULT_DISPLAY);
Craig Mautner4f67ba62012-08-02 11:23:00 -07006749
6750 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006751 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07006752 readForcedDisplaySizeAndDensityLocked(displayContent);
Dianne Hackborn5a052a42012-08-15 18:49:23 -07006753
Jeff Browne215f262012-09-10 16:01:14 -07006754 mDisplayReady = true;
Craig Mautner4f67ba62012-08-02 11:23:00 -07006755 mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
Jeff Browne215f262012-09-10 16:01:14 -07006756 PackageManager.FEATURE_TOUCHSCREEN);
Craig Mautner4f67ba62012-08-02 11:23:00 -07006757
Jeff Browne215f262012-09-10 16:01:14 -07006758 mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
6759 displayContent.mInitialDisplayWidth,
6760 displayContent.mInitialDisplayHeight,
6761 displayContent.mInitialDisplayDensity);
Craig Mautner4f67ba62012-08-02 11:23:00 -07006762 }
Dianne Hackborn5a052a42012-08-15 18:49:23 -07006763
6764 try {
6765 mActivityManager.updateConfiguration(null);
6766 } catch (RemoteException e) {
6767 }
Craig Mautner59c00972012-07-30 12:10:24 -07006768 }
6769
Craig Mautner2d5618c2012-10-18 13:55:47 -07006770 private void displayReady(int displayId) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07006771 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006772 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07006773 if (displayContent != null) {
6774 mAnimator.addDisplayLocked(displayId);
6775 synchronized(displayContent.mDisplaySizeLock) {
6776 // Bootstrap the default logical display from the display manager.
6777 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
6778 DisplayInfo newDisplayInfo = mDisplayManagerService.getDisplayInfo(displayId);
6779 if (newDisplayInfo != null) {
6780 displayInfo.copyFrom(newDisplayInfo);
6781 }
6782 displayContent.mInitialDisplayWidth = displayInfo.logicalWidth;
6783 displayContent.mInitialDisplayHeight = displayInfo.logicalHeight;
6784 displayContent.mInitialDisplayDensity = displayInfo.logicalDensityDpi;
6785 displayContent.mBaseDisplayWidth = displayContent.mInitialDisplayWidth;
6786 displayContent.mBaseDisplayHeight = displayContent.mInitialDisplayHeight;
6787 displayContent.mBaseDisplayDensity = displayContent.mInitialDisplayDensity;
Jeff Brownbd6e1502012-08-28 03:27:37 -07006788 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07006789 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07006790 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07006791 }
6792
Dianne Hackborn661cd522011-08-22 00:26:20 -07006793 public void systemReady() {
6794 mPolicy.systemReady();
6795 }
6796
Craig Mautner59c00972012-07-30 12:10:24 -07006797 // TODO(multidisplay): Call isScreenOn for each display.
Craig Mautner3d7b7d52012-05-24 11:28:26 -07006798 private void sendScreenStatusToClientsLocked() {
Craig Mautner59c00972012-07-30 12:10:24 -07006799 final boolean on = mPowerManager.isScreenOn();
Craig Mautner7c6be102013-07-16 12:30:28 -07006800 final int numDisplays = mDisplayContents.size();
6801 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
6802 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
6803 final int numWindows = windows.size();
6804 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
6805 try {
6806 windows.get(winNdx).mClient.dispatchScreenState(on);
6807 } catch (RemoteException e) {
6808 // Ignored
6809 }
Romain Guy7e4e5612012-03-05 14:37:29 -08006810 }
6811 }
6812 }
6813
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006814 // -------------------------------------------------------------
6815 // Async Handler
6816 // -------------------------------------------------------------
6817
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006818 final class H extends Handler {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006819 public static final int REPORT_FOCUS_CHANGE = 2;
6820 public static final int REPORT_LOSING_FOCUS = 3;
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08006821 public static final int DO_TRAVERSAL = 4;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006822 public static final int ADD_STARTING = 5;
6823 public static final int REMOVE_STARTING = 6;
6824 public static final int FINISHED_STARTING = 7;
6825 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07006826 public static final int REPORT_APPLICATION_TOKEN_DRAWN = 9;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006827 public static final int WINDOW_FREEZE_TIMEOUT = 11;
Craig Mautner259328c2012-08-21 19:30:58 -07006828
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006829 public static final int APP_TRANSITION_TIMEOUT = 13;
6830 public static final int PERSIST_ANIMATION_SCALE = 14;
6831 public static final int FORCE_GC = 15;
6832 public static final int ENABLE_SCREEN = 16;
6833 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006834 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07006835 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07006836 public static final int DRAG_START_TIMEOUT = 20;
Chris Tated4533f12010-10-19 15:15:08 -07006837 public static final int DRAG_END_TIMEOUT = 21;
Jeff Brown2992ea72011-01-28 22:04:14 -08006838 public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006839 public static final int BOOT_TIMEOUT = 23;
Dianne Hackborn38e29a62011-09-18 14:43:08 -07006840 public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
Craig Mautner96868332012-12-04 14:29:11 -08006841 public static final int SHOW_STRICT_MODE_VIOLATION = 25;
6842 public static final int DO_ANIMATION_CALLBACK = 26;
Romain Guy06882f82009-06-10 13:36:04 -07006843
Craig Mautner96868332012-12-04 14:29:11 -08006844 public static final int DO_DISPLAY_ADDED = 27;
6845 public static final int DO_DISPLAY_REMOVED = 28;
6846 public static final int DO_DISPLAY_CHANGED = 29;
Craig Mautner722285e2012-09-07 13:55:58 -07006847
Craig Mautner96868332012-12-04 14:29:11 -08006848 public static final int CLIENT_FREEZE_TIMEOUT = 30;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07006849
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006850 @Override
6851 public void handleMessage(Message msg) {
Craig Mautner7d8df392012-04-06 15:26:23 -07006852 if (DEBUG_WINDOW_TRACE) {
6853 Slog.v(TAG, "handleMessage: entry what=" + msg.what);
6854 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006855 switch (msg.what) {
6856 case REPORT_FOCUS_CHANGE: {
6857 WindowState lastFocus;
6858 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07006859
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006860 synchronized(mWindowMap) {
6861 lastFocus = mLastFocus;
6862 newFocus = mCurrentFocus;
6863 if (lastFocus == newFocus) {
6864 // Focus is not changing, so nothing to do.
6865 return;
6866 }
6867 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006868 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006869 // + " to " + newFocus);
6870 if (newFocus != null && lastFocus != null
6871 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006872 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006873 mLosingFocus.add(lastFocus);
6874 lastFocus = null;
6875 }
6876 }
6877
6878 if (lastFocus != newFocus) {
6879 //System.out.println("Changing focus from " + lastFocus
6880 // + " to " + newFocus);
6881 if (newFocus != null) {
Dianne Hackborne3f23a32013-03-01 13:25:35 -08006882 //Slog.i(TAG, "Gaining focus: " + newFocus);
6883 newFocus.reportFocusChangedSerialized(true, mInTouchMode);
Konstantin Lopyrev5e7833a2010-08-09 17:01:11 -07006884 notifyFocusChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006885 }
6886
6887 if (lastFocus != null) {
Dianne Hackborne3f23a32013-03-01 13:25:35 -08006888 //Slog.i(TAG, "Losing focus: " + lastFocus);
6889 lastFocus.reportFocusChangedSerialized(false, mInTouchMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006890 }
6891 }
6892 } break;
6893
6894 case REPORT_LOSING_FOCUS: {
6895 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07006896
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006897 synchronized(mWindowMap) {
6898 losers = mLosingFocus;
6899 mLosingFocus = new ArrayList<WindowState>();
6900 }
6901
6902 final int N = losers.size();
6903 for (int i=0; i<N; i++) {
Dianne Hackborne3f23a32013-03-01 13:25:35 -08006904 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
6905 losers.get(i).reportFocusChangedSerialized(false, mInTouchMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006906 }
6907 } break;
6908
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08006909 case DO_TRAVERSAL: {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006910 synchronized(mWindowMap) {
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08006911 mTraversalScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006912 performLayoutAndPlaceSurfacesLocked();
6913 }
6914 } break;
6915
6916 case ADD_STARTING: {
6917 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
6918 final StartingData sd = wtoken.startingData;
6919
6920 if (sd == null) {
6921 // Animation has been canceled... do nothing.
6922 return;
6923 }
Romain Guy06882f82009-06-10 13:36:04 -07006924
Joe Onorato8a9b2202010-02-26 18:56:32 -08006925 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006926 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07006927
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006928 View view = null;
6929 try {
6930 view = mPolicy.addStartingWindow(
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07006931 wtoken.token, sd.pkg, sd.theme, sd.compatInfo,
6932 sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006933 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006934 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006935 }
6936
6937 if (view != null) {
6938 boolean abort = false;
6939
6940 synchronized(mWindowMap) {
6941 if (wtoken.removed || wtoken.startingData == null) {
6942 // If the window was successfully added, then
6943 // we need to remove it.
6944 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006945 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006946 "Aborted starting " + wtoken
6947 + ": removed=" + wtoken.removed
6948 + " startingData=" + wtoken.startingData);
6949 wtoken.startingWindow = null;
6950 wtoken.startingData = null;
6951 abort = true;
6952 }
6953 } else {
6954 wtoken.startingView = view;
6955 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006956 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006957 "Added starting " + wtoken
6958 + ": startingWindow="
6959 + wtoken.startingWindow + " startingView="
6960 + wtoken.startingView);
6961 }
6962
6963 if (abort) {
6964 try {
6965 mPolicy.removeStartingWindow(wtoken.token, view);
6966 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006967 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006968 }
6969 }
6970 }
6971 } break;
6972
6973 case REMOVE_STARTING: {
6974 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
6975 IBinder token = null;
6976 View view = null;
6977 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006978 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006979 + wtoken + ": startingWindow="
6980 + wtoken.startingWindow + " startingView="
6981 + wtoken.startingView);
6982 if (wtoken.startingWindow != null) {
6983 view = wtoken.startingView;
6984 token = wtoken.token;
6985 wtoken.startingData = null;
6986 wtoken.startingView = null;
6987 wtoken.startingWindow = null;
Craig Mautner38b24782012-07-02 16:21:28 -07006988 wtoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006989 }
6990 }
6991 if (view != null) {
6992 try {
6993 mPolicy.removeStartingWindow(token, view);
6994 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006995 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006996 }
6997 }
6998 } break;
6999
7000 case FINISHED_STARTING: {
7001 IBinder token = null;
7002 View view = null;
7003 while (true) {
7004 synchronized (mWindowMap) {
7005 final int N = mFinishedStarting.size();
7006 if (N <= 0) {
7007 break;
7008 }
7009 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
7010
Joe Onorato8a9b2202010-02-26 18:56:32 -08007011 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007012 "Finished starting " + wtoken
7013 + ": startingWindow=" + wtoken.startingWindow
7014 + " startingView=" + wtoken.startingView);
7015
7016 if (wtoken.startingWindow == null) {
7017 continue;
7018 }
7019
7020 view = wtoken.startingView;
7021 token = wtoken.token;
7022 wtoken.startingData = null;
7023 wtoken.startingView = null;
7024 wtoken.startingWindow = null;
Craig Mautner38b24782012-07-02 16:21:28 -07007025 wtoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007026 }
7027
7028 try {
7029 mPolicy.removeStartingWindow(token, view);
7030 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007031 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007032 }
7033 }
7034 } break;
7035
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07007036 case REPORT_APPLICATION_TOKEN_DRAWN: {
7037 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7038
7039 try {
7040 if (DEBUG_VISIBILITY) Slog.v(
7041 TAG, "Reporting drawn in " + wtoken);
7042 wtoken.appToken.windowsDrawn();
7043 } catch (RemoteException ex) {
7044 }
7045 } break;
7046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007047 case REPORT_APPLICATION_TOKEN_WINDOWS: {
7048 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7049
7050 boolean nowVisible = msg.arg1 != 0;
7051 boolean nowGone = msg.arg2 != 0;
7052
7053 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007054 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007055 TAG, "Reporting visible in " + wtoken
7056 + " visible=" + nowVisible
7057 + " gone=" + nowGone);
7058 if (nowVisible) {
7059 wtoken.appToken.windowsVisible();
7060 } else {
7061 wtoken.appToken.windowsGone();
7062 }
7063 } catch (RemoteException ex) {
7064 }
7065 } break;
Romain Guy06882f82009-06-10 13:36:04 -07007066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007067 case WINDOW_FREEZE_TIMEOUT: {
Craig Mautner59c00972012-07-30 12:10:24 -07007068 // TODO(multidisplay): Can non-default displays rotate?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007069 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007070 Slog.w(TAG, "Window freeze timeout expired.");
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007071 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07007072 int i = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007073 while (i > 0) {
7074 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07007075 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007076 if (w.mOrientationChanging) {
7077 w.mOrientationChanging = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07007078 w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
7079 - mDisplayFreezeTime);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007080 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007081 }
7082 }
7083 performLayoutAndPlaceSurfacesLocked();
7084 }
7085 break;
7086 }
Romain Guy06882f82009-06-10 13:36:04 -07007087
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007088 case APP_TRANSITION_TIMEOUT: {
7089 synchronized (mWindowMap) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08007090 if (mAppTransition.isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08007091 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** APP TRANSITION TIMEOUT");
7092 mAppTransition.setTimeout();
Craig Mautner2ad92072013-02-25 16:19:24 -08007093 mAnimatingAppTokens.clear();
7094 mAnimatingAppTokens.addAll(mAppTokens);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007095 performLayoutAndPlaceSurfacesLocked();
7096 }
7097 }
7098 break;
7099 }
Romain Guy06882f82009-06-10 13:36:04 -07007100
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007101 case PERSIST_ANIMATION_SCALE: {
Jeff Sharkey6e2bee72012-10-01 13:39:08 -07007102 Settings.Global.putFloat(mContext.getContentResolver(),
7103 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
7104 Settings.Global.putFloat(mContext.getContentResolver(),
7105 Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
7106 Settings.Global.putFloat(mContext.getContentResolver(),
7107 Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007108 break;
7109 }
Romain Guy06882f82009-06-10 13:36:04 -07007110
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007111 case FORCE_GC: {
Craig Mautner1caa3992012-06-22 09:46:48 -07007112 synchronized (mWindowMap) {
Craig Mautner96868332012-12-04 14:29:11 -08007113 // Since we're holding both mWindowMap and mAnimator we don't need to
7114 // hold mAnimator.mLayoutToAnim.
7115 if (mAnimator.mAnimating || mAnimationScheduled) {
7116 // If we are animating, don't do the gc now but
7117 // delay a bit so we don't interrupt the animation.
7118 sendEmptyMessageDelayed(H.FORCE_GC, 2000);
7119 return;
7120 }
7121 // If we are currently rotating the display, it will
7122 // schedule a new message when done.
7123 if (mDisplayFrozen) {
7124 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007125 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007126 }
7127 Runtime.getRuntime().gc();
7128 break;
7129 }
Romain Guy06882f82009-06-10 13:36:04 -07007130
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007131 case ENABLE_SCREEN: {
7132 performEnableScreen();
7133 break;
7134 }
Romain Guy06882f82009-06-10 13:36:04 -07007135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007136 case APP_FREEZE_TIMEOUT: {
7137 synchronized (mWindowMap) {
Craig Mautner96868332012-12-04 14:29:11 -08007138 Slog.w(TAG, "App freeze timeout expired.");
Craig Mautner2ad92072013-02-25 16:19:24 -08007139 int i = mAppTokens.size();
7140 while (i > 0) {
7141 i--;
7142 AppWindowToken tok = mAppTokens.get(i);
Craig Mautner96868332012-12-04 14:29:11 -08007143 if (tok.mAppAnimator.freezingScreen) {
7144 Slog.w(TAG, "Force clearing freeze: " + tok);
7145 unsetAppFreezingScreenLocked(tok, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007146 }
7147 }
7148 }
7149 break;
7150 }
Romain Guy06882f82009-06-10 13:36:04 -07007151
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007152 case CLIENT_FREEZE_TIMEOUT: {
7153 synchronized (mWindowMap) {
7154 if (mClientFreezingScreen) {
7155 mClientFreezingScreen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07007156 mLastFinishedFreezeSource = "client-timeout";
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007157 stopFreezingDisplayLocked();
7158 }
7159 }
7160 break;
7161 }
7162
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007163 case SEND_NEW_CONFIGURATION: {
7164 removeMessages(SEND_NEW_CONFIGURATION);
7165 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07007166 break;
7167 }
Romain Guy06882f82009-06-10 13:36:04 -07007168
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07007169 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007170 if (mWindowsChanged) {
7171 synchronized (mWindowMap) {
7172 mWindowsChanged = false;
7173 }
7174 notifyWindowsChanged();
7175 }
7176 break;
7177 }
7178
Christopher Tatea53146c2010-09-07 11:57:52 -07007179 case DRAG_START_TIMEOUT: {
7180 IBinder win = (IBinder)msg.obj;
7181 if (DEBUG_DRAG) {
7182 Slog.w(TAG, "Timeout starting drag by win " + win);
7183 }
7184 synchronized (mWindowMap) {
7185 // !!! TODO: ANR the app that has failed to start the drag in time
7186 if (mDragState != null) {
Chris Tated4533f12010-10-19 15:15:08 -07007187 mDragState.unregister();
Jeff Brown2e44b072011-01-24 15:21:56 -08007188 mInputMonitor.updateInputWindowsLw(true /*force*/);
Christopher Tatea53146c2010-09-07 11:57:52 -07007189 mDragState.reset();
7190 mDragState = null;
7191 }
7192 }
Chris Tated4533f12010-10-19 15:15:08 -07007193 break;
Christopher Tatea53146c2010-09-07 11:57:52 -07007194 }
7195
Chris Tated4533f12010-10-19 15:15:08 -07007196 case DRAG_END_TIMEOUT: {
7197 IBinder win = (IBinder)msg.obj;
7198 if (DEBUG_DRAG) {
7199 Slog.w(TAG, "Timeout ending drag to win " + win);
7200 }
7201 synchronized (mWindowMap) {
7202 // !!! TODO: ANR the drag-receiving app
Christopher Tated9be36c2011-08-16 16:09:33 -07007203 if (mDragState != null) {
7204 mDragState.mDragResult = false;
7205 mDragState.endDragLw();
7206 }
Chris Tated4533f12010-10-19 15:15:08 -07007207 }
7208 break;
7209 }
Jeff Brown2992ea72011-01-28 22:04:14 -08007210
7211 case REPORT_HARD_KEYBOARD_STATUS_CHANGE: {
7212 notifyHardKeyboardStatusChange();
7213 break;
7214 }
Dianne Hackborn38e29a62011-09-18 14:43:08 -07007215
7216 case BOOT_TIMEOUT: {
7217 performBootTimeout();
7218 break;
7219 }
7220
7221 case WAITING_FOR_DRAWN_TIMEOUT: {
7222 Pair<WindowState, IRemoteCallback> pair;
7223 synchronized (mWindowMap) {
7224 pair = (Pair<WindowState, IRemoteCallback>)msg.obj;
7225 Slog.w(TAG, "Timeout waiting for drawn: " + pair.first);
7226 if (!mWaitingForDrawn.remove(pair)) {
7227 return;
7228 }
7229 }
7230 try {
7231 pair.second.sendResult(null);
7232 } catch (RemoteException e) {
7233 }
7234 break;
7235 }
Craig Mautnera608b882012-03-30 13:03:49 -07007236
Craig Mautner0447a812012-05-22 16:01:31 -07007237 case SHOW_STRICT_MODE_VIOLATION: {
Chris Craik3198ef32012-10-10 14:52:30 -07007238 showStrictModeViolation(msg.arg1, msg.arg2);
Craig Mautner0447a812012-05-22 16:01:31 -07007239 break;
7240 }
7241
Dianne Hackborn84375872012-06-01 19:03:50 -07007242 case DO_ANIMATION_CALLBACK: {
7243 try {
7244 ((IRemoteCallback)msg.obj).sendResult(null);
7245 } catch (RemoteException e) {
7246 }
7247 break;
7248 }
Craig Mautner722285e2012-09-07 13:55:58 -07007249
Craig Mautner722285e2012-09-07 13:55:58 -07007250 case DO_DISPLAY_ADDED:
7251 synchronized (mWindowMap) {
7252 handleDisplayAddedLocked(msg.arg1);
7253 }
7254 break;
7255
7256 case DO_DISPLAY_REMOVED:
7257 synchronized (mWindowMap) {
7258 handleDisplayRemovedLocked(msg.arg1);
7259 }
7260 break;
7261
7262 case DO_DISPLAY_CHANGED:
7263 synchronized (mWindowMap) {
7264 handleDisplayChangedLocked(msg.arg1);
7265 }
7266 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007267 }
Craig Mautner7d8df392012-04-06 15:26:23 -07007268 if (DEBUG_WINDOW_TRACE) {
7269 Slog.v(TAG, "handleMessage: exit");
7270 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007271 }
7272 }
7273
7274 // -------------------------------------------------------------
7275 // IWindowManager API
7276 // -------------------------------------------------------------
7277
Craig Mautner7d8df392012-04-06 15:26:23 -07007278 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007279 public IWindowSession openSession(IInputMethodClient client,
7280 IInputContext inputContext) {
7281 if (client == null) throw new IllegalArgumentException("null client");
7282 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08007283 Session session = new Session(this, client, inputContext);
Jeff Brown46b9ac02010-04-22 18:58:52 -07007284 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007285 }
7286
Craig Mautner7d8df392012-04-06 15:26:23 -07007287 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007288 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
7289 synchronized (mWindowMap) {
7290 // The focus for the client is the window immediately below
7291 // where we would place the input method window.
7292 int idx = findDesiredInputMethodWindowIndexLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007293 if (idx > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07007294 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007295 WindowState imFocus = getDefaultWindowListLocked().get(idx-1);
Dianne Hackbornac920872012-05-22 11:49:49 -07007296 if (DEBUG_INPUT_METHOD) {
7297 Slog.i(TAG, "Desired input method target: " + imFocus);
Craig Mautner59c00972012-07-30 12:10:24 -07007298 Slog.i(TAG, "Current focus: " + mCurrentFocus);
7299 Slog.i(TAG, "Last focus: " + mLastFocus);
Dianne Hackbornac920872012-05-22 11:49:49 -07007300 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007301 if (imFocus != null) {
Dianne Hackborne75d8722011-01-27 19:37:40 -08007302 // This may be a starting window, in which case we still want
7303 // to count it as okay.
7304 if (imFocus.mAttrs.type == LayoutParams.TYPE_APPLICATION_STARTING
7305 && imFocus.mAppToken != null) {
7306 // The client has definitely started, so it really should
7307 // have a window in this app token. Let's look for it.
7308 for (int i=0; i<imFocus.mAppToken.windows.size(); i++) {
7309 WindowState w = imFocus.mAppToken.windows.get(i);
7310 if (w != imFocus) {
Dianne Hackbornac920872012-05-22 11:49:49 -07007311 Log.i(TAG, "Switching to real app window: " + w);
Dianne Hackborne75d8722011-01-27 19:37:40 -08007312 imFocus = w;
7313 break;
7314 }
7315 }
7316 }
Dianne Hackbornac920872012-05-22 11:49:49 -07007317 if (DEBUG_INPUT_METHOD) {
7318 Slog.i(TAG, "IM target client: " + imFocus.mSession.mClient);
7319 if (imFocus.mSession.mClient != null) {
7320 Slog.i(TAG, "IM target client binder: "
7321 + imFocus.mSession.mClient.asBinder());
7322 Slog.i(TAG, "Requesting client binder: " + client.asBinder());
7323 }
7324 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007325 if (imFocus.mSession.mClient != null &&
7326 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
7327 return true;
7328 }
7329 }
7330 }
Craig Mautner59c00972012-07-30 12:10:24 -07007331
7332 // Okay, how about this... what is the current focus?
7333 // It seems in some cases we may not have moved the IM
7334 // target window, such as when it was in a pop-up window,
7335 // so let's also look at the current focus. (An example:
7336 // go to Gmail, start searching so the keyboard goes up,
7337 // press home. Sometimes the IME won't go down.)
7338 // Would be nice to fix this more correctly, but it's
7339 // way at the end of a release, and this should be good enough.
7340 if (mCurrentFocus != null && mCurrentFocus.mSession.mClient != null
7341 && mCurrentFocus.mSession.mClient.asBinder() == client.asBinder()) {
7342 return true;
7343 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007344 }
7345 return false;
7346 }
Romain Guy06882f82009-06-10 13:36:04 -07007347
Dianne Hackborn672cf452013-03-26 15:24:24 -07007348 @Override
Craig Mautner59c00972012-07-30 12:10:24 -07007349 public void getInitialDisplaySize(int displayId, Point size) {
Craig Mautner58106812012-12-28 12:27:40 -08007350 synchronized (mWindowMap) {
7351 final DisplayContent displayContent = getDisplayContentLocked(displayId);
7352 if (displayContent != null) {
7353 synchronized(displayContent.mDisplaySizeLock) {
7354 size.x = displayContent.mInitialDisplayWidth;
7355 size.y = displayContent.mInitialDisplayHeight;
7356 }
Craig Mautner2d5618c2012-10-18 13:55:47 -07007357 }
Dianne Hackborn7d608422011-08-07 16:24:18 -07007358 }
7359 }
7360
Craig Mautner2d5618c2012-10-18 13:55:47 -07007361 @Override
Dianne Hackborn672cf452013-03-26 15:24:24 -07007362 public void getBaseDisplaySize(int displayId, Point size) {
7363 synchronized (mWindowMap) {
7364 final DisplayContent displayContent = getDisplayContentLocked(displayId);
7365 if (displayContent != null) {
7366 synchronized(displayContent.mDisplaySizeLock) {
7367 size.x = displayContent.mBaseDisplayWidth;
7368 size.y = displayContent.mBaseDisplayHeight;
7369 }
7370 }
7371 }
7372 }
7373
7374 @Override
Jeff Brown43aa1592012-09-10 17:36:31 -07007375 public void setForcedDisplaySize(int displayId, int width, int height) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08007376 if (mContext.checkCallingOrSelfPermission(
7377 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7378 PackageManager.PERMISSION_GRANTED) {
7379 throw new SecurityException("Must hold permission " +
7380 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7381 }
7382 if (displayId != Display.DEFAULT_DISPLAY) {
7383 throw new IllegalArgumentException("Can only set the default display");
7384 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007385 synchronized(mWindowMap) {
Jeff Brown43aa1592012-09-10 17:36:31 -07007386 // Set some sort of reasonable bounds on the size of the display that we
7387 // will try to emulate.
7388 final int MIN_WIDTH = 200;
7389 final int MIN_HEIGHT = 200;
7390 final int MAX_SCALE = 2;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007391 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007392 if (displayContent != null) {
7393 width = Math.min(Math.max(width, MIN_WIDTH),
7394 displayContent.mInitialDisplayWidth * MAX_SCALE);
7395 height = Math.min(Math.max(height, MIN_HEIGHT),
7396 displayContent.mInitialDisplayHeight * MAX_SCALE);
7397 setForcedDisplaySizeLocked(displayContent, width, height);
7398 Settings.Global.putString(mContext.getContentResolver(),
7399 Settings.Global.DISPLAY_SIZE_FORCED, width + "," + height);
7400 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007401 }
7402 }
7403
Dianne Hackborndde331c2012-08-03 14:01:57 -07007404 private void readForcedDisplaySizeAndDensityLocked(final DisplayContent displayContent) {
Jeff Brown43aa1592012-09-10 17:36:31 -07007405 final String sizeStr = Settings.Global.getString(mContext.getContentResolver(),
7406 Settings.Global.DISPLAY_SIZE_FORCED);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007407 if (sizeStr != null && sizeStr.length() > 0) {
7408 final int pos = sizeStr.indexOf(',');
7409 if (pos > 0 && sizeStr.lastIndexOf(',') == pos) {
7410 int width, height;
7411 try {
7412 width = Integer.parseInt(sizeStr.substring(0, pos));
7413 height = Integer.parseInt(sizeStr.substring(pos+1));
7414 synchronized(displayContent.mDisplaySizeLock) {
7415 if (displayContent.mBaseDisplayWidth != width
7416 || displayContent.mBaseDisplayHeight != height) {
Dianne Hackborndde331c2012-08-03 14:01:57 -07007417 Slog.i(TAG, "FORCED DISPLAY SIZE: " + width + "x" + height);
7418 displayContent.mBaseDisplayWidth = width;
7419 displayContent.mBaseDisplayHeight = height;
7420 }
7421 }
7422 } catch (NumberFormatException ex) {
7423 }
7424 }
Joe Onorato571ae902011-05-24 13:48:43 -07007425 }
Jeff Brown43aa1592012-09-10 17:36:31 -07007426 final String densityStr = Settings.Global.getString(mContext.getContentResolver(),
7427 Settings.Global.DISPLAY_DENSITY_FORCED);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007428 if (densityStr != null && densityStr.length() > 0) {
7429 int density;
7430 try {
7431 density = Integer.parseInt(densityStr);
7432 synchronized(displayContent.mDisplaySizeLock) {
7433 if (displayContent.mBaseDisplayDensity != density) {
Dianne Hackborndde331c2012-08-03 14:01:57 -07007434 Slog.i(TAG, "FORCED DISPLAY DENSITY: " + density);
7435 displayContent.mBaseDisplayDensity = density;
7436 }
7437 }
7438 } catch (NumberFormatException ex) {
7439 }
Joe Onorato571ae902011-05-24 13:48:43 -07007440 }
Joe Onorato571ae902011-05-24 13:48:43 -07007441 }
7442
Craig Mautner2d5618c2012-10-18 13:55:47 -07007443 // displayContent must not be null
Craig Mautner59c00972012-07-30 12:10:24 -07007444 private void setForcedDisplaySizeLocked(DisplayContent displayContent, int width, int height) {
Joe Onorato571ae902011-05-24 13:48:43 -07007445 Slog.i(TAG, "Using new display size: " + width + "x" + height);
7446
Craig Mautner59c00972012-07-30 12:10:24 -07007447 synchronized(displayContent.mDisplaySizeLock) {
7448 displayContent.mBaseDisplayWidth = width;
7449 displayContent.mBaseDisplayHeight = height;
Dianne Hackborn1fbee792011-11-30 11:29:58 -08007450 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007451 reconfigureDisplayLocked(displayContent);
7452 }
7453
Craig Mautner2d5618c2012-10-18 13:55:47 -07007454 @Override
Dianne Hackborndde331c2012-08-03 14:01:57 -07007455 public void clearForcedDisplaySize(int displayId) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08007456 if (mContext.checkCallingOrSelfPermission(
7457 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7458 PackageManager.PERMISSION_GRANTED) {
7459 throw new SecurityException("Must hold permission " +
7460 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7461 }
7462 if (displayId != Display.DEFAULT_DISPLAY) {
7463 throw new IllegalArgumentException("Can only set the default display");
7464 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007465 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007466 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007467 if (displayContent != null) {
7468 setForcedDisplaySizeLocked(displayContent, displayContent.mInitialDisplayWidth,
7469 displayContent.mInitialDisplayHeight);
7470 Settings.Global.putString(mContext.getContentResolver(),
7471 Settings.Global.DISPLAY_SIZE_FORCED, "");
7472 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007473 }
7474 }
7475
Craig Mautner2d5618c2012-10-18 13:55:47 -07007476 @Override
Dianne Hackborn672cf452013-03-26 15:24:24 -07007477 public int getInitialDisplayDensity(int displayId) {
7478 synchronized (mWindowMap) {
7479 final DisplayContent displayContent = getDisplayContentLocked(displayId);
7480 if (displayContent != null) {
7481 synchronized(displayContent.mDisplaySizeLock) {
7482 return displayContent.mInitialDisplayDensity;
7483 }
7484 }
7485 }
7486 return -1;
7487 }
7488
7489 @Override
7490 public int getBaseDisplayDensity(int displayId) {
7491 synchronized (mWindowMap) {
7492 final DisplayContent displayContent = getDisplayContentLocked(displayId);
7493 if (displayContent != null) {
7494 synchronized(displayContent.mDisplaySizeLock) {
7495 return displayContent.mBaseDisplayDensity;
7496 }
7497 }
7498 }
7499 return -1;
7500 }
7501
7502 @Override
Dianne Hackborndde331c2012-08-03 14:01:57 -07007503 public void setForcedDisplayDensity(int displayId, int density) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08007504 if (mContext.checkCallingOrSelfPermission(
7505 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7506 PackageManager.PERMISSION_GRANTED) {
7507 throw new SecurityException("Must hold permission " +
7508 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7509 }
7510 if (displayId != Display.DEFAULT_DISPLAY) {
7511 throw new IllegalArgumentException("Can only set the default display");
7512 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007513 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007514 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007515 if (displayContent != null) {
7516 setForcedDisplayDensityLocked(displayContent, density);
7517 Settings.Global.putString(mContext.getContentResolver(),
7518 Settings.Global.DISPLAY_DENSITY_FORCED, Integer.toString(density));
7519 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007520 }
7521 }
7522
Craig Mautner2d5618c2012-10-18 13:55:47 -07007523 // displayContent must not be null
Dianne Hackborndde331c2012-08-03 14:01:57 -07007524 private void setForcedDisplayDensityLocked(DisplayContent displayContent, int density) {
7525 Slog.i(TAG, "Using new display density: " + density);
7526
7527 synchronized(displayContent.mDisplaySizeLock) {
7528 displayContent.mBaseDisplayDensity = density;
7529 }
7530 reconfigureDisplayLocked(displayContent);
7531 }
7532
Craig Mautner2d5618c2012-10-18 13:55:47 -07007533 @Override
Dianne Hackborndde331c2012-08-03 14:01:57 -07007534 public void clearForcedDisplayDensity(int displayId) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08007535 if (mContext.checkCallingOrSelfPermission(
7536 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7537 PackageManager.PERMISSION_GRANTED) {
7538 throw new SecurityException("Must hold permission " +
7539 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7540 }
7541 if (displayId != Display.DEFAULT_DISPLAY) {
7542 throw new IllegalArgumentException("Can only set the default display");
7543 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007544 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007545 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007546 if (displayContent != null) {
7547 setForcedDisplayDensityLocked(displayContent, displayContent.mInitialDisplayDensity);
7548 Settings.Global.putString(mContext.getContentResolver(),
7549 Settings.Global.DISPLAY_DENSITY_FORCED, "");
7550 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007551 }
7552 }
7553
Craig Mautner2d5618c2012-10-18 13:55:47 -07007554 // displayContent must not be null
Dianne Hackborndde331c2012-08-03 14:01:57 -07007555 private void reconfigureDisplayLocked(DisplayContent displayContent) {
Craig Mautner69b08182012-09-05 13:07:13 -07007556 // TODO: Multidisplay: for now only use with default display.
Jeff Browne215f262012-09-10 16:01:14 -07007557 mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
7558 displayContent.mBaseDisplayWidth,
7559 displayContent.mBaseDisplayHeight,
7560 displayContent.mBaseDisplayDensity);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007561
Craig Mautner19d59bc2012-09-04 11:15:56 -07007562 displayContent.layoutNeeded = true;
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007563
7564 boolean configChanged = updateOrientationFromAppTokensLocked(false);
7565 mTempConfiguration.setToDefaults();
7566 mTempConfiguration.fontScale = mCurConfiguration.fontScale;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08007567 if (computeScreenConfigurationLocked(mTempConfiguration)) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007568 if (mCurConfiguration.diff(mTempConfiguration) != 0) {
7569 configChanged = true;
7570 }
7571 }
7572
7573 if (configChanged) {
7574 mWaitingForConfig = true;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007575 startFreezingDisplayLocked(false, 0, 0);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007576 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
7577 }
7578
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007579 performLayoutAndPlaceSurfacesLocked();
7580 }
7581
Craig Mautner24d887472013-03-20 15:40:36 -07007582 @Override
Dianne Hackbornc652de82013-02-15 16:32:56 -08007583 public void setOverscan(int displayId, int left, int top, int right, int bottom) {
7584 if (mContext.checkCallingOrSelfPermission(
7585 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7586 PackageManager.PERMISSION_GRANTED) {
7587 throw new SecurityException("Must hold permission " +
7588 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7589 }
7590 synchronized(mWindowMap) {
7591 DisplayContent displayContent = getDisplayContentLocked(displayId);
7592 if (displayContent != null) {
7593 mDisplayManagerService.setOverscan(displayId, left, top, right, bottom);
7594 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
7595 synchronized(displayContent.mDisplaySizeLock) {
7596 displayInfo.overscanLeft = left;
7597 displayInfo.overscanTop = top;
7598 displayInfo.overscanRight = right;
7599 displayInfo.overscanBottom = bottom;
7600 }
7601 mPolicy.setDisplayOverscan(displayContent.getDisplay(), left, top, right, bottom);
7602 displayContent.layoutNeeded = true;
7603 mDisplaySettings.setOverscanLocked(displayInfo.name, left, top, right, bottom);
7604 mDisplaySettings.writeSettingsLocked();
7605 performLayoutAndPlaceSurfacesLocked();
7606 }
7607 }
7608 }
7609
Craig Mautner6cfa7292013-01-15 09:05:42 -08007610 @Override
Dianne Hackbornf87d1962012-04-04 12:48:24 -07007611 public boolean hasSystemNavBar() {
7612 return mPolicy.hasSystemNavBar();
Dianne Hackborn81e56d52011-05-26 00:55:58 -07007613 }
7614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007615 // -------------------------------------------------------------
7616 // Internals
7617 // -------------------------------------------------------------
7618
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007619 final WindowState windowForClientLocked(Session session, IWindow client,
7620 boolean throwOnError) {
7621 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007622 }
Romain Guy06882f82009-06-10 13:36:04 -07007623
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007624 final WindowState windowForClientLocked(Session session, IBinder client,
7625 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007626 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007627 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007628 TAG, "Looking up client " + client + ": " + win);
7629 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007630 RuntimeException ex = new IllegalArgumentException(
7631 "Requested window " + client + " does not exist");
7632 if (throwOnError) {
7633 throw ex;
7634 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007635 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007636 return null;
7637 }
7638 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007639 RuntimeException ex = new IllegalArgumentException(
7640 "Requested window " + client + " is in session " +
7641 win.mSession + ", not " + session);
7642 if (throwOnError) {
7643 throw ex;
7644 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007645 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007646 return null;
7647 }
7648
7649 return win;
7650 }
7651
Dianne Hackborna8f60182009-09-01 19:01:50 -07007652 final void rebuildAppWindowListLocked() {
Craig Mautner7c6be102013-07-16 12:30:28 -07007653 final int numDisplays = mDisplayContents.size();
7654 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
7655 rebuildAppWindowListLocked(mDisplayContents.valueAt(displayNdx));
Craig Mautner59c00972012-07-30 12:10:24 -07007656 }
7657 }
7658
7659 private void rebuildAppWindowListLocked(final DisplayContent displayContent) {
7660 final WindowList windows = displayContent.getWindowList();
7661 int NW = windows.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07007662 int i;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007663 int lastBelow = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007664 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007665
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007666 if (mRebuildTmp.length < NW) {
7667 mRebuildTmp = new WindowState[NW+10];
7668 }
7669
Dianne Hackborna8f60182009-09-01 19:01:50 -07007670 // First remove all existing app windows.
7671 i=0;
7672 while (i < NW) {
Craig Mautner59c00972012-07-30 12:10:24 -07007673 WindowState w = windows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007674 if (w.mAppToken != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07007675 WindowState win = windows.remove(i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007676 win.mRebuilding = true;
7677 mRebuildTmp[numRemoved] = win;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007678 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007679 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007680 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07007681 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007682 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07007683 continue;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007684 } else if (lastBelow == i-1) {
Craig Mautner65d11b32012-10-01 13:59:52 -07007685 if (w.mAttrs.type == TYPE_WALLPAPER || w.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007686 lastBelow = i;
7687 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07007688 }
7689 i++;
7690 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007691
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007692 // Keep whatever windows were below the app windows still below,
7693 // by skipping them.
7694 lastBelow++;
7695 i = lastBelow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007696
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007697 // First add all of the exiting app tokens... these are no longer
7698 // in the main app list, but still have windows shown. We put them
7699 // in the back because now that the animation is over we no longer
7700 // will care about them.
Craig Mautner2ad92072013-02-25 16:19:24 -08007701 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07007702 for (int j=0; j<NT; j++) {
Craig Mautner2ad92072013-02-25 16:19:24 -08007703 i = reAddAppWindowsLocked(displayContent, i, mExitingAppTokens.get(j));
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007704 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007705
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007706 // And add in the still active app tokens in Z order.
Craig Mautner2ad92072013-02-25 16:19:24 -08007707 NT = mAnimatingAppTokens.size();
7708 for (int j=0; j<NT; j++) {
7709 i = reAddAppWindowsLocked(displayContent, i, mAnimatingAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07007710 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007711
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007712 i -= lastBelow;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007713 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007714 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007715 + " windows but added " + i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007716 for (i=0; i<numRemoved; i++) {
7717 WindowState ws = mRebuildTmp[i];
7718 if (ws.mRebuilding) {
7719 StringWriter sw = new StringWriter();
7720 PrintWriter pw = new PrintWriter(sw);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07007721 ws.dump(pw, "", true);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007722 pw.flush();
7723 Slog.w(TAG, "This window was lost: " + ws);
7724 Slog.w(TAG, sw.toString());
Craig Mautner96868332012-12-04 14:29:11 -08007725 ws.mWinAnimator.destroySurfaceLocked();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007726 }
7727 }
7728 Slog.w(TAG, "Current app token list:");
Craig Mautner2ad92072013-02-25 16:19:24 -08007729 dumpAnimatingAppTokensLocked();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007730 Slog.w(TAG, "Final window list:");
7731 dumpWindowsLocked();
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007732 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07007733 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007734
Craig Mautner59c00972012-07-30 12:10:24 -07007735 private final void assignLayersLocked(WindowList windows) {
7736 int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007737 int curBaseLayer = 0;
7738 int curLayer = 0;
7739 int i;
Romain Guy06882f82009-06-10 13:36:04 -07007740
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007741 if (DEBUG_LAYERS) {
7742 RuntimeException here = new RuntimeException("here");
7743 here.fillInStackTrace();
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07007744 Slog.v(TAG, "Assigning layers", here);
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007745 }
7746
Svetoslav Ganov55468c62012-10-15 15:09:02 -07007747 boolean anyLayerChanged = false;
7748
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007749 for (i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07007750 final WindowState w = windows.get(i);
Craig Mautneracafd192012-05-10 10:41:02 -07007751 final WindowStateAnimator winAnimator = w.mWinAnimator;
7752 boolean layerChanged = false;
7753 int oldLayer = w.mLayer;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007754 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
7755 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007756 curLayer += WINDOW_LAYER_MULTIPLIER;
7757 w.mLayer = curLayer;
7758 } else {
7759 curBaseLayer = curLayer = w.mBaseLayer;
7760 w.mLayer = curLayer;
7761 }
Craig Mautneracafd192012-05-10 10:41:02 -07007762 if (w.mLayer != oldLayer) {
7763 layerChanged = true;
Svetoslav Ganov55468c62012-10-15 15:09:02 -07007764 anyLayerChanged = true;
Craig Mautneracafd192012-05-10 10:41:02 -07007765 }
7766 oldLayer = winAnimator.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007767 if (w.mTargetAppToken != null) {
Craig Mautneracafd192012-05-10 10:41:02 -07007768 winAnimator.mAnimLayer =
Craig Mautner59431632012-04-04 11:56:44 -07007769 w.mLayer + w.mTargetAppToken.mAppAnimator.animLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007770 } else if (w.mAppToken != null) {
Craig Mautneracafd192012-05-10 10:41:02 -07007771 winAnimator.mAnimLayer =
Craig Mautner59431632012-04-04 11:56:44 -07007772 w.mLayer + w.mAppToken.mAppAnimator.animLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007773 } else {
Craig Mautneracafd192012-05-10 10:41:02 -07007774 winAnimator.mAnimLayer = w.mLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007775 }
7776 if (w.mIsImWindow) {
Craig Mautneracafd192012-05-10 10:41:02 -07007777 winAnimator.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007778 } else if (w.mIsWallpaper) {
Craig Mautneracafd192012-05-10 10:41:02 -07007779 winAnimator.mAnimLayer += mWallpaperAnimLayerAdjustment;
7780 }
7781 if (winAnimator.mAnimLayer != oldLayer) {
7782 layerChanged = true;
Svetoslav Ganov55468c62012-10-15 15:09:02 -07007783 anyLayerChanged = true;
Craig Mautneracafd192012-05-10 10:41:02 -07007784 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07007785 if (layerChanged && mAnimator.isDimmingLocked(winAnimator)) {
Craig Mautneracafd192012-05-10 10:41:02 -07007786 // Force an animation pass just to update the mDimAnimator layer.
Craig Mautner96868332012-12-04 14:29:11 -08007787 scheduleAnimationLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007788 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007789 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
Craig Mautner8863cca2012-09-18 15:04:34 -07007790 + "mBase=" + w.mBaseLayer
7791 + " mLayer=" + w.mLayer
7792 + (w.mAppToken == null ?
7793 "" : " mAppLayer=" + w.mAppToken.mAppAnimator.animLayerAdjustment)
7794 + " =mAnimLayer=" + winAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007795 //System.out.println(
7796 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
7797 }
Svetoslav Ganov55468c62012-10-15 15:09:02 -07007798
Svetoslav Ganov545252f2012-12-10 18:29:24 -08007799 //TODO (multidisplay): Magnification is supported only for the default display.
7800 if (mDisplayMagnifier != null && anyLayerChanged
7801 && windows.get(windows.size() - 1).getDisplayId() == Display.DEFAULT_DISPLAY) {
7802 mDisplayMagnifier.onWindowLayersChangedLocked();
Svetoslav Ganov55468c62012-10-15 15:09:02 -07007803 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007804 }
7805
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007806 private final void performLayoutAndPlaceSurfacesLocked() {
Dianne Hackborn7ad44382012-10-18 17:46:00 -07007807 int loopCount = 6;
Craig Mautnera13a41d2012-10-16 12:53:13 -07007808 do {
7809 mTraversalScheduled = false;
7810 performLayoutAndPlaceSurfacesLockedLoop();
7811 mH.removeMessages(H.DO_TRAVERSAL);
Dianne Hackborn7ad44382012-10-18 17:46:00 -07007812 loopCount--;
7813 } while (mTraversalScheduled && loopCount > 0);
Craig Mautner96868332012-12-04 14:29:11 -08007814 mInnerFields.mWallpaperActionPending = false;
Craig Mautnera13a41d2012-10-16 12:53:13 -07007815 }
7816
7817 private boolean mInLayout = false;
7818 private final void performLayoutAndPlaceSurfacesLockedLoop() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007819 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07007820 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007821 throw new RuntimeException("Recursive call!");
7822 }
Craig Mautneref25d7a2012-05-15 23:01:47 -07007823 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
7824 + Debug.getCallers(3));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007825 return;
7826 }
7827
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007828 if (mWaitingForConfig) {
7829 // Our configuration has changed (most likely rotation), but we
7830 // don't yet have the complete configuration to report to
7831 // applications. Don't do any window layout until we have it.
7832 return;
7833 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08007834
Jeff Browne215f262012-09-10 16:01:14 -07007835 if (!mDisplayReady) {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07007836 // Not yet initialized, nothing to do.
7837 return;
7838 }
7839
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07007840 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08007841 mInLayout = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007842 boolean recoveringMemory = false;
Craig Mautner6cfa7292013-01-15 09:05:42 -08007843
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08007844 try {
7845 if (mForceRemoves != null) {
7846 recoveringMemory = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007847 // Wait a little bit for things to settle down, and off we go.
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08007848 for (int i=0; i<mForceRemoves.size(); i++) {
7849 WindowState ws = mForceRemoves.get(i);
7850 Slog.i(TAG, "Force removing: " + ws);
7851 removeWindowInnerLocked(ws.mSession, ws);
7852 }
7853 mForceRemoves = null;
7854 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
7855 Object tmp = new Object();
7856 synchronized (tmp) {
7857 try {
7858 tmp.wait(250);
7859 } catch (InterruptedException e) {
7860 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007861 }
7862 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08007863 } catch (RuntimeException e) {
Dianne Hackborn89620282011-09-11 12:47:45 -07007864 Log.wtf(TAG, "Unhandled exception while force removing for memory", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007865 }
Craig Mautner59c00972012-07-30 12:10:24 -07007866
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007867 try {
Craig Mautner76a71652012-09-03 23:23:58 -07007868 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Craig Mautnerbb1449b2012-03-23 16:11:14 -07007869
Craig Mautner59c00972012-07-30 12:10:24 -07007870 mInLayout = false;
7871
Craig Mautner19d59bc2012-09-04 11:15:56 -07007872 if (needsLayout()) {
Craig Mautnerbb1449b2012-03-23 16:11:14 -07007873 if (++mLayoutRepeatCount < 6) {
7874 requestTraversalLocked();
7875 } else {
7876 Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
7877 mLayoutRepeatCount = 0;
7878 }
7879 } else {
7880 mLayoutRepeatCount = 0;
7881 }
Craig Mautnerbb1449b2012-03-23 16:11:14 -07007882
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007883 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07007884 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
You Kimcb6291c2012-12-04 23:22:28 +09007885 mH.sendEmptyMessage(H.REPORT_WINDOWS_CHANGE);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007886 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007887 } catch (RuntimeException e) {
7888 mInLayout = false;
Dianne Hackborn89620282011-09-11 12:47:45 -07007889 Log.wtf(TAG, "Unhandled exception while laying out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007890 }
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07007891
7892 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007893 }
7894
Craig Mautner59c00972012-07-30 12:10:24 -07007895 private final void performLayoutLockedInner(final DisplayContent displayContent,
7896 boolean initial, boolean updateInputWindows) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07007897 if (!displayContent.layoutNeeded) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08007898 return;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007899 }
Craig Mautner19d59bc2012-09-04 11:15:56 -07007900 displayContent.layoutNeeded = false;
Craig Mautner59c00972012-07-30 12:10:24 -07007901 WindowList windows = displayContent.getWindowList();
Craig Mautner69b08182012-09-05 13:07:13 -07007902 boolean isDefaultDisplay = displayContent.isDefaultDisplay;
Craig Mautner59c00972012-07-30 12:10:24 -07007903
7904 DisplayInfo displayInfo = displayContent.getDisplayInfo();
7905 final int dw = displayInfo.logicalWidth;
7906 final int dh = displayInfo.logicalHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007907
Dianne Hackborndf89e652011-10-06 22:35:11 -07007908 final int NFW = mFakeWindows.size();
7909 for (int i=0; i<NFW; i++) {
7910 mFakeWindows.get(i).layout(dw, dh);
7911 }
7912
Craig Mautner59c00972012-07-30 12:10:24 -07007913 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007914 int i;
7915
Dianne Hackborn01b02a72012-01-12 14:05:03 -08007916 if (DEBUG_LAYOUT) {
7917 Slog.v(TAG, "-------------------------------------");
7918 Slog.v(TAG, "performLayout: needed="
Craig Mautner19d59bc2012-09-04 11:15:56 -07007919 + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
Dianne Hackborn01b02a72012-01-12 14:05:03 -08007920 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007921
7922 WindowStateAnimator universeBackground = null;
7923
Craig Mautner69b08182012-09-05 13:07:13 -07007924 mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mRotation);
7925 if (isDefaultDisplay) {
7926 // Not needed on non-default displays.
7927 mSystemDecorLayer = mPolicy.getSystemDecorRectLw(mSystemDecorRect);
7928 mScreenRect.set(0, 0, dw, dh);
7929 }
Romain Guy06882f82009-06-10 13:36:04 -07007930
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007931 int seq = mLayoutSeq+1;
7932 if (seq < 0) seq = 0;
7933 mLayoutSeq = seq;
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07007934
7935 boolean behindDream = false;
7936
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007937 // First perform layout of any root windows (not attached
7938 // to another window).
7939 int topAttached = -1;
7940 for (i = N-1; i >= 0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07007941 final WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007942
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007943 // Don't do layout of a window if it is not visible, or
7944 // soon won't be visible, to avoid wasting time and funky
7945 // changes while a window is animating away.
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07007946 final boolean gone = (behindDream && mPolicy.canBeForceHidden(win, win.mAttrs))
Craig Mautnerae446592012-12-06 19:05:05 -08007947 || win.isGoneForLayoutLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007948
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007949 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
Dianne Hackborn01b02a72012-01-12 14:05:03 -08007950 Slog.v(TAG, "1ST PASS " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007951 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
Craig Mautner812d2ca2012-09-27 15:35:34 -07007952 + " mLayoutAttached=" + win.mLayoutAttached
Craig Mautnera3f4bf52012-10-10 20:37:48 -07007953 + " screen changed=" + win.isConfigChanged());
Dianne Hackborn01b02a72012-01-12 14:05:03 -08007954 final AppWindowToken atoken = win.mAppToken;
7955 if (gone) Slog.v(TAG, " GONE: mViewVisibility="
7956 + win.mViewVisibility + " mRelayoutCalled="
7957 + win.mRelayoutCalled + " hidden="
7958 + win.mRootToken.hidden + " hiddenRequested="
7959 + (atoken != null && atoken.hiddenRequested)
7960 + " mAttachedHidden=" + win.mAttachedHidden);
7961 else Slog.v(TAG, " VIS: mViewVisibility="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007962 + win.mViewVisibility + " mRelayoutCalled="
7963 + win.mRelayoutCalled + " hidden="
7964 + win.mRootToken.hidden + " hiddenRequested="
7965 + (atoken != null && atoken.hiddenRequested)
7966 + " mAttachedHidden=" + win.mAttachedHidden);
7967 }
Craig Mautner69b08182012-09-05 13:07:13 -07007968
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007969 // If this view is GONE, then skip it -- keep the current
7970 // frame, and let the caller know so they can ignore it
7971 // if they want. (We do the normal layout for INVISIBLE
7972 // windows, since that means "perform layout as normal,
7973 // just don't display").
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007974 if (!gone || !win.mHaveFrame || win.mLayoutNeeded
Craig Mautnerf02296f2012-11-06 14:33:46 -08007975 || (win.mAttrs.type == TYPE_KEYGUARD && win.isConfigChanged())
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007976 || win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007977 if (!win.mLayoutAttached) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08007978 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08007979 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08007980 win.mContentChanged = false;
7981 }
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07007982 if (win.mAttrs.type == TYPE_DREAM) {
7983 // Don't layout windows behind a dream, so that if it
7984 // does stuff like hide the status bar we won't get a
7985 // bad transition when it goes away.
7986 behindDream = true;
7987 }
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08007988 win.mLayoutNeeded = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007989 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007990 mPolicy.layoutWindowLw(win, win.mAttrs, null);
7991 win.mLayoutSeq = seq;
Dianne Hackborn01b02a72012-01-12 14:05:03 -08007992 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007993 + win.mFrame + " mContainingFrame="
7994 + win.mContainingFrame + " mDisplayFrame="
7995 + win.mDisplayFrame);
7996 } else {
7997 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007998 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07007999 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008000 if (win.mViewVisibility == View.VISIBLE
8001 && win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND
8002 && universeBackground == null) {
8003 universeBackground = win.mWinAnimator;
8004 }
8005 }
8006
8007 if (mAnimator.mUniverseBackground != universeBackground) {
8008 mFocusMayChange = true;
8009 mAnimator.mUniverseBackground = universeBackground;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008010 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008011
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008012 boolean attachedBehindDream = false;
8013
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008014 // Now perform layout of attached windows, which usually
8015 // depend on the position of the window they are attached to.
8016 // XXX does not deal with windows that are attached to windows
8017 // that are themselves attached.
8018 for (i = topAttached; i >= 0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07008019 final WindowState win = windows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008020
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008021 if (win.mLayoutAttached) {
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008022 if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008023 + " mHaveFrame=" + win.mHaveFrame
8024 + " mViewVisibility=" + win.mViewVisibility
8025 + " mRelayoutCalled=" + win.mRelayoutCalled);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008026 // If this view is GONE, then skip it -- keep the current
8027 // frame, and let the caller know so they can ignore it
8028 // if they want. (We do the normal layout for INVISIBLE
8029 // windows, since that means "perform layout as normal,
8030 // just don't display").
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008031 if (attachedBehindDream && mPolicy.canBeForceHidden(win, win.mAttrs)) {
8032 continue;
8033 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008034 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008035 || !win.mHaveFrame || win.mLayoutNeeded) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008036 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08008037 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008038 win.mContentChanged = false;
8039 }
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008040 win.mLayoutNeeded = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008041 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008042 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
8043 win.mLayoutSeq = seq;
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008044 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008045 + win.mFrame + " mContainingFrame="
8046 + win.mContainingFrame + " mDisplayFrame="
8047 + win.mDisplayFrame);
8048 }
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008049 } else if (win.mAttrs.type == TYPE_DREAM) {
8050 // Don't layout windows behind a dream, so that if it
8051 // does stuff like hide the status bar we won't get a
8052 // bad transition when it goes away.
8053 attachedBehindDream = behindDream;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008054 }
8055 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08008056
Jeff Brown349703e2010-06-22 01:27:15 -07008057 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown3a22cd92011-01-21 13:59:04 -08008058 mInputMonitor.setUpdateInputWindowsNeededLw();
8059 if (updateInputWindows) {
Jeff Brown2e44b072011-01-24 15:21:56 -08008060 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08008061 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008062
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008063 mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008064 }
Romain Guy06882f82009-06-10 13:36:04 -07008065
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008066 void makeWindowFreezingScreenIfNeededLocked(WindowState w) {
8067 // If the screen is currently frozen or off, then keep
8068 // it frozen/off until this window draws at its new
8069 // orientation.
Craig Mautner2fb98b12012-03-20 17:24:00 -07008070 if (!okToDisplay()) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008071 if (DEBUG_ORIENTATION) Slog.v(TAG,
8072 "Changing surface while display frozen: " + w);
8073 w.mOrientationChanging = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -07008074 w.mLastFreezeDuration = 0;
Craig Mautner3255a282012-04-16 15:42:47 -07008075 mInnerFields.mOrientationChangeComplete = false;
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008076 if (!mWindowsFreezingScreen) {
8077 mWindowsFreezingScreen = true;
8078 // XXX should probably keep timeout from
8079 // when we first froze the display.
8080 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
Craig Mautner6cfa7292013-01-15 09:05:42 -08008081 mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT,
You Kimcb6291c2012-12-04 23:22:28 +09008082 WINDOW_FREEZE_TIMEOUT_DURATION);
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008083 }
8084 }
8085 }
8086
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008087 /**
8088 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
Craig Mautner19d59bc2012-09-04 11:15:56 -07008089 * @param windows List of windows on default display.
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008090 * @return bitmap indicating if another pass through layout must be made.
8091 */
Craig Mautner59c00972012-07-30 12:10:24 -07008092 public int handleAppTransitionReadyLocked(WindowList windows) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008093 int changes = 0;
8094 int i;
8095 int NN = mOpeningApps.size();
8096 boolean goodToGo = true;
8097 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8098 "Checking " + NN + " opening apps (frozen="
8099 + mDisplayFrozen + " timeout="
Craig Mautner164d4bb2012-11-26 13:51:23 -08008100 + mAppTransition.isTimeout() + ")...");
8101 if (!mDisplayFrozen && !mAppTransition.isTimeout()) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008102 // If the display isn't frozen, wait to do anything until
8103 // all of the apps are ready. Otherwise just go because
8104 // we'll unfreeze the display when everyone is ready.
8105 for (i=0; i<NN && goodToGo; i++) {
8106 AppWindowToken wtoken = mOpeningApps.get(i);
8107 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Craig Mautner1d961d42012-05-27 12:02:11 -07008108 "Check opening app=" + wtoken + ": allDrawn="
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008109 + wtoken.allDrawn + " startingDisplayed="
Craig Mautner7358fbf2012-04-12 21:06:33 -07008110 + wtoken.startingDisplayed + " startingMoved="
8111 + wtoken.startingMoved);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008112 if (!wtoken.allDrawn && !wtoken.startingDisplayed
8113 && !wtoken.startingMoved) {
8114 goodToGo = false;
8115 }
8116 }
8117 }
8118 if (goodToGo) {
8119 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
Craig Mautner164d4bb2012-11-26 13:51:23 -08008120 int transit = mAppTransition.getAppTransition();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008121 if (mSkipAppTransitionAnimation) {
Craig Mautner4b71aa12012-12-27 17:20:01 -08008122 transit = AppTransition.TRANSIT_UNSET;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008123 }
Craig Mautner164d4bb2012-11-26 13:51:23 -08008124 mAppTransition.goodToGo();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008125 mStartingIconInTransition = false;
8126 mSkipAppTransitionAnimation = false;
8127
8128 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
8129
Craig Mautneref25d7a2012-05-15 23:01:47 -07008130 rebuildAppWindowListLocked();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008131
Craig Mautner0afddcb2012-05-08 15:38:00 -07008132 // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
Craig Mautner83339b42012-05-01 22:13:23 -07008133 WindowState oldWallpaper =
8134 mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
Craig Mautner0afddcb2012-05-08 15:38:00 -07008135 && !mWallpaperTarget.mWinAnimator.isDummyAnimation()
Craig Mautner83339b42012-05-01 22:13:23 -07008136 ? null : mWallpaperTarget;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008137
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008138 mInnerFields.mWallpaperMayChange = false;
8139
8140 // The top-most window will supply the layout params,
8141 // and we will determine it below.
8142 LayoutParams animLp = null;
8143 int bestAnimLayer = -1;
8144 boolean fullscreenAnim = false;
8145
8146 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8147 "New wallpaper target=" + mWallpaperTarget
Daniel Sandlerab886f52012-06-04 14:36:25 -04008148 + ", oldWallpaper=" + oldWallpaper
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008149 + ", lower target=" + mLowerWallpaperTarget
8150 + ", upper target=" + mUpperWallpaperTarget);
Craig Mautnerae446592012-12-06 19:05:05 -08008151
8152 boolean openingAppHasWallpaper = false;
8153 boolean closingAppHasWallpaper = false;
8154 final AppWindowToken lowerWallpaperAppToken;
8155 final AppWindowToken upperWallpaperAppToken;
8156 if (mLowerWallpaperTarget == null) {
8157 lowerWallpaperAppToken = upperWallpaperAppToken = null;
8158 } else {
8159 lowerWallpaperAppToken = mLowerWallpaperTarget.mAppToken;
8160 upperWallpaperAppToken = mUpperWallpaperTarget.mAppToken;
8161 }
8162
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008163 // Do a first pass through the tokens for two
8164 // things:
8165 // (1) Determine if both the closing and opening
8166 // app token sets are wallpaper targets, in which
8167 // case special animations are needed
8168 // (since the wallpaper needs to stay static
8169 // behind them).
8170 // (2) Find the layout params of the top-most
8171 // application window in the tokens, which is
8172 // what will control the animation theme.
8173 final int NC = mClosingApps.size();
8174 NN = NC + mOpeningApps.size();
8175 for (i=0; i<NN; i++) {
Craig Mautnerae446592012-12-06 19:05:05 -08008176 final AppWindowToken wtoken;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008177 if (i < NC) {
8178 wtoken = mClosingApps.get(i);
Craig Mautnerae446592012-12-06 19:05:05 -08008179 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
8180 closingAppHasWallpaper = true;
8181 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008182 } else {
Craig Mautnerae446592012-12-06 19:05:05 -08008183 wtoken = mOpeningApps.get(i - NC);
8184 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
8185 openingAppHasWallpaper = true;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008186 }
8187 }
Craig Mautnerae446592012-12-06 19:05:05 -08008188
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008189 if (wtoken.appFullscreen) {
8190 WindowState ws = wtoken.findMainWindow();
8191 if (ws != null) {
8192 animLp = ws.mAttrs;
8193 bestAnimLayer = ws.mLayer;
8194 fullscreenAnim = true;
8195 }
8196 } else if (!fullscreenAnim) {
8197 WindowState ws = wtoken.findMainWindow();
8198 if (ws != null) {
8199 if (ws.mLayer > bestAnimLayer) {
8200 animLp = ws.mAttrs;
8201 bestAnimLayer = ws.mLayer;
8202 }
8203 }
8204 }
8205 }
8206
Craig Mautnerae446592012-12-06 19:05:05 -08008207 if (closingAppHasWallpaper && openingAppHasWallpaper) {
8208 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Wallpaper animation!");
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008209 switch (transit) {
Craig Mautner4b71aa12012-12-27 17:20:01 -08008210 case AppTransition.TRANSIT_ACTIVITY_OPEN:
8211 case AppTransition.TRANSIT_TASK_OPEN:
8212 case AppTransition.TRANSIT_TASK_TO_FRONT:
8213 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008214 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08008215 case AppTransition.TRANSIT_ACTIVITY_CLOSE:
8216 case AppTransition.TRANSIT_TASK_CLOSE:
8217 case AppTransition.TRANSIT_TASK_TO_BACK:
8218 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008219 break;
8220 }
Craig Mautnerae446592012-12-06 19:05:05 -08008221 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "New transit: " + transit);
Daniel Sandlerab886f52012-06-04 14:36:25 -04008222 } else if ((oldWallpaper != null) && !mOpeningApps.contains(oldWallpaper.mAppToken)) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008223 // We are transitioning from an activity with
8224 // a wallpaper to one without.
Craig Mautner4b71aa12012-12-27 17:20:01 -08008225 transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008226 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8227 "New transit away from wallpaper: " + transit);
Craig Mautner8863cca2012-09-18 15:04:34 -07008228 } else if (mWallpaperTarget != null && mWallpaperTarget.isVisibleLw()) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008229 // We are transitioning from an activity without
8230 // a wallpaper to now showing the wallpaper
Craig Mautner4b71aa12012-12-27 17:20:01 -08008231 transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008232 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8233 "New transit into wallpaper: " + transit);
8234 }
8235
8236 // If all closing windows are obscured, then there is
8237 // no need to do an animation. This is the case, for
8238 // example, when this transition is being done behind
8239 // the lock screen.
8240 if (!mPolicy.allowAppAnimationsLw()) {
8241 animLp = null;
8242 }
8243
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008244 AppWindowToken topOpeningApp = null;
8245 int topOpeningLayer = 0;
8246
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008247 NN = mOpeningApps.size();
8248 for (i=0; i<NN; i++) {
8249 AppWindowToken wtoken = mOpeningApps.get(i);
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008250 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Craig Mautnerbec53f72012-04-05 11:49:05 -07008251 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008252 appAnimator.clearThumbnail();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008253 wtoken.inPendingTransaction = false;
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008254 appAnimator.animation = null;
Craig Mautnerbec53f72012-04-05 11:49:05 -07008255 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008256 wtoken.updateReportedVisibilityLocked();
8257 wtoken.waitingToShow = false;
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008258
8259 appAnimator.mAllAppWinAnimators.clear();
8260 final int N = wtoken.allAppWindows.size();
8261 for (int j = 0; j < N; j++) {
8262 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
8263 }
8264 mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
8265
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008266 if (animLp != null) {
8267 int layer = -1;
8268 for (int j=0; j<wtoken.windows.size(); j++) {
8269 WindowState win = wtoken.windows.get(j);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07008270 if (win.mWinAnimator.mAnimLayer > layer) {
8271 layer = win.mWinAnimator.mAnimLayer;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008272 }
8273 }
8274 if (topOpeningApp == null || layer > topOpeningLayer) {
8275 topOpeningApp = wtoken;
8276 topOpeningLayer = layer;
8277 }
8278 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008279 }
8280 NN = mClosingApps.size();
8281 for (i=0; i<NN; i++) {
8282 AppWindowToken wtoken = mClosingApps.get(i);
8283 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Craig Mautner8863cca2012-09-18 15:04:34 -07008284 "Now closing app " + wtoken);
Craig Mautner59431632012-04-04 11:56:44 -07008285 wtoken.mAppAnimator.clearThumbnail();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008286 wtoken.inPendingTransaction = false;
Craig Mautner59431632012-04-04 11:56:44 -07008287 wtoken.mAppAnimator.animation = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008288 setTokenVisibilityLocked(wtoken, animLp, false,
8289 transit, false);
8290 wtoken.updateReportedVisibilityLocked();
8291 wtoken.waitingToHide = false;
8292 // Force the allDrawn flag, because we want to start
8293 // this guy's animations regardless of whether it's
8294 // gotten drawn.
8295 wtoken.allDrawn = true;
Craig Mautner7636dfb2012-11-16 15:24:11 -08008296 wtoken.deferClearAllDrawn = false;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008297 }
8298
Craig Mautner164d4bb2012-11-26 13:51:23 -08008299 AppWindowAnimator appAnimator =
8300 topOpeningApp == null ? null : topOpeningApp.mAppAnimator;
8301 Bitmap nextAppTransitionThumbnail = mAppTransition.getNextAppTransitionThumbnail();
8302 if (nextAppTransitionThumbnail != null && appAnimator != null
8303 && appAnimator.animation != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008304 // This thumbnail animation is very special, we need to have
8305 // an extra surface with the thumbnail included with the animation.
Craig Mautner164d4bb2012-11-26 13:51:23 -08008306 Rect dirty = new Rect(0, 0, nextAppTransitionThumbnail.getWidth(),
8307 nextAppTransitionThumbnail.getHeight());
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008308 try {
Jeff Browne215f262012-09-10 16:01:14 -07008309 // TODO(multi-display): support other displays
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008310 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07008311 final Display display = displayContent.getDisplay();
Mathias Agopian29479eb2013-02-14 14:36:04 -08008312 SurfaceControl surfaceControl = new SurfaceControl(mFxSession,
Jeff Brown64a55af2012-08-26 02:47:39 -07008313 "thumbnail anim",
Craig Mautner6881a102012-07-27 13:04:51 -07008314 dirty.width(), dirty.height(),
Mathias Agopian3866f0d2013-02-11 22:08:48 -08008315 PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
Mathias Agopian29479eb2013-02-14 14:36:04 -08008316 surfaceControl.setLayerStack(display.getLayerStack());
8317 appAnimator.thumbnail = surfaceControl;
8318 if (SHOW_TRANSACTIONS) Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008319 Surface drawSurface = new Surface();
Mathias Agopian29479eb2013-02-14 14:36:04 -08008320 drawSurface.copyFrom(surfaceControl);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008321 Canvas c = drawSurface.lockCanvas(dirty);
Craig Mautner164d4bb2012-11-26 13:51:23 -08008322 c.drawBitmap(nextAppTransitionThumbnail, 0, 0, null);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008323 drawSurface.unlockCanvasAndPost(c);
8324 drawSurface.release();
Craig Mautner164d4bb2012-11-26 13:51:23 -08008325 appAnimator.thumbnailLayer = topOpeningLayer;
8326 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
8327 Animation anim = mAppTransition.createThumbnailAnimationLocked(
8328 transit, true, true, displayInfo.appWidth, displayInfo.appHeight);
8329 appAnimator.thumbnailAnimation = anim;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008330 anim.restrictDuration(MAX_ANIMATION_DURATION);
8331 anim.scaleCurrentDuration(mTransitionAnimationScale);
Craig Mautner164d4bb2012-11-26 13:51:23 -08008332 Point p = new Point();
8333 mAppTransition.getStartingPoint(p);
8334 appAnimator.thumbnailX = p.x;
8335 appAnimator.thumbnailY = p.y;
Mathias Agopian3866f0d2013-02-11 22:08:48 -08008336 } catch (SurfaceControl.OutOfResourcesException e) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008337 Slog.e(TAG, "Can't allocate thumbnail surface w=" + dirty.width()
8338 + " h=" + dirty.height(), e);
Craig Mautner164d4bb2012-11-26 13:51:23 -08008339 appAnimator.clearThumbnail();
Mathias Agopian3866f0d2013-02-11 22:08:48 -08008340 } catch (Surface.OutOfResourcesException e) {
8341 Slog.e(TAG, "Can't allocate Canvas surface w=" + dirty.width()
8342 + " h=" + dirty.height(), e);
8343 appAnimator.clearThumbnail();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008344 }
8345 }
8346
Craig Mautner164d4bb2012-11-26 13:51:23 -08008347 mAppTransition.postAnimationCallback();
8348 mAppTransition.clear();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008349
8350 mOpeningApps.clear();
8351 mClosingApps.clear();
8352
8353 // This has changed the visibility of windows, so perform
8354 // a new layout to get them all up-to-date.
Craig Mautner39834192012-09-02 07:47:24 -07008355 changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008356 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008357 getDefaultDisplayContentLocked().layoutNeeded = true;
Craig Mautner59c00972012-07-30 12:10:24 -07008358
8359 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008360 if (windows == getDefaultWindowListLocked()
8361 && !moveInputMethodWindowsIfNeededLocked(true)) {
Craig Mautner59c00972012-07-30 12:10:24 -07008362 assignLayersLocked(windows);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008363 }
Craig Mautner59c00972012-07-30 12:10:24 -07008364 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, false /*updateInputWindows*/);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008365 mFocusMayChange = false;
8366 }
8367
8368 return changes;
8369 }
8370
8371 /**
8372 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008373 * @return bitmap indicating if another pass through layout must be made.
8374 */
Craig Mautner2f995a72012-02-21 09:53:21 -08008375 private int handleAnimatingStoppedAndTransitionLocked() {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008376 int changes = 0;
8377
Craig Mautner9a29a5d2012-12-27 19:03:40 -08008378 mAppTransition.setIdle();
Craig Mautneref25d7a2012-05-15 23:01:47 -07008379 // Restore window app tokens to the ActivityManager views
Craig Mautner2ad92072013-02-25 16:19:24 -08008380 for (int i = mAnimatingAppTokens.size() - 1; i >= 0; i--) {
8381 mAnimatingAppTokens.get(i).sendingToBottom = false;
Craig Mautner3f99fde2012-06-19 14:10:01 -07008382 }
Craig Mautner2ad92072013-02-25 16:19:24 -08008383 mAnimatingAppTokens.clear();
8384 mAnimatingAppTokens.addAll(mAppTokens);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008385 rebuildAppWindowListLocked();
Craig Mautneref25d7a2012-05-15 23:01:47 -07008386
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008387 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Craig Mautnerae446592012-12-06 19:05:05 -08008388 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
8389 "Wallpaper layer changed: assigning layers + relayout");
Craig Mautneref25d7a2012-05-15 23:01:47 -07008390 moveInputMethodWindowsIfNeededLocked(true);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008391 mInnerFields.mWallpaperMayChange = true;
8392 // Since the window list has been rebuilt, focus might
8393 // have to be recomputed since the actual order of windows
8394 // might have changed again.
8395 mFocusMayChange = true;
8396
8397 return changes;
8398 }
8399
Craig Mautnere32c3072012-03-12 15:25:35 -07008400 private void updateResizingWindows(final WindowState w) {
Craig Mautnera608b882012-03-30 13:03:49 -07008401 final WindowStateAnimator winAnimator = w.mWinAnimator;
Craig Mautnerade0a9a2012-10-06 13:55:07 -07008402 if (w.mHasSurface && w.mLayoutSeq == mLayoutSeq) {
Dianne Hackbornc4aad012013-02-22 15:05:25 -08008403 w.mOverscanInsetsChanged |=
8404 !w.mLastOverscanInsets.equals(w.mOverscanInsets);
Craig Mautnere32c3072012-03-12 15:25:35 -07008405 w.mContentInsetsChanged |=
Dianne Hackborn5c58de32012-04-28 19:52:37 -07008406 !w.mLastContentInsets.equals(w.mContentInsets);
Craig Mautnere32c3072012-03-12 15:25:35 -07008407 w.mVisibleInsetsChanged |=
Dianne Hackborn5c58de32012-04-28 19:52:37 -07008408 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Craig Mautner812d2ca2012-09-27 15:35:34 -07008409 boolean configChanged = w.isConfigChanged();
Craig Mautnere32c3072012-03-12 15:25:35 -07008410 if (DEBUG_CONFIGURATION && configChanged) {
8411 Slog.v(TAG, "Win " + w + " config changed: "
8412 + mCurConfiguration);
8413 }
8414 if (localLOGV) Slog.v(TAG, "Resizing " + w
8415 + ": configChanged=" + configChanged
8416 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
8417 w.mLastFrame.set(w.mFrame);
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07008418 if (w.mContentInsetsChanged
Craig Mautnere32c3072012-03-12 15:25:35 -07008419 || w.mVisibleInsetsChanged
Craig Mautnera608b882012-03-30 13:03:49 -07008420 || winAnimator.mSurfaceResized
Craig Mautnere32c3072012-03-12 15:25:35 -07008421 || configChanged) {
8422 if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
8423 Slog.v(TAG, "Resize reasons: "
8424 + " contentInsetsChanged=" + w.mContentInsetsChanged
Craig Mautnerae446592012-12-06 19:05:05 -08008425 + " " + w.mContentInsets.toShortString()
Craig Mautnere32c3072012-03-12 15:25:35 -07008426 + " visibleInsetsChanged=" + w.mVisibleInsetsChanged
Craig Mautnerae446592012-12-06 19:05:05 -08008427 + " " + w.mVisibleInsets.toShortString()
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008428 + " surfaceResized=" + winAnimator.mSurfaceResized
Craig Mautnere32c3072012-03-12 15:25:35 -07008429 + " configChanged=" + configChanged);
8430 }
8431
Dianne Hackbornc4aad012013-02-22 15:05:25 -08008432 w.mLastOverscanInsets.set(w.mOverscanInsets);
Craig Mautnere32c3072012-03-12 15:25:35 -07008433 w.mLastContentInsets.set(w.mContentInsets);
8434 w.mLastVisibleInsets.set(w.mVisibleInsets);
8435 makeWindowFreezingScreenIfNeededLocked(w);
8436 // If the orientation is changing, then we need to
8437 // hold off on unfreezing the display until this
8438 // window has been redrawn; to do that, we need
8439 // to go through the process of getting informed
8440 // by the application when it has finished drawing.
8441 if (w.mOrientationChanging) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07008442 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautner83339b42012-05-01 22:13:23 -07008443 "Orientation start waiting for draw mDrawState=DRAW_PENDING in "
Mathias Agopian29479eb2013-02-14 14:36:04 -08008444 + w + ", surface " + winAnimator.mSurfaceControl);
Craig Mautner749a7bb2012-04-02 13:49:53 -07008445 winAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
Craig Mautnere32c3072012-03-12 15:25:35 -07008446 if (w.mAppToken != null) {
8447 w.mAppToken.allDrawn = false;
Craig Mautner7636dfb2012-11-16 15:24:11 -08008448 w.mAppToken.deferClearAllDrawn = false;
Craig Mautnere32c3072012-03-12 15:25:35 -07008449 }
8450 }
8451 if (!mResizingWindows.contains(w)) {
8452 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008453 "Resizing window " + w + " to " + winAnimator.mSurfaceW
8454 + "x" + winAnimator.mSurfaceH);
Craig Mautnere32c3072012-03-12 15:25:35 -07008455 mResizingWindows.add(w);
8456 }
8457 } else if (w.mOrientationChanging) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07008458 if (w.isDrawnLw()) {
Craig Mautnere32c3072012-03-12 15:25:35 -07008459 if (DEBUG_ORIENTATION) Slog.v(TAG,
8460 "Orientation not waiting for draw in "
Mathias Agopian29479eb2013-02-14 14:36:04 -08008461 + w + ", surface " + winAnimator.mSurfaceControl);
Craig Mautnere32c3072012-03-12 15:25:35 -07008462 w.mOrientationChanging = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07008463 w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
8464 - mDisplayFreezeTime);
Craig Mautnere32c3072012-03-12 15:25:35 -07008465 }
8466 }
8467 }
8468 }
8469
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008470 /**
8471 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
8472 *
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008473 * @param w WindowState this method is applied to.
8474 * @param currentTime The time which animations use for calculating transitions.
8475 * @param innerDw Width of app window.
8476 * @param innerDh Height of app window.
8477 */
8478 private void handleNotObscuredLocked(final WindowState w, final long currentTime,
8479 final int innerDw, final int innerDh) {
8480 final WindowManager.LayoutParams attrs = w.mAttrs;
8481 final int attrFlags = attrs.flags;
8482 final boolean canBeSeen = w.isDisplayedLw();
8483
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07008484 if (w.mHasSurface) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008485 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
8486 mInnerFields.mHoldScreen = w.mSession;
8487 }
8488 if (!mInnerFields.mSyswin && w.mAttrs.screenBrightness >= 0
8489 && mInnerFields.mScreenBrightness < 0) {
8490 mInnerFields.mScreenBrightness = w.mAttrs.screenBrightness;
8491 }
8492 if (!mInnerFields.mSyswin && w.mAttrs.buttonBrightness >= 0
8493 && mInnerFields.mButtonBrightness < 0) {
8494 mInnerFields.mButtonBrightness = w.mAttrs.buttonBrightness;
8495 }
Jeff Brown1e3b98d2012-09-30 18:58:59 -07008496 if (!mInnerFields.mSyswin && w.mAttrs.userActivityTimeout >= 0
8497 && mInnerFields.mUserActivityTimeout < 0) {
8498 mInnerFields.mUserActivityTimeout = w.mAttrs.userActivityTimeout;
8499 }
8500
Craig Mautner65d11b32012-10-01 13:59:52 -07008501 final int type = attrs.type;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008502 if (canBeSeen
Craig Mautner65d11b32012-10-01 13:59:52 -07008503 && (type == TYPE_SYSTEM_DIALOG
Craig Mautner88400d32012-09-30 12:35:45 -07008504 || type == TYPE_RECENTS_OVERLAY
Craig Mautner65d11b32012-10-01 13:59:52 -07008505 || type == TYPE_KEYGUARD
8506 || type == TYPE_SYSTEM_ERROR)) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008507 mInnerFields.mSyswin = true;
8508 }
Craig Mautner65d11b32012-10-01 13:59:52 -07008509
8510 if (canBeSeen) {
8511 if (type == TYPE_DREAM || type == TYPE_KEYGUARD) {
8512 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_MIRROR;
8513 } else if (mInnerFields.mDisplayHasContent
8514 == LayoutFields.DISPLAY_CONTENT_UNKNOWN) {
8515 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNIQUE;
8516 }
8517 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008518 }
8519
8520 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
8521 if (opaqueDrawn && w.isFullscreen(innerDw, innerDh)) {
8522 // This window completely covers everything behind it,
Craig Mautner2fb98b12012-03-20 17:24:00 -07008523 // so we want to leave all of them as undimmed (for
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008524 // performance reasons).
8525 mInnerFields.mObscured = true;
Craig Mautner312eac42012-11-13 10:56:22 -08008526 }
8527 }
8528
8529 private void handleFlagDimBehind(WindowState w, int innerDw, int innerDh) {
8530 final WindowManager.LayoutParams attrs = w.mAttrs;
8531 if ((attrs.flags & FLAG_DIM_BEHIND) != 0
8532 && w.isDisplayedLw()
Craig Mautner236a35b2012-06-08 09:54:59 -07008533 && !w.mExiting) {
Craig Mautner312eac42012-11-13 10:56:22 -08008534 mInnerFields.mDimming = true;
8535 final WindowStateAnimator winAnimator = w.mWinAnimator;
8536 if (!mAnimator.isDimmingLocked(winAnimator)) {
Craig Mautner312eac42012-11-13 10:56:22 -08008537 if (localLOGV) Slog.v(TAG, "Win " + w + " start dimming.");
Craig Mautner1420b932012-12-28 17:14:38 -08008538 startDimmingLocked(winAnimator, w.mExiting ? 0 : w.mAttrs.dimAmount);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008539 }
8540 }
8541 }
8542
Craig Mautner2ad92072013-02-25 16:19:24 -08008543 private void updateAllDrawnLocked() {
Craig Mautner6fbda632012-07-03 09:26:39 -07008544 // See if any windows have been drawn, so they (and others
8545 // associated with them) can now be shown.
Craig Mautner2ad92072013-02-25 16:19:24 -08008546 final ArrayList<AppWindowToken> appTokens = mAnimatingAppTokens;
8547 final int NT = appTokens.size();
8548 for (int i=0; i<NT; i++) {
8549 AppWindowToken wtoken = appTokens.get(i);
Craig Mautner6fbda632012-07-03 09:26:39 -07008550 if (!wtoken.allDrawn) {
8551 int numInteresting = wtoken.numInterestingWindows;
8552 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
8553 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
8554 "allDrawn: " + wtoken
8555 + " interesting=" + numInteresting
8556 + " drawn=" + wtoken.numDrawnWindows);
8557 wtoken.allDrawn = true;
8558 }
8559 }
8560 }
8561 }
8562
Brad Fitzpatrick68044332010-11-22 18:19:48 -08008563 // "Something has changed! Let's make it correct now."
Craig Mautner76a71652012-09-03 23:23:58 -07008564 private final void performLayoutAndPlaceSurfacesLockedInner(boolean recoveringMemory) {
Craig Mautner7d8df392012-04-06 15:26:23 -07008565 if (DEBUG_WINDOW_TRACE) {
Craig Mautner3255a282012-04-16 15:42:47 -07008566 Slog.v(TAG, "performLayoutAndPlaceSurfacesLockedInner: entry. Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -07008567 + Debug.getCallers(3));
Craig Mautner7d8df392012-04-06 15:26:23 -07008568 }
Joe Onorato34bcebc2010-07-07 18:05:01 -04008569
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008570 final long currentTime = SystemClock.uptimeMillis();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008571
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008572 int i;
8573
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008574 if (mFocusMayChange) {
8575 mFocusMayChange = false;
Jeff Brown3a22cd92011-01-21 13:59:04 -08008576 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
8577 false /*updateInputWindows*/);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008578 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008579
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008580 // Initialize state of exiting tokens.
Craig Mautner2ad92072013-02-25 16:19:24 -08008581 for (i=mExitingTokens.size()-1; i>=0; i--) {
8582 mExitingTokens.get(i).hasVisible = false;
8583 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008584
Craig Mautner2ad92072013-02-25 16:19:24 -08008585 // Initialize state of exiting applications.
8586 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
8587 mExitingAppTokens.get(i).hasVisible = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008588 }
8589
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008590 mInnerFields.mHoldScreen = null;
8591 mInnerFields.mScreenBrightness = -1;
8592 mInnerFields.mButtonBrightness = -1;
Jeff Brown1e3b98d2012-09-30 18:58:59 -07008593 mInnerFields.mUserActivityTimeout = -1;
Craig Mautner65d11b32012-10-01 13:59:52 -07008594 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNKNOWN;
Jeff Brown1e3b98d2012-09-30 18:58:59 -07008595
Craig Mautner6fbda632012-07-03 09:26:39 -07008596 mTransactionSequence++;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07008597
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008598 final DisplayContent defaultDisplay = getDefaultDisplayContentLocked();
Craig Mautner76a71652012-09-03 23:23:58 -07008599 final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
8600 final int defaultDw = defaultInfo.logicalWidth;
8601 final int defaultDh = defaultInfo.logicalHeight;
Craig Mautner76a71652012-09-03 23:23:58 -07008602
Dianne Hackborn36991742011-10-11 21:35:26 -07008603 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
8604 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
Mathias Agopian3866f0d2013-02-11 22:08:48 -08008605 SurfaceControl.openTransaction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008606 try {
Craig Mautner76a71652012-09-03 23:23:58 -07008607
Jeff Brown4ed8fe72012-08-30 18:18:29 -07008608 if (mWatermark != null) {
Craig Mautner76a71652012-09-03 23:23:58 -07008609 mWatermark.positionSurface(defaultDw, defaultDh);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07008610 }
8611 if (mStrictModeFlash != null) {
Craig Mautner76a71652012-09-03 23:23:58 -07008612 mStrictModeFlash.positionSurface(defaultDw, defaultDh);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07008613 }
8614
Craig Mautner7358fbf2012-04-12 21:06:33 -07008615 boolean focusDisplayed = false;
Craig Mautner2ad92072013-02-25 16:19:24 -08008616 boolean updateAllDrawn = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008617
Craig Mautner7c6be102013-07-16 12:30:28 -07008618 final int numDisplays = mDisplayContents.size();
8619 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
8620 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautner76a71652012-09-03 23:23:58 -07008621 WindowList windows = displayContent.getWindowList();
8622 DisplayInfo displayInfo = displayContent.getDisplayInfo();
Craig Mautner19d59bc2012-09-04 11:15:56 -07008623 final int displayId = displayContent.getDisplayId();
Craig Mautner76a71652012-09-03 23:23:58 -07008624 final int dw = displayInfo.logicalWidth;
8625 final int dh = displayInfo.logicalHeight;
8626 final int innerDw = displayInfo.appWidth;
8627 final int innerDh = displayInfo.appHeight;
Craig Mautner19d59bc2012-09-04 11:15:56 -07008628 final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008629
Craig Mautner65d11b32012-10-01 13:59:52 -07008630 // Reset for each display unless we are forcing mirroring.
8631 if (mInnerFields.mDisplayHasContent != LayoutFields.DISPLAY_CONTENT_MIRROR) {
8632 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNKNOWN;
8633 }
8634
Craig Mautner76a71652012-09-03 23:23:58 -07008635 int repeats = 0;
8636 do {
8637 repeats++;
8638 if (repeats > 6) {
8639 Slog.w(TAG, "Animation repeat aborted after too many iterations");
Craig Mautner76a71652012-09-03 23:23:58 -07008640 displayContent.layoutNeeded = false;
8641 break;
Craig Mautner5702d4d2012-06-30 14:10:16 -07008642 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008643
Craig Mautner76a71652012-09-03 23:23:58 -07008644 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("On entry to LockedInner",
8645 displayContent.pendingLayoutChanges);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008646
Craig Mautner0bf6ec92012-12-18 08:33:27 -08008647 if ((displayContent.pendingLayoutChanges &
8648 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
8649 (adjustWallpaperWindowsLocked() &
8650 ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Craig Mautner76a71652012-09-03 23:23:58 -07008651 assignLayersLocked(windows);
Craig Mautner76a71652012-09-03 23:23:58 -07008652 displayContent.layoutNeeded = true;
8653 }
8654
8655 if (isDefaultDisplay && (displayContent.pendingLayoutChanges
8656 & WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
8657 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
8658 if (updateOrientationFromAppTokensLocked(true)) {
Craig Mautner76a71652012-09-03 23:23:58 -07008659 displayContent.layoutNeeded = true;
8660 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008661 }
8662 }
8663
Craig Mautner76a71652012-09-03 23:23:58 -07008664 if ((displayContent.pendingLayoutChanges
8665 & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
Craig Mautner76a71652012-09-03 23:23:58 -07008666 displayContent.layoutNeeded = true;
Craig Mautner6fbda632012-07-03 09:26:39 -07008667 }
Craig Mautner76a71652012-09-03 23:23:58 -07008668
8669 // FIRST LOOP: Perform a layout, if needed.
8670 if (repeats < 4) {
8671 performLayoutLockedInner(displayContent, repeats == 1,
8672 false /*updateInputWindows*/);
8673 } else {
8674 Slog.w(TAG, "Layout repeat skipped after too many iterations");
8675 }
8676
8677 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
8678 // it is animating.
8679 displayContent.pendingLayoutChanges = 0;
8680
8681 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("loop number "
8682 + mLayoutRepeatCount, displayContent.pendingLayoutChanges);
8683
Craig Mautner69b08182012-09-05 13:07:13 -07008684 if (isDefaultDisplay) {
8685 mPolicy.beginPostLayoutPolicyLw(dw, dh);
8686 for (i = windows.size() - 1; i >= 0; i--) {
8687 WindowState w = windows.get(i);
8688 if (w.mHasSurface) {
8689 mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs);
8690 }
Craig Mautner6fbda632012-07-03 09:26:39 -07008691 }
Craig Mautner69b08182012-09-05 13:07:13 -07008692 displayContent.pendingLayoutChanges |= mPolicy.finishPostLayoutPolicyLw();
8693 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
8694 "after finishPostLayoutPolicyLw", displayContent.pendingLayoutChanges);
Craig Mautner76a71652012-09-03 23:23:58 -07008695 }
Craig Mautner76a71652012-09-03 23:23:58 -07008696 } while (displayContent.pendingLayoutChanges != 0);
8697
8698 mInnerFields.mObscured = false;
8699 mInnerFields.mDimming = false;
8700 mInnerFields.mSyswin = false;
8701
8702 // Only used if default window
8703 final boolean someoneLosingFocus = !mLosingFocus.isEmpty();
8704
8705 final int N = windows.size();
8706 for (i=N-1; i>=0; i--) {
8707 WindowState w = windows.get(i);
8708
8709 final boolean obscuredChanged = w.mObscured != mInnerFields.mObscured;
8710
8711 // Update effect.
8712 w.mObscured = mInnerFields.mObscured;
8713 if (!mInnerFields.mObscured) {
8714 handleNotObscuredLocked(w, currentTime, innerDw, innerDh);
8715 }
8716
Craig Mautner312eac42012-11-13 10:56:22 -08008717 if (!mInnerFields.mDimming) {
8718 handleFlagDimBehind(w, innerDw, innerDh);
8719 }
8720
Craig Mautner76a71652012-09-03 23:23:58 -07008721 if (isDefaultDisplay && obscuredChanged && (mWallpaperTarget == w)
8722 && w.isVisibleLw()) {
8723 // This is the wallpaper target and its obscured state
8724 // changed... make sure the current wallaper's visibility
8725 // has been updated accordingly.
8726 updateWallpaperVisibilityLocked();
8727 }
8728
8729 final WindowStateAnimator winAnimator = w.mWinAnimator;
8730
8731 // If the window has moved due to its containing
8732 // content frame changing, then we'd like to animate
8733 // it.
8734 if (w.mHasSurface && w.shouldAnimateMove()) {
8735 // Frame has moved, containing content frame
8736 // has also moved, and we're not currently animating...
8737 // let's do something.
8738 Animation a = AnimationUtils.loadAnimation(mContext,
8739 com.android.internal.R.anim.window_move_from_decor);
8740 winAnimator.setAnimation(a);
8741 winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
8742 winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
8743 try {
8744 w.mClient.moved(w.mFrame.left, w.mFrame.top);
8745 } catch (RemoteException e) {
8746 }
8747 }
8748
8749 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
8750 w.mContentChanged = false;
8751
8752 // Moved from updateWindowsAndWallpaperLocked().
8753 if (w.mHasSurface) {
8754 // Take care of the window being ready to display.
Craig Mautner69b08182012-09-05 13:07:13 -07008755 final boolean committed =
8756 winAnimator.commitFinishDrawingLocked(currentTime);
8757 if (isDefaultDisplay && committed) {
Dianne Hackborn7ad44382012-10-18 17:46:00 -07008758 if (w.mAttrs.type == TYPE_DREAM) {
8759 // HACK: When a dream is shown, it may at that
8760 // point hide the lock screen. So we need to
8761 // redo the layout to let the phone window manager
8762 // make this happen.
8763 displayContent.pendingLayoutChanges |=
8764 WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
8765 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
8766 debugLayoutRepeats(
8767 "dream and commitFinishDrawingLocked true",
8768 displayContent.pendingLayoutChanges);
8769 }
8770 }
Craig Mautner65d11b32012-10-01 13:59:52 -07008771 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07008772 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Craig Mautner76a71652012-09-03 23:23:58 -07008773 "First draw done in potential wallpaper target " + w);
8774 mInnerFields.mWallpaperMayChange = true;
8775 displayContent.pendingLayoutChanges |=
8776 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
8777 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
8778 debugLayoutRepeats(
8779 "wallpaper and commitFinishDrawingLocked true",
8780 displayContent.pendingLayoutChanges);
Craig Mautner6fbda632012-07-03 09:26:39 -07008781 }
8782 }
Craig Mautner76a71652012-09-03 23:23:58 -07008783 }
8784
Craig Mautnera91f9e22012-09-14 16:22:08 -07008785 winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
Craig Mautner76a71652012-09-03 23:23:58 -07008786
8787 final AppWindowToken atoken = w.mAppToken;
Craig Mautner65d11b32012-10-01 13:59:52 -07008788 if (DEBUG_STARTING_WINDOW && atoken != null
8789 && w == atoken.startingWindow) {
Craig Mautner76a71652012-09-03 23:23:58 -07008790 Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen="
8791 + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
8792 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
8793 }
8794 if (atoken != null
8795 && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
8796 if (atoken.lastTransactionSequence != mTransactionSequence) {
8797 atoken.lastTransactionSequence = mTransactionSequence;
8798 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
8799 atoken.startingDisplayed = false;
8800 }
Craig Mautner65d11b32012-10-01 13:59:52 -07008801 if ((w.isOnScreen() || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
Craig Mautner76a71652012-09-03 23:23:58 -07008802 && !w.mExiting && !w.mDestroying) {
8803 if (WindowManagerService.DEBUG_VISIBILITY ||
8804 WindowManagerService.DEBUG_ORIENTATION) {
8805 Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
8806 + ", isAnimating=" + winAnimator.isAnimating());
8807 if (!w.isDrawnLw()) {
Mathias Agopian29479eb2013-02-14 14:36:04 -08008808 Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceControl
Craig Mautner76a71652012-09-03 23:23:58 -07008809 + " pv=" + w.mPolicyVisibility
8810 + " mDrawState=" + winAnimator.mDrawState
8811 + " ah=" + w.mAttachedHidden
8812 + " th=" + atoken.hiddenRequested
8813 + " a=" + winAnimator.mAnimating);
Craig Mautner6fbda632012-07-03 09:26:39 -07008814 }
8815 }
Craig Mautner76a71652012-09-03 23:23:58 -07008816 if (w != atoken.startingWindow) {
8817 if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
8818 atoken.numInterestingWindows++;
8819 if (w.isDrawnLw()) {
8820 atoken.numDrawnWindows++;
8821 if (WindowManagerService.DEBUG_VISIBILITY ||
8822 WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
8823 "tokenMayBeDrawn: " + atoken
8824 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen
8825 + " mAppFreezing=" + w.mAppFreezing);
8826 updateAllDrawn = true;
8827 }
8828 }
8829 } else if (w.isDrawnLw()) {
8830 atoken.startingDisplayed = true;
8831 }
Craig Mautner6fbda632012-07-03 09:26:39 -07008832 }
8833 }
8834 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008835
Craig Mautner76a71652012-09-03 23:23:58 -07008836 if (isDefaultDisplay && someoneLosingFocus && (w == mCurrentFocus)
8837 && w.isDisplayedLw()) {
8838 focusDisplayed = true;
8839 }
Craig Mautner51bb12b2012-04-27 14:39:53 -07008840
Craig Mautner76a71652012-09-03 23:23:58 -07008841 updateResizingWindows(w);
8842 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07008843
Craig Mautner65d11b32012-10-01 13:59:52 -07008844 final boolean hasUniqueContent;
8845 switch (mInnerFields.mDisplayHasContent) {
8846 case LayoutFields.DISPLAY_CONTENT_MIRROR:
8847 hasUniqueContent = isDefaultDisplay;
8848 break;
8849 case LayoutFields.DISPLAY_CONTENT_UNIQUE:
8850 hasUniqueContent = true;
8851 break;
8852 case LayoutFields.DISPLAY_CONTENT_UNKNOWN:
8853 default:
8854 hasUniqueContent = false;
8855 break;
8856 }
8857 mDisplayManagerService.setDisplayHasContent(displayId, hasUniqueContent,
8858 true /* inTraversal, must call performTraversalInTrans... below */);
8859
Craig Mautnera91f9e22012-09-14 16:22:08 -07008860 if (!mInnerFields.mDimming && mAnimator.isDimmingLocked(displayId)) {
8861 stopDimmingLocked(displayId);
8862 }
Craig Mautner2ad92072013-02-25 16:19:24 -08008863 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008864
Craig Mautner2ad92072013-02-25 16:19:24 -08008865 if (updateAllDrawn) {
8866 updateAllDrawnLocked();
Craig Mautner6fbda632012-07-03 09:26:39 -07008867 }
8868
Craig Mautner7358fbf2012-04-12 21:06:33 -07008869 if (focusDisplayed) {
8870 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
8871 }
Craig Mautner65d11b32012-10-01 13:59:52 -07008872
8873 // Give the display manager a chance to adjust properties
8874 // like display rotation if it needs to.
8875 mDisplayManagerService.performTraversalInTransactionFromWindowManager();
8876
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008877 } catch (RuntimeException e) {
Dianne Hackborn89620282011-09-11 12:47:45 -07008878 Log.wtf(TAG, "Unhandled exception in Window Manager", e);
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07008879 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -08008880 SurfaceControl.closeTransaction();
Chet Haased5d11af2012-10-31 08:57:17 -07008881 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
8882 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008883 }
8884
Craig Mautner76a71652012-09-03 23:23:58 -07008885 final WindowList defaultWindows = defaultDisplay.getWindowList();
8886
Craig Mautner764983d2012-03-22 11:37:36 -07008887 // If we are ready to perform an app transition, check through
8888 // all of the app tokens to be shown and see if they are ready
8889 // to go.
Craig Mautner164d4bb2012-11-26 13:51:23 -08008890 if (mAppTransition.isReady()) {
Craig Mautner76a71652012-09-03 23:23:58 -07008891 defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07008892 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAppTransitionReadyLocked",
Craig Mautnerae446592012-12-06 19:05:05 -08008893 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07008894 }
8895
Craig Mautner164d4bb2012-11-26 13:51:23 -08008896 if (!mAnimator.mAnimating && mAppTransition.isRunning()) {
Craig Mautner764983d2012-03-22 11:37:36 -07008897 // We have finished the animation of an app transition. To do
8898 // this, we have delayed a lot of operations like showing and
8899 // hiding apps, moving apps in Z-order, etc. The app token list
8900 // reflects the correct Z-order, but the window list may now
8901 // be out of sync with it. So here we will just rebuild the
8902 // entire app window list. Fun!
Craig Mautner76a71652012-09-03 23:23:58 -07008903 defaultDisplay.pendingLayoutChanges |= handleAnimatingStoppedAndTransitionLocked();
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07008904 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAnimStopAndXitionLock",
Craig Mautner76a71652012-09-03 23:23:58 -07008905 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07008906 }
8907
Craig Mautner76a71652012-09-03 23:23:58 -07008908 if (mInnerFields.mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
Craig Mautner164d4bb2012-11-26 13:51:23 -08008909 && !mAppTransition.isReady()) {
Craig Mautner764983d2012-03-22 11:37:36 -07008910 // At this point, there was a window with a wallpaper that
8911 // was force hiding other windows behind it, but now it
8912 // is going away. This may be simple -- just animate
8913 // away the wallpaper and its window -- or it may be
8914 // hard -- the wallpaper now needs to be shown behind
8915 // something that was hidden.
Craig Mautnerae446592012-12-06 19:05:05 -08008916 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07008917 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animateAwayWallpaperLocked",
Craig Mautner76a71652012-09-03 23:23:58 -07008918 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07008919 }
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07008920 mInnerFields.mWallpaperForceHidingChanged = false;
Craig Mautner764983d2012-03-22 11:37:36 -07008921
Craig Mautnere7ae2502012-03-26 17:11:19 -07008922 if (mInnerFields.mWallpaperMayChange) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07008923 if (WindowManagerService.DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Craig Mautnere7ae2502012-03-26 17:11:19 -07008924 "Wallpaper may change! Adjusting");
Craig Mautnerae446592012-12-06 19:05:05 -08008925 defaultDisplay.pendingLayoutChanges |=
8926 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
8927 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
8928 defaultDisplay.pendingLayoutChanges);
Craig Mautnere7ae2502012-03-26 17:11:19 -07008929 }
8930
8931 if (mFocusMayChange) {
8932 mFocusMayChange = false;
8933 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
8934 false /*updateInputWindows*/)) {
Craig Mautner76a71652012-09-03 23:23:58 -07008935 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
Craig Mautnere7ae2502012-03-26 17:11:19 -07008936 }
8937 }
Craig Mautner764983d2012-03-22 11:37:36 -07008938
Craig Mautner19d59bc2012-09-04 11:15:56 -07008939 if (needsLayout()) {
Craig Mautner76a71652012-09-03 23:23:58 -07008940 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
8941 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
8942 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07008943 }
8944
Craig Mautnerade0a9a2012-10-06 13:55:07 -07008945 for (i = mResizingWindows.size() - 1; i >= 0; i--) {
8946 WindowState win = mResizingWindows.get(i);
8947 if (win.mAppFreezing) {
8948 // Don't remove this window until rotation has completed.
8949 continue;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07008950 }
Craig Mautnerade0a9a2012-10-06 13:55:07 -07008951 final WindowStateAnimator winAnimator = win.mWinAnimator;
8952 try {
8953 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
8954 "Reporting new frame to " + win + ": " + win.mCompatFrame);
8955 int diff = 0;
8956 boolean configChanged = win.isConfigChanged();
Dianne Hackborn7ff30112012-11-08 11:12:09 -08008957 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
Craig Mautnerade0a9a2012-10-06 13:55:07 -07008958 && configChanged) {
8959 Slog.i(TAG, "Sending new config to window " + win + ": "
8960 + winAnimator.mSurfaceW + "x" + winAnimator.mSurfaceH
8961 + " / " + mCurConfiguration + " / 0x"
8962 + Integer.toHexString(diff));
8963 }
Craig Mautnere8552142012-11-07 13:55:47 -08008964 win.setConfiguration(mCurConfiguration);
Craig Mautnerade0a9a2012-10-06 13:55:07 -07008965 if (DEBUG_ORIENTATION &&
8966 winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) Slog.i(
8967 TAG, "Resizing " + win + " WITH DRAW PENDING");
Sangkyu Lee0438bd62013-01-16 14:53:17 +09008968 final IWindow client = win.mClient;
8969 final Rect frame = win.mFrame;
8970 final Rect overscanInsets = win.mLastOverscanInsets;
8971 final Rect contentInsets = win.mLastContentInsets;
8972 final Rect visibleInsets = win.mLastVisibleInsets;
8973 final boolean reportDraw
8974 = winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING;
8975 final Configuration newConfig = configChanged ? win.mConfiguration : null;
8976 if (win.mClient instanceof IWindow.Stub) {
8977 // To prevent deadlock simulate one-way call if win.mClient is a local object.
8978 mH.post(new Runnable() {
8979 @Override
8980 public void run() {
8981 try {
8982 client.resized(frame, overscanInsets, contentInsets,
8983 visibleInsets, reportDraw, newConfig);
8984 } catch (RemoteException e) {
8985 // Not a remote call, RemoteException won't be raised.
8986 }
8987 }
8988 });
8989 } else {
8990 client.resized(frame, overscanInsets, contentInsets, visibleInsets, reportDraw,
8991 newConfig);
8992 }
Dianne Hackbornc4aad012013-02-22 15:05:25 -08008993 win.mOverscanInsetsChanged = false;
Craig Mautnerade0a9a2012-10-06 13:55:07 -07008994 win.mContentInsetsChanged = false;
8995 win.mVisibleInsetsChanged = false;
8996 winAnimator.mSurfaceResized = false;
8997 } catch (RemoteException e) {
8998 win.mOrientationChanging = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07008999 win.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
9000 - mDisplayFreezeTime);
Craig Mautnerade0a9a2012-10-06 13:55:07 -07009001 }
9002 mResizingWindows.remove(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009003 }
Romain Guy06882f82009-06-10 13:36:04 -07009004
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009005 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
9006 "With display frozen, orientationChangeComplete="
9007 + mInnerFields.mOrientationChangeComplete);
9008 if (mInnerFields.mOrientationChangeComplete) {
9009 if (mWindowsFreezingScreen) {
9010 mWindowsFreezingScreen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009011 mLastFinishedFreezeSource = mInnerFields.mLastWindowFreezeSource;
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009012 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
9013 }
9014 stopFreezingDisplayLocked();
9015 }
9016
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009017 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009018 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009019 i = mDestroySurface.size();
9020 if (i > 0) {
9021 do {
9022 i--;
9023 WindowState win = mDestroySurface.get(i);
9024 win.mDestroying = false;
9025 if (mInputMethodWindow == win) {
9026 mInputMethodWindow = null;
9027 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009028 if (win == mWallpaperTarget) {
9029 wallpaperDestroyed = true;
9030 }
Craig Mautner96868332012-12-04 14:29:11 -08009031 win.mWinAnimator.destroySurfaceLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009032 } while (i > 0);
9033 mDestroySurface.clear();
9034 }
9035
9036 // Time to remove any exiting tokens?
Craig Mautner2ad92072013-02-25 16:19:24 -08009037 for (i=mExitingTokens.size()-1; i>=0; i--) {
9038 WindowToken token = mExitingTokens.get(i);
9039 if (!token.hasVisible) {
9040 mExitingTokens.remove(i);
9041 if (token.windowType == TYPE_WALLPAPER) {
9042 mWallpaperTokens.remove(token);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07009043 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009044 }
Craig Mautner2ad92072013-02-25 16:19:24 -08009045 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009046
Craig Mautner2ad92072013-02-25 16:19:24 -08009047 // Time to remove any exiting applications?
9048 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
9049 AppWindowToken token = mExitingAppTokens.get(i);
9050 if (!token.hasVisible && !mClosingApps.contains(token)) {
9051 // Make sure there is no animation running on this token,
9052 // so any windows associated with it will be removed as
9053 // soon as their animations are complete
9054 token.mAppAnimator.clearAnimation();
9055 token.mAppAnimator.animating = false;
9056 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
9057 "performLayout: App token exiting now removed" + token);
9058 mAppTokens.remove(token);
9059 mAnimatingAppTokens.remove(token);
9060 mExitingAppTokens.remove(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009061 }
9062 }
9063
Dianne Hackborn12d3a942012-04-27 14:16:30 -07009064 if (!mAnimator.mAnimating && mRelayoutWhileAnimating.size() > 0) {
9065 for (int j=mRelayoutWhileAnimating.size()-1; j>=0; j--) {
9066 try {
9067 mRelayoutWhileAnimating.get(j).mClient.doneAnimating();
9068 } catch (RemoteException e) {
9069 }
9070 }
9071 mRelayoutWhileAnimating.clear();
9072 }
9073
Craig Mautnerae446592012-12-06 19:05:05 -08009074 if (wallpaperDestroyed) {
9075 defaultDisplay.pendingLayoutChanges |=
9076 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
9077 defaultDisplay.layoutNeeded = true;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009078 }
Craig Mautner76a71652012-09-03 23:23:58 -07009079
Craig Mautner7c6be102013-07-16 12:30:28 -07009080 final int numDisplays = mDisplayContents.size();
9081 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9082 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautner76a71652012-09-03 23:23:58 -07009083 if (displayContent.pendingLayoutChanges != 0) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009084 displayContent.layoutNeeded = true;
Craig Mautner76a71652012-09-03 23:23:58 -07009085 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009086 }
Jeff Browneb857f12010-07-16 10:06:33 -07009087
Jeff Brown3a22cd92011-01-21 13:59:04 -08009088 // Finally update all input windows now that the window changes have stabilized.
Jeff Brown2e44b072011-01-24 15:21:56 -08009089 mInputMonitor.updateInputWindowsLw(true /*force*/);
Jeff Browneb857f12010-07-16 10:06:33 -07009090
Craig Mautner259328c2012-08-21 19:30:58 -07009091 setHoldScreenLocked(mInnerFields.mHoldScreen);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009092 if (!mDisplayFrozen) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009093 if (mInnerFields.mScreenBrightness < 0 || mInnerFields.mScreenBrightness > 1.0f) {
Jeff Brown96307042012-07-27 15:51:34 -07009094 mPowerManager.setScreenBrightnessOverrideFromWindowManager(-1);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009095 } else {
Jeff Brown96307042012-07-27 15:51:34 -07009096 mPowerManager.setScreenBrightnessOverrideFromWindowManager(
9097 toBrightnessOverride(mInnerFields.mScreenBrightness));
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009098 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009099 if (mInnerFields.mButtonBrightness < 0 || mInnerFields.mButtonBrightness > 1.0f) {
Jeff Brown96307042012-07-27 15:51:34 -07009100 mPowerManager.setButtonBrightnessOverrideFromWindowManager(-1);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009101 } else {
Jeff Brown96307042012-07-27 15:51:34 -07009102 mPowerManager.setButtonBrightnessOverrideFromWindowManager(
9103 toBrightnessOverride(mInnerFields.mButtonBrightness));
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009104 }
Jeff Brown1e3b98d2012-09-30 18:58:59 -07009105 mPowerManager.setUserActivityTimeoutOverrideFromWindowManager(
9106 mInnerFields.mUserActivityTimeout);
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009107 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009108
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009109 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009110 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Jeff Brown96307042012-07-27 15:51:34 -07009111 mPowerManager.wakeUp(SystemClock.uptimeMillis());
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009112 mTurnOnScreen = false;
9113 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009114
Craig Mautnera608b882012-03-30 13:03:49 -07009115 if (mInnerFields.mUpdateRotation) {
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009116 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009117 if (updateRotationUncheckedLocked(false)) {
Dianne Hackborn3e4f9d02011-02-04 14:05:55 -08009118 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07009119 } else {
Craig Mautnera608b882012-03-30 13:03:49 -07009120 mInnerFields.mUpdateRotation = false;
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009121 }
9122 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009123
Craig Mautner19d59bc2012-09-04 11:15:56 -07009124 if (mInnerFields.mOrientationChangeComplete && !defaultDisplay.layoutNeeded
9125 && !mInnerFields.mUpdateRotation) {
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07009126 checkDrawnWindowsLocked();
9127 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009128
Craig Mautner76a71652012-09-03 23:23:58 -07009129 final int N = mPendingRemove.size();
9130 if (N > 0) {
9131 if (mPendingRemoveTmp.length < N) {
9132 mPendingRemoveTmp = new WindowState[N+10];
9133 }
9134 mPendingRemove.toArray(mPendingRemoveTmp);
9135 mPendingRemove.clear();
9136 DisplayContentList displayList = new DisplayContentList();
9137 for (i = 0; i < N; i++) {
9138 WindowState w = mPendingRemoveTmp[i];
9139 removeWindowInnerLocked(w.mSession, w);
9140 if (!displayList.contains(w.mDisplayContent)) {
9141 displayList.add(w.mDisplayContent);
9142 }
9143 }
9144
9145 for (DisplayContent displayContent : displayList) {
9146 assignLayersLocked(displayContent.getWindowList());
Craig Mautner19d59bc2012-09-04 11:15:56 -07009147 displayContent.layoutNeeded = true;
Craig Mautner76a71652012-09-03 23:23:58 -07009148 }
Craig Mautner76a71652012-09-03 23:23:58 -07009149 }
9150
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08009151 // Check to see if we are now in a state where the screen should
9152 // be enabled, because the window obscured flags have changed.
9153 enableScreenIfNeededLocked();
Craig Mautner7d8df392012-04-06 15:26:23 -07009154
Craig Mautner96868332012-12-04 14:29:11 -08009155 scheduleAnimationLocked();
Craig Mautner7d8df392012-04-06 15:26:23 -07009156
9157 if (DEBUG_WINDOW_TRACE) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009158 Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: animating="
9159 + mAnimator.mAnimating);
Craig Mautner7d8df392012-04-06 15:26:23 -07009160 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009161 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009162
Jeff Brown96307042012-07-27 15:51:34 -07009163 private int toBrightnessOverride(float value) {
9164 return (int)(value * PowerManager.BRIGHTNESS_ON);
9165 }
9166
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009167 void checkDrawnWindowsLocked() {
9168 if (mWaitingForDrawn.size() > 0) {
9169 for (int j=mWaitingForDrawn.size()-1; j>=0; j--) {
9170 Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(j);
9171 WindowState win = pair.first;
9172 //Slog.i(TAG, "Waiting for drawn " + win + ": removed="
9173 // + win.mRemoved + " visible=" + win.isVisibleLw()
9174 // + " shown=" + win.mSurfaceShown);
9175 if (win.mRemoved || !win.isVisibleLw()) {
9176 // Window has been removed or made invisible; no draw
9177 // will now happen, so stop waiting.
9178 Slog.w(TAG, "Aborted waiting for drawn: " + pair.first);
9179 try {
9180 pair.second.sendResult(null);
9181 } catch (RemoteException e) {
9182 }
9183 mWaitingForDrawn.remove(pair);
9184 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009185 } else if (win.mWinAnimator.mSurfaceShown) {
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009186 // Window is now drawn (and shown).
9187 try {
9188 pair.second.sendResult(null);
9189 } catch (RemoteException e) {
9190 }
9191 mWaitingForDrawn.remove(pair);
9192 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9193 }
9194 }
9195 }
9196 }
9197
Craig Mautner2268e7e2012-12-13 15:40:00 -08009198 @Override
Jeff Brownc38c9be2012-10-04 13:16:19 -07009199 public boolean waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
9200 if (token != null && callback != null) {
9201 synchronized (mWindowMap) {
9202 WindowState win = windowForClientLocked(null, token, true);
9203 if (win != null) {
9204 Pair<WindowState, IRemoteCallback> pair =
9205 new Pair<WindowState, IRemoteCallback>(win, callback);
9206 Message m = mH.obtainMessage(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9207 mH.sendMessageDelayed(m, 2000);
9208 mWaitingForDrawn.add(pair);
9209 checkDrawnWindowsLocked();
9210 return true;
9211 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009212 }
9213 }
Jeff Brownc38c9be2012-10-04 13:16:19 -07009214 return false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009215 }
9216
Craig Mautner259328c2012-08-21 19:30:58 -07009217 void setHoldScreenLocked(final Session newHoldScreen) {
9218 final boolean hold = newHoldScreen != null;
9219
9220 if (hold && mHoldingScreenOn != newHoldScreen) {
9221 mHoldingScreenWakeLock.setWorkSource(new WorkSource(newHoldScreen.mUid));
9222 }
9223 mHoldingScreenOn = newHoldScreen;
9224
9225 final boolean state = mHoldingScreenWakeLock.isHeld();
9226 if (hold != state) {
9227 if (hold) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07009228 mHoldingScreenWakeLock.acquire();
Jeff Brownc38c9be2012-10-04 13:16:19 -07009229 mPolicy.keepScreenOnStartedLw();
Jeff Brown46b9ac02010-04-22 18:58:52 -07009230 } else {
Jeff Brownc38c9be2012-10-04 13:16:19 -07009231 mPolicy.keepScreenOnStoppedLw();
Jeff Brown46b9ac02010-04-22 18:58:52 -07009232 mHoldingScreenWakeLock.release();
9233 }
9234 }
9235 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009236
Craig Mautner722285e2012-09-07 13:55:58 -07009237 @Override
Jeff Brown4ed8fe72012-08-30 18:18:29 -07009238 public void requestTraversal() {
9239 synchronized (mWindowMap) {
9240 requestTraversalLocked();
9241 }
9242 }
9243
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08009244 void requestTraversalLocked() {
9245 if (!mTraversalScheduled) {
9246 mTraversalScheduled = true;
9247 mH.sendEmptyMessage(H.DO_TRAVERSAL);
9248 }
9249 }
9250
Craig Mautner711f90a2012-07-03 18:43:52 -07009251 /** Note that Locked in this case is on mLayoutToAnim */
Jeff Brown4a06c802012-02-15 15:06:01 -08009252 void scheduleAnimationLocked() {
Craig Mautner96868332012-12-04 14:29:11 -08009253 if (!mAnimationScheduled) {
9254 mAnimationScheduled = true;
Craig Mautner711f90a2012-07-03 18:43:52 -07009255 mChoreographer.postCallback(
9256 Choreographer.CALLBACK_ANIMATION, mAnimator.mAnimationRunnable, null);
9257 }
9258 }
9259
Craig Mautner1420b932012-12-28 17:14:38 -08009260 void startDimmingLocked(final WindowStateAnimator winAnimator, final float target) {
9261 mAnimator.setDimWinAnimatorLocked(winAnimator.mWin.getDisplayId(), winAnimator);
Craig Mautnera76fdb72012-07-03 19:03:02 -07009262 }
9263
Craig Mautnera91f9e22012-09-14 16:22:08 -07009264 void stopDimmingLocked(int displayId) {
Craig Mautner1420b932012-12-28 17:14:38 -08009265 mAnimator.setDimWinAnimatorLocked(displayId, null);
Craig Mautnera76fdb72012-07-03 19:03:02 -07009266 }
9267
Craig Mautner19d59bc2012-09-04 11:15:56 -07009268 private boolean needsLayout() {
Craig Mautner7c6be102013-07-16 12:30:28 -07009269 final int numDisplays = mDisplayContents.size();
9270 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9271 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
9272 if (displayContent.layoutNeeded) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009273 return true;
9274 }
9275 }
9276 return false;
9277 }
9278
Craig Mautner96868332012-12-04 14:29:11 -08009279 boolean copyAnimToLayoutParamsLocked() {
Craig Mautner322e4032012-07-13 13:35:20 -07009280 boolean doRequest = false;
Craig Mautner322e4032012-07-13 13:35:20 -07009281
Craig Mautner96868332012-12-04 14:29:11 -08009282 final int bulkUpdateParams = mAnimator.mBulkUpdateParams;
Craig Mautner96868332012-12-04 14:29:11 -08009283 if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) {
9284 mInnerFields.mUpdateRotation = true;
9285 doRequest = true;
Craig Mautner322e4032012-07-13 13:35:20 -07009286 }
Craig Mautner96868332012-12-04 14:29:11 -08009287 if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
9288 mInnerFields.mWallpaperMayChange = true;
9289 doRequest = true;
9290 }
9291 if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
9292 mInnerFields.mWallpaperForceHidingChanged = true;
9293 doRequest = true;
9294 }
9295 if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
9296 mInnerFields.mOrientationChangeComplete = false;
9297 } else {
9298 mInnerFields.mOrientationChangeComplete = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009299 mInnerFields.mLastWindowFreezeSource = mAnimator.mLastWindowFreezeSource;
Craig Mautner96868332012-12-04 14:29:11 -08009300 if (mWindowsFreezingScreen) {
9301 doRequest = true;
9302 }
9303 }
9304 if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
9305 mTurnOnScreen = true;
9306 }
9307 if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_ACTION_PENDING) != 0) {
9308 mInnerFields.mWallpaperActionPending = true;
9309 }
9310
Craig Mautner322e4032012-07-13 13:35:20 -07009311 return doRequest;
9312 }
9313
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009314 boolean reclaimSomeSurfaceMemoryLocked(WindowStateAnimator winAnimator, String operation,
9315 boolean secure) {
Mathias Agopian29479eb2013-02-14 14:36:04 -08009316 final SurfaceControl surface = winAnimator.mSurfaceControl;
Dianne Hackborn64825172011-03-02 21:32:58 -08009317 boolean leakedSurface = false;
9318 boolean killedApps = false;
Romain Guy06882f82009-06-10 13:36:04 -07009319
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009320 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
9321 winAnimator.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -07009322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009323 if (mForceRemoves == null) {
9324 mForceRemoves = new ArrayList<WindowState>();
9325 }
Romain Guy06882f82009-06-10 13:36:04 -07009326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009327 long callingIdentity = Binder.clearCallingIdentity();
9328 try {
9329 // There was some problem... first, do a sanity check of the
9330 // window list to make sure we haven't left any dangling surfaces
9331 // around.
Craig Mautner59c00972012-07-30 12:10:24 -07009332
Craig Mautner7c6be102013-07-16 12:30:28 -07009333 final int numDisplays = mDisplayContents.size();
9334 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9335 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
9336 final int numWindows = windows.size();
9337 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
9338 final WindowState ws = windows.get(winNdx);
9339 WindowStateAnimator wsa = ws.mWinAnimator;
9340 if (wsa.mSurfaceControl != null) {
9341 if (!mSessions.contains(wsa.mSession)) {
9342 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
9343 + ws + " surface=" + wsa.mSurfaceControl
9344 + " token=" + ws.mToken
9345 + " pid=" + ws.mSession.mPid
9346 + " uid=" + ws.mSession.mUid);
9347 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
9348 wsa.mSurfaceControl.destroy();
9349 wsa.mSurfaceShown = false;
9350 wsa.mSurfaceControl = null;
9351 ws.mHasSurface = false;
9352 mForceRemoves.add(ws);
9353 leakedSurface = true;
9354 } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
9355 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
9356 + ws + " surface=" + wsa.mSurfaceControl
9357 + " token=" + ws.mAppToken);
9358 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
9359 wsa.mSurfaceControl.destroy();
9360 wsa.mSurfaceShown = false;
9361 wsa.mSurfaceControl = null;
9362 ws.mHasSurface = false;
9363 leakedSurface = true;
9364 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009365 }
9366 }
9367 }
Romain Guy06882f82009-06-10 13:36:04 -07009368
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009369 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009370 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009371 SparseIntArray pidCandidates = new SparseIntArray();
Craig Mautner7c6be102013-07-16 12:30:28 -07009372 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9373 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
9374 final int numWindows = windows.size();
9375 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
9376 final WindowState ws = windows.get(winNdx);
9377 if (mForceRemoves.contains(ws)) {
9378 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009379 }
Craig Mautner7c6be102013-07-16 12:30:28 -07009380 WindowStateAnimator wsa = ws.mWinAnimator;
9381 if (wsa.mSurfaceControl != null) {
9382 pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
9383 }
9384 }
9385 if (pidCandidates.size() > 0) {
9386 int[] pids = new int[pidCandidates.size()];
9387 for (int i=0; i<pids.length; i++) {
9388 pids[i] = pidCandidates.keyAt(i);
9389 }
9390 try {
9391 if (mActivityManager.killPids(pids, "Free memory", secure)) {
9392 killedApps = true;
9393 }
9394 } catch (RemoteException e) {
9395 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009396 }
9397 }
9398 }
Romain Guy06882f82009-06-10 13:36:04 -07009399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009400 if (leakedSurface || killedApps) {
9401 // We managed to reclaim some memory, so get rid of the trouble
9402 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -08009403 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009404 if (surface != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009405 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
Dianne Hackborn5fd21692011-06-07 14:09:47 -07009406 "RECOVER DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009407 surface.destroy();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009408 winAnimator.mSurfaceShown = false;
Mathias Agopian29479eb2013-02-14 14:36:04 -08009409 winAnimator.mSurfaceControl = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009410 winAnimator.mWin.mHasSurface = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009411 }
Romain Guy06882f82009-06-10 13:36:04 -07009412
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009413 try {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009414 winAnimator.mWin.mClient.dispatchGetNewSurface();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009415 } catch (RemoteException e) {
9416 }
9417 }
9418 } finally {
9419 Binder.restoreCallingIdentity(callingIdentity);
9420 }
Dianne Hackborn64825172011-03-02 21:32:58 -08009421
9422 return leakedSurface || killedApps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009423 }
Romain Guy06882f82009-06-10 13:36:04 -07009424
Jeff Brown3a22cd92011-01-21 13:59:04 -08009425 private boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009426 WindowState newFocus = computeFocusedWindowLocked();
9427 if (mCurrentFocus != newFocus) {
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07009428 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009429 // This check makes sure that we don't already have the focus
9430 // change message pending.
9431 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
9432 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009433 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009434 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
9435 final WindowState oldFocus = mCurrentFocus;
9436 mCurrentFocus = newFocus;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009437 mAnimator.setCurrentFocus(newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009438 mLosingFocus.remove(newFocus);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009439 int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus);
Romain Guy06882f82009-06-10 13:36:04 -07009440
Craig Mautner59c00972012-07-30 12:10:24 -07009441 // TODO(multidisplay): Focused windows on default display only.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07009442 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07009443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009444 final WindowState imWindow = mInputMethodWindow;
9445 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009446 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009447 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009448 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
Jeff Brown20337632012-09-24 14:25:54 -07009449 displayContent.layoutNeeded = true;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009450 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009451 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Craig Mautner59c00972012-07-30 12:10:24 -07009452 performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009453 focusChanged &= ~WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009454 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
9455 // Client will do the layout, but we need to assign layers
9456 // for handleNewWindowLocked() below.
Craig Mautner59c00972012-07-30 12:10:24 -07009457 assignLayersLocked(displayContent.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009458 }
9459 }
Dianne Hackborndf89e652011-10-06 22:35:11 -07009460
Craig Mautner39834192012-09-02 07:47:24 -07009461 if ((focusChanged & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07009462 // The change in focus caused us to need to do a layout. Okay.
Jeff Brown20337632012-09-24 14:25:54 -07009463 displayContent.layoutNeeded = true;
Dianne Hackborndf89e652011-10-06 22:35:11 -07009464 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Craig Mautner59c00972012-07-30 12:10:24 -07009465 performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009466 }
9467 }
9468
Jeff Brown349703e2010-06-22 01:27:15 -07009469 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
9470 // If we defer assigning layers, then the caller is responsible for
9471 // doing this part.
Jeff Brown3a22cd92011-01-21 13:59:04 -08009472 finishUpdateFocusedWindowAfterAssignLayersLocked(updateInputWindows);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009473 }
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07009474
9475 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009476 return true;
9477 }
9478 return false;
9479 }
Craig Mautner66f78d72012-12-04 16:46:50 -08009480
Jeff Brown3a22cd92011-01-21 13:59:04 -08009481 private void finishUpdateFocusedWindowAfterAssignLayersLocked(boolean updateInputWindows) {
9482 mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows);
Jeff Brown349703e2010-06-22 01:27:15 -07009483 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009484
9485 private WindowState computeFocusedWindowLocked() {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07009486 if (mAnimator.mUniverseBackground != null
9487 && mAnimator.mUniverseBackground.mWin.canReceiveKeys()) {
9488 return mAnimator.mUniverseBackground.mWin;
9489 }
9490
Jeff Brown20337632012-09-24 14:25:54 -07009491 final int displayCount = mDisplayContents.size();
9492 for (int i = 0; i < displayCount; i++) {
9493 final DisplayContent displayContent = mDisplayContents.valueAt(i);
9494 WindowState win = findFocusedWindowLocked(displayContent);
9495 if (win != null) {
9496 return win;
9497 }
9498 }
9499 return null;
9500 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009501
Jeff Brown20337632012-09-24 14:25:54 -07009502 private WindowState findFocusedWindowLocked(DisplayContent displayContent) {
Craig Mautner2ad92072013-02-25 16:19:24 -08009503 int nextAppIndex = mAppTokens.size()-1;
9504 WindowToken nextApp = nextAppIndex >= 0 ? mAppTokens.get(nextAppIndex) : null;
Jeff Brown20337632012-09-24 14:25:54 -07009505
9506 final WindowList windows = displayContent.getWindowList();
Craig Mautner59c00972012-07-30 12:10:24 -07009507 for (int i = windows.size() - 1; i >= 0; i--) {
Jeff Brown20337632012-09-24 14:25:54 -07009508 final WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009509
Joe Onorato8a9b2202010-02-26 18:56:32 -08009510 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009511 TAG, "Looking for focus: " + i
9512 + " = " + win
9513 + ", flags=" + win.mAttrs.flags
9514 + ", canReceive=" + win.canReceiveKeys());
9515
9516 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -07009517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009518 // If this window's application has been removed, just skip it.
Craig Mautneref25d7a2012-05-15 23:01:47 -07009519 if (thisApp != null && (thisApp.removed || thisApp.sendingToBottom)) {
Craig Mautner3f99fde2012-06-19 14:10:01 -07009520 if (DEBUG_FOCUS) Slog.v(TAG, "Skipping app because " + (thisApp.removed
9521 ? "removed" : "sendingToBottom"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009522 continue;
9523 }
Romain Guy06882f82009-06-10 13:36:04 -07009524
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009525 // If there is a focused app, don't allow focus to go to any
9526 // windows below it. If this is an application window, step
9527 // through the app tokens until we find its app.
9528 if (thisApp != null && nextApp != null && thisApp != nextApp
9529 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
Craig Mautner2ad92072013-02-25 16:19:24 -08009530 int origAppIndex = nextAppIndex;
9531 while (nextAppIndex > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009532 if (nextApp == mFocusedApp) {
9533 // Whoops, we are below the focused app... no focus
9534 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -08009535 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009536 TAG, "Reached focused app: " + mFocusedApp);
9537 return null;
9538 }
Craig Mautner2ad92072013-02-25 16:19:24 -08009539 nextAppIndex--;
9540 nextApp = mAppTokens.get(nextAppIndex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009541 if (nextApp == thisApp) {
9542 break;
9543 }
9544 }
9545 if (thisApp != nextApp) {
9546 // Uh oh, the app token doesn't exist! This shouldn't
9547 // happen, but if it does we can get totally hosed...
9548 // so restart at the original app.
Craig Mautner2ad92072013-02-25 16:19:24 -08009549 nextAppIndex = origAppIndex;
9550 nextApp = mAppTokens.get(nextAppIndex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009551 }
9552 }
9553
9554 // Dispatch to this window if it is wants key events.
9555 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009556 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009557 TAG, "Found focus @ " + i + " = " + win);
Jeff Brown20337632012-09-24 14:25:54 -07009558 return win;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009559 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009560 }
Jeff Brown20337632012-09-24 14:25:54 -07009561 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009562 }
9563
Craig Mautner3c174372013-02-21 17:54:37 -08009564 private void startFreezingDisplayLocked(boolean inTransaction, int exitAnim, int enterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009565 if (mDisplayFrozen) {
9566 return;
9567 }
Romain Guy06882f82009-06-10 13:36:04 -07009568
Jeff Browne215f262012-09-10 16:01:14 -07009569 if (!mDisplayReady || !mPolicy.isScreenOnFully()) {
Dianne Hackborn8e8d65f2011-08-11 19:36:18 -07009570 // No need to freeze the screen before the system is ready or if
9571 // the screen is off.
9572 return;
9573 }
9574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009575 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -07009576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009577 mDisplayFrozen = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009578 mDisplayFreezeTime = SystemClock.elapsedRealtime();
9579 mLastFinishedFreezeSource = null;
Craig Mautner7d8df392012-04-06 15:26:23 -07009580
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009581 mInputMonitor.freezeInputDispatchingLw();
Craig Mautner7d8df392012-04-06 15:26:23 -07009582
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07009583 // Clear the last input window -- that is just used for
9584 // clean transitions between IMEs, and if we are freezing
9585 // the screen then the whole world is changing behind the scenes.
9586 mPolicy.setLastInputMethodWindowLw(null, null);
9587
Craig Mautner164d4bb2012-11-26 13:51:23 -08009588 if (mAppTransition.isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08009589 mAppTransition.freeze();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009590 }
Romain Guy06882f82009-06-10 13:36:04 -07009591
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009592 if (PROFILE_ORIENTATION) {
9593 File file = new File("/data/system/frozen");
9594 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
9595 }
Dianne Hackborna1111872010-11-23 20:55:11 -08009596
9597 if (CUSTOM_SCREEN_ROTATION) {
Craig Mautner3c174372013-02-21 17:54:37 -08009598 mExitAnimId = exitAnim;
9599 mEnterAnimId = enterAnim;
Craig Mautnera91f9e22012-09-14 16:22:08 -07009600 final DisplayContent displayContent = getDefaultDisplayContentLocked();
9601 final int displayId = displayContent.getDisplayId();
9602 ScreenRotationAnimation screenRotationAnimation =
9603 mAnimator.getScreenRotationAnimationLocked(displayId);
9604 if (screenRotationAnimation != null) {
9605 screenRotationAnimation.kill();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08009606 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07009607
Craig Mautner59c00972012-07-30 12:10:24 -07009608 // TODO(multidisplay): rotation on main screen only.
Jeff Browne215f262012-09-10 16:01:14 -07009609 final Display display = displayContent.getDisplay();
9610 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
Craig Mautnera91f9e22012-09-14 16:22:08 -07009611 screenRotationAnimation = new ScreenRotationAnimation(mContext,
Jeff Browne215f262012-09-10 16:01:14 -07009612 display, mFxSession, inTransaction, displayInfo.logicalWidth,
Craig Mautner3c174372013-02-21 17:54:37 -08009613 displayInfo.logicalHeight, display.getRotation());
Craig Mautnera91f9e22012-09-14 16:22:08 -07009614 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackborna1111872010-11-23 20:55:11 -08009615 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009616 }
Romain Guy06882f82009-06-10 13:36:04 -07009617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009618 private void stopFreezingDisplayLocked() {
9619 if (!mDisplayFrozen) {
9620 return;
9621 }
Romain Guy06882f82009-06-10 13:36:04 -07009622
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009623 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen
9624 || mClientFreezingScreen) {
Craig Mautnerd87946b2012-03-29 18:00:19 -07009625 if (DEBUG_ORIENTATION) Slog.d(TAG,
9626 "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + mWaitingForConfig
9627 + ", mAppsFreezingScreen=" + mAppsFreezingScreen
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009628 + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen
9629 + ", mClientFreezingScreen=" + mClientFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009630 return;
9631 }
Craig Mautner66f78d72012-12-04 16:46:50 -08009632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009633 mDisplayFrozen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009634 mLastDisplayFreezeDuration = (int)(SystemClock.elapsedRealtime() - mDisplayFreezeTime);
9635 StringBuilder sb = new StringBuilder(128);
9636 sb.append("Screen frozen for ");
9637 TimeUtils.formatDuration(mLastDisplayFreezeDuration, sb);
9638 if (mLastFinishedFreezeSource != null) {
9639 sb.append(" due to ");
9640 sb.append(mLastFinishedFreezeSource);
9641 }
9642 Slog.i(TAG, sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009643 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009644 mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009645 if (PROFILE_ORIENTATION) {
9646 Debug.stopMethodTracing();
9647 }
Dianne Hackborna1111872010-11-23 20:55:11 -08009648
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009649 boolean updateRotation = false;
Craig Mautner59c00972012-07-30 12:10:24 -07009650
Craig Mautnera91f9e22012-09-14 16:22:08 -07009651 final DisplayContent displayContent = getDefaultDisplayContentLocked();
9652 final int displayId = displayContent.getDisplayId();
9653 ScreenRotationAnimation screenRotationAnimation =
9654 mAnimator.getScreenRotationAnimationLocked(displayId);
9655 if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
9656 && screenRotationAnimation.hasScreenshot()) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07009657 if (DEBUG_ORIENTATION) Slog.i(TAG, "**** Dismissing screen rotation animation");
Craig Mautner59c00972012-07-30 12:10:24 -07009658 // TODO(multidisplay): rotation on main screen only.
Craig Mautnera91f9e22012-09-14 16:22:08 -07009659 DisplayInfo displayInfo = displayContent.getDisplayInfo();
Craig Mautner3c174372013-02-21 17:54:37 -08009660 // Get rotation animation again, with new top window
9661 boolean isDimming = mAnimator.isDimmingLocked(Display.DEFAULT_DISPLAY);
9662 if (!mPolicy.validateRotationAnimationLw(mExitAnimId, mEnterAnimId, isDimming)) {
9663 mExitAnimId = mEnterAnimId = 0;
9664 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07009665 if (screenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
Craig Mautner59c00972012-07-30 12:10:24 -07009666 mTransitionAnimationScale, displayInfo.logicalWidth,
Craig Mautner3c174372013-02-21 17:54:37 -08009667 displayInfo.logicalHeight, mExitAnimId, mEnterAnimId)) {
Craig Mautner96868332012-12-04 14:29:11 -08009668 scheduleAnimationLocked();
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009669 } else {
Craig Mautnera91f9e22012-09-14 16:22:08 -07009670 screenRotationAnimation.kill();
9671 screenRotationAnimation = null;
9672 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009673 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -08009674 }
9675 } else {
Craig Mautnera91f9e22012-09-14 16:22:08 -07009676 if (screenRotationAnimation != null) {
9677 screenRotationAnimation.kill();
9678 screenRotationAnimation = null;
9679 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009680 }
9681 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -08009682 }
Romain Guy06882f82009-06-10 13:36:04 -07009683
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009684 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009685
Dianne Hackborn420829e2011-01-28 11:30:35 -08009686 boolean configChanged;
Craig Mautner0bf6ec92012-12-18 08:33:27 -08009687
Christopher Tateb696aee2010-04-02 19:08:30 -07009688 // While the display is frozen we don't re-compute the orientation
9689 // to avoid inconsistent states. However, something interesting
9690 // could have actually changed during that time so re-evaluate it
9691 // now to catch that.
Dianne Hackborn420829e2011-01-28 11:30:35 -08009692 configChanged = updateOrientationFromAppTokensLocked(false);
Christopher Tateb696aee2010-04-02 19:08:30 -07009693
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009694 // A little kludge: a lot could have happened while the
9695 // display was frozen, so now that we are coming back we
9696 // do a gc so that any remote references the system
9697 // processes holds on others can be released if they are
9698 // no longer needed.
9699 mH.removeMessages(H.FORCE_GC);
You Kimcb6291c2012-12-04 23:22:28 +09009700 mH.sendEmptyMessageDelayed(H.FORCE_GC, 2000);
Romain Guy06882f82009-06-10 13:36:04 -07009701
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009702 mScreenFrozenLock.release();
Craig Mautner6cfa7292013-01-15 09:05:42 -08009703
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009704 if (updateRotation) {
9705 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Jeff Brown01a98dd2011-09-20 15:08:29 -07009706 configChanged |= updateRotationUncheckedLocked(false);
Dianne Hackborn420829e2011-01-28 11:30:35 -08009707 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08009708
Dianne Hackborn420829e2011-01-28 11:30:35 -08009709 if (configChanged) {
9710 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009711 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009712 }
Romain Guy06882f82009-06-10 13:36:04 -07009713
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07009714 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
9715 DisplayMetrics dm) {
9716 if (index < tokens.length) {
9717 String str = tokens[index];
9718 if (str != null && str.length() > 0) {
9719 try {
9720 int val = Integer.parseInt(str);
9721 return val;
9722 } catch (Exception e) {
9723 }
9724 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009725 }
9726 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
9727 return defDps;
9728 }
9729 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
9730 return val;
9731 }
9732
Jeff Brown4ed8fe72012-08-30 18:18:29 -07009733 void createWatermarkInTransaction() {
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009734 if (mWatermark != null) {
9735 return;
9736 }
9737
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07009738 File file = new File("/system/etc/setup.conf");
9739 FileInputStream in = null;
Craig Mautner2268e7e2012-12-13 15:40:00 -08009740 DataInputStream ind = null;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07009741 try {
9742 in = new FileInputStream(file);
Craig Mautner2268e7e2012-12-13 15:40:00 -08009743 ind = new DataInputStream(in);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07009744 String line = ind.readLine();
9745 if (line != null) {
9746 String[] toks = line.split("%");
9747 if (toks != null && toks.length > 0) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07009748 mWatermark = new Watermark(getDefaultDisplayContentLocked().getDisplay(),
Jeff Browne215f262012-09-10 16:01:14 -07009749 mRealDisplayMetrics, mFxSession, toks);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07009750 }
9751 }
9752 } catch (FileNotFoundException e) {
9753 } catch (IOException e) {
9754 } finally {
Craig Mautner2268e7e2012-12-13 15:40:00 -08009755 if (ind != null) {
9756 try {
9757 ind.close();
9758 } catch (IOException e) {
9759 }
Craig Mautner0bf6ec92012-12-18 08:33:27 -08009760 } else if (in != null) {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07009761 try {
9762 in.close();
9763 } catch (IOException e) {
9764 }
9765 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009766 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009767 }
9768
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009769 @Override
Joe Onorato664644d2011-01-23 17:53:23 -08009770 public void statusBarVisibilityChanged(int visibility) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07009771 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
9772 != PackageManager.PERMISSION_GRANTED) {
9773 throw new SecurityException("Caller does not hold permission "
9774 + android.Manifest.permission.STATUS_BAR);
9775 }
Dianne Hackborn9a230e02011-10-06 11:51:27 -07009776
Joe Onorato664644d2011-01-23 17:53:23 -08009777 synchronized (mWindowMap) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07009778 mLastStatusBarVisibility = visibility;
9779 visibility = mPolicy.adjustSystemUiVisibilityLw(visibility);
9780 updateStatusBarVisibilityLocked(visibility);
9781 }
9782 }
9783
Craig Mautner59c00972012-07-30 12:10:24 -07009784 // TOOD(multidisplay): StatusBar on multiple screens?
Dianne Hackborndf89e652011-10-06 22:35:11 -07009785 void updateStatusBarVisibilityLocked(int visibility) {
9786 mInputManager.setSystemUiVisibility(visibility);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07009787 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07009788 final int N = windows.size();
Dianne Hackborndf89e652011-10-06 22:35:11 -07009789 for (int i = 0; i < N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07009790 WindowState ws = windows.get(i);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009791 try {
9792 int curValue = ws.mSystemUiVisibility;
9793 int diff = curValue ^ visibility;
9794 // We are only interested in differences of one of the
9795 // clearable flags...
9796 diff &= View.SYSTEM_UI_CLEARABLE_FLAGS;
9797 // ...if it has actually been cleared.
9798 diff &= ~visibility;
9799 int newValue = (curValue&~diff) | (visibility&diff);
9800 if (newValue != curValue) {
9801 ws.mSeq++;
9802 ws.mSystemUiVisibility = newValue;
9803 }
9804 if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) {
9805 ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq,
9806 visibility, newValue, diff);
9807 }
9808 } catch (RemoteException e) {
9809 // so sorry
9810 }
9811 }
9812 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08009813
Dianne Hackborndf89e652011-10-06 22:35:11 -07009814 @Override
9815 public void reevaluateStatusBarVisibility() {
9816 synchronized (mWindowMap) {
9817 int visibility = mPolicy.adjustSystemUiVisibilityLw(mLastStatusBarVisibility);
9818 updateStatusBarVisibilityLocked(visibility);
9819 performLayoutAndPlaceSurfacesLocked();
9820 }
9821 }
9822
9823 @Override
Jeff Brown32cbc38552011-12-01 14:01:49 -08009824 public FakeWindow addFakeWindow(Looper looper,
9825 InputEventReceiver.Factory inputEventReceiverFactory,
Dianne Hackborndf89e652011-10-06 22:35:11 -07009826 String name, int windowType, int layoutParamsFlags, boolean canReceiveKeys,
9827 boolean hasFocus, boolean touchFullscreen) {
9828 synchronized (mWindowMap) {
Jeff Brown32cbc38552011-12-01 14:01:49 -08009829 FakeWindowImpl fw = new FakeWindowImpl(this, looper, inputEventReceiverFactory,
9830 name, windowType,
Dianne Hackborndf89e652011-10-06 22:35:11 -07009831 layoutParamsFlags, canReceiveKeys, hasFocus, touchFullscreen);
9832 int i=0;
9833 while (i<mFakeWindows.size()) {
9834 if (mFakeWindows.get(i).mWindowLayer <= fw.mWindowLayer) {
9835 break;
Joe Onorato664644d2011-01-23 17:53:23 -08009836 }
9837 }
Dianne Hackborndf89e652011-10-06 22:35:11 -07009838 mFakeWindows.add(i, fw);
9839 mInputMonitor.updateInputWindowsLw(true);
9840 return fw;
9841 }
9842 }
9843
9844 boolean removeFakeWindowLocked(FakeWindow window) {
9845 synchronized (mWindowMap) {
9846 if (mFakeWindows.remove(window)) {
9847 mInputMonitor.updateInputWindowsLw(true);
9848 return true;
9849 }
9850 return false;
Joe Onorato664644d2011-01-23 17:53:23 -08009851 }
9852 }
9853
satoke0a99412012-05-10 02:22:58 +09009854 // It is assumed that this method is called only by InputMethodManagerService.
9855 public void saveLastInputMethodWindowForTransition() {
9856 synchronized (mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -07009857 // TODO(multidisplay): Pass in the displayID.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07009858 DisplayContent displayContent = getDefaultDisplayContentLocked();
satoke0a99412012-05-10 02:22:58 +09009859 if (mInputMethodWindow != null) {
9860 mPolicy.setLastInputMethodWindowLw(mInputMethodWindow, mInputMethodTarget);
9861 }
9862 }
9863 }
9864
Daniel Sandler0c4ccff2011-10-19 16:39:14 -04009865 @Override
9866 public boolean hasNavigationBar() {
9867 return mPolicy.hasNavigationBar();
9868 }
9869
Craig Mautner96868332012-12-04 14:29:11 -08009870 @Override
Adam Cohenf7522022012-10-03 20:03:18 -07009871 public void lockNow(Bundle options) {
9872 mPolicy.lockNow(options);
Jim Miller93c518e2012-01-17 15:55:31 -08009873 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08009874
Craig Mautner96868332012-12-04 14:29:11 -08009875 @Override
Jim Millerbfec0a82012-11-05 20:05:22 -08009876 public boolean isSafeModeEnabled() {
9877 return mSafeMode;
9878 }
Jim Miller93c518e2012-01-17 15:55:31 -08009879
Craig Mautner96868332012-12-04 14:29:11 -08009880 @Override
Jim Miller4eeb4f62012-11-08 00:04:29 -08009881 public void showAssistant() {
9882 // TODO: What permission?
9883 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
9884 != PackageManager.PERMISSION_GRANTED) {
9885 return;
9886 }
9887 mPolicy.showAssistant();
9888 }
9889
Jeff Brownd7a04de2012-06-17 14:17:52 -07009890 void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009891 pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
Jeff Brownd7a04de2012-06-17 14:17:52 -07009892 mPolicy.dump(" ", pw, args);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009893 }
9894
Dianne Hackborn529e7442012-11-01 14:22:28 -07009895 void dumpAnimatorLocked(PrintWriter pw, String[] args, boolean dumpAll) {
9896 pw.println("WINDOW MANAGER ANIMATOR STATE (dumpsys window animator)");
9897 mAnimator.dumpLocked(pw, " ", dumpAll);
9898 }
9899
Jeff Brownd7a04de2012-06-17 14:17:52 -07009900 void dumpTokensLocked(PrintWriter pw, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009901 pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
9902 if (mTokenMap.size() > 0) {
9903 pw.println(" All tokens:");
9904 Iterator<WindowToken> it = mTokenMap.values().iterator();
9905 while (it.hasNext()) {
9906 WindowToken token = it.next();
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07009907 pw.print(" "); pw.print(token);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009908 if (dumpAll) {
9909 pw.println(':');
9910 token.dump(pw, " ");
9911 } else {
9912 pw.println();
9913 }
9914 }
9915 }
9916 if (mWallpaperTokens.size() > 0) {
9917 pw.println();
9918 pw.println(" Wallpaper tokens:");
9919 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
9920 WindowToken token = mWallpaperTokens.get(i);
9921 pw.print(" Wallpaper #"); pw.print(i);
9922 pw.print(' '); pw.print(token);
9923 if (dumpAll) {
9924 pw.println(':');
9925 token.dump(pw, " ");
9926 } else {
9927 pw.println();
9928 }
9929 }
9930 }
Craig Mautner2ad92072013-02-25 16:19:24 -08009931 if (mAppTokens.size() > 0) {
9932 pw.println();
9933 pw.println(" Application tokens in Z order:");
9934 for (int i=mAppTokens.size()-1; i>=0; i--) {
9935 pw.print(" App #"); pw.print(i);
9936 pw.print(' '); pw.print(mAppTokens.get(i)); pw.println(":");
9937 mAppTokens.get(i).dump(pw, " ");
9938 }
9939 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009940 if (mFinishedStarting.size() > 0) {
9941 pw.println();
9942 pw.println(" Finishing start of application tokens:");
9943 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
9944 WindowToken token = mFinishedStarting.get(i);
9945 pw.print(" Finished Starting #"); pw.print(i);
9946 pw.print(' '); pw.print(token);
9947 if (dumpAll) {
9948 pw.println(':');
9949 token.dump(pw, " ");
9950 } else {
9951 pw.println();
9952 }
9953 }
9954 }
Craig Mautner2ad92072013-02-25 16:19:24 -08009955 if (mExitingTokens.size() > 0) {
9956 pw.println();
9957 pw.println(" Exiting tokens:");
9958 for (int i=mExitingTokens.size()-1; i>=0; i--) {
9959 WindowToken token = mExitingTokens.get(i);
9960 pw.print(" Exiting #"); pw.print(i);
9961 pw.print(' '); pw.print(token);
9962 if (dumpAll) {
9963 pw.println(':');
9964 token.dump(pw, " ");
9965 } else {
9966 pw.println();
9967 }
9968 }
9969 }
9970 if (mExitingAppTokens.size() > 0) {
9971 pw.println();
9972 pw.println(" Exiting application tokens:");
9973 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
9974 WindowToken token = mExitingAppTokens.get(i);
9975 pw.print(" Exiting App #"); pw.print(i);
9976 pw.print(' '); pw.print(token);
9977 if (dumpAll) {
9978 pw.println(':');
9979 token.dump(pw, " ");
9980 } else {
9981 pw.println();
9982 }
9983 }
9984 }
9985 if (mAppTransition.isRunning() && mAnimatingAppTokens.size() > 0) {
9986 pw.println();
9987 pw.println(" Application tokens during animation:");
9988 for (int i=mAnimatingAppTokens.size()-1; i>=0; i--) {
9989 WindowToken token = mAnimatingAppTokens.get(i);
9990 pw.print(" App moving to bottom #"); pw.print(i);
9991 pw.print(' '); pw.print(token);
9992 if (dumpAll) {
9993 pw.println(':');
9994 token.dump(pw, " ");
9995 } else {
9996 pw.println();
9997 }
9998 }
9999 }
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010000 if (mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
10001 pw.println();
10002 if (mOpeningApps.size() > 0) {
10003 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
10004 }
10005 if (mClosingApps.size() > 0) {
10006 pw.print(" mClosingApps="); pw.println(mClosingApps);
10007 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010008 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010009 }
10010
Jeff Brownd7a04de2012-06-17 14:17:52 -070010011 void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010012 pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
10013 if (mSessions.size() > 0) {
10014 Iterator<Session> it = mSessions.iterator();
10015 while (it.hasNext()) {
10016 Session s = it.next();
10017 pw.print(" Session "); pw.print(s); pw.println(':');
10018 s.dump(pw, " ");
10019 }
10020 }
10021 }
10022
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010023 void dumpDisplayContentsLocked(PrintWriter pw, boolean dumpAll) {
10024 pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)");
10025 if (mDisplayReady) {
Craig Mautner7c6be102013-07-16 12:30:28 -070010026 final int numDisplays = mDisplayContents.size();
10027 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10028 mDisplayContents.valueAt(displayNdx).dump(" ", pw);
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010029 }
10030 } else {
10031 pw.println(" NO DISPLAY");
10032 }
10033 }
10034
Jeff Brownd7a04de2012-06-17 14:17:52 -070010035 void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010036 ArrayList<WindowState> windows) {
10037 pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010038 dumpWindowsNoHeaderLocked(pw, dumpAll, windows);
10039 }
10040
10041 void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll,
10042 ArrayList<WindowState> windows) {
Craig Mautner59c00972012-07-30 12:10:24 -070010043 int j = 0;
Craig Mautner7c6be102013-07-16 12:30:28 -070010044 final int numDisplays = mDisplayContents.size();
10045 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10046 final WindowList windowList = mDisplayContents.valueAt(displayNdx).getWindowList();
10047 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
10048 final WindowState w = windowList.get(winNdx);
10049 if (windows == null || windows.contains(w)) {
10050 pw.print(" Window #"); pw.print(j++); pw.print(' ');
10051 pw.print(w); pw.println(":");
10052 w.dump(pw, " ", dumpAll || windows != null);
10053 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010054 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010055 }
10056 if (mInputMethodDialogs.size() > 0) {
10057 pw.println();
10058 pw.println(" Input method dialogs:");
10059 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
10060 WindowState w = mInputMethodDialogs.get(i);
10061 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010062 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010063 }
10064 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010065 }
10066 if (mPendingRemove.size() > 0) {
10067 pw.println();
10068 pw.println(" Remove pending for:");
10069 for (int i=mPendingRemove.size()-1; i>=0; i--) {
10070 WindowState w = mPendingRemove.get(i);
10071 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010072 pw.print(" Remove #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010073 pw.print(w);
10074 if (dumpAll) {
10075 pw.println(":");
10076 w.dump(pw, " ", true);
10077 } else {
10078 pw.println();
10079 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010080 }
10081 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010082 }
10083 if (mForceRemoves != null && mForceRemoves.size() > 0) {
10084 pw.println();
10085 pw.println(" Windows force removing:");
10086 for (int i=mForceRemoves.size()-1; i>=0; i--) {
10087 WindowState w = mForceRemoves.get(i);
10088 pw.print(" Removing #"); pw.print(i); pw.print(' ');
10089 pw.print(w);
10090 if (dumpAll) {
10091 pw.println(":");
10092 w.dump(pw, " ", true);
10093 } else {
10094 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010095 }
10096 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010097 }
10098 if (mDestroySurface.size() > 0) {
10099 pw.println();
10100 pw.println(" Windows waiting to destroy their surface:");
10101 for (int i=mDestroySurface.size()-1; i>=0; i--) {
10102 WindowState w = mDestroySurface.get(i);
10103 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010104 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010105 pw.print(w);
10106 if (dumpAll) {
10107 pw.println(":");
10108 w.dump(pw, " ", true);
10109 } else {
10110 pw.println();
10111 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010112 }
10113 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010114 }
10115 if (mLosingFocus.size() > 0) {
10116 pw.println();
10117 pw.println(" Windows losing focus:");
10118 for (int i=mLosingFocus.size()-1; i>=0; i--) {
10119 WindowState w = mLosingFocus.get(i);
10120 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010121 pw.print(" Losing #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010122 pw.print(w);
10123 if (dumpAll) {
10124 pw.println(":");
10125 w.dump(pw, " ", true);
10126 } else {
10127 pw.println();
10128 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010129 }
10130 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010131 }
10132 if (mResizingWindows.size() > 0) {
10133 pw.println();
10134 pw.println(" Windows waiting to resize:");
10135 for (int i=mResizingWindows.size()-1; i>=0; i--) {
10136 WindowState w = mResizingWindows.get(i);
10137 if (windows == null || windows.contains(w)) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010138 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010139 pw.print(w);
10140 if (dumpAll) {
10141 pw.println(":");
10142 w.dump(pw, " ", true);
10143 } else {
10144 pw.println();
10145 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010146 }
10147 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010148 }
Dianne Hackborn38e29a62011-09-18 14:43:08 -070010149 if (mWaitingForDrawn.size() > 0) {
10150 pw.println();
10151 pw.println(" Clients waiting for these windows to be drawn:");
10152 for (int i=mWaitingForDrawn.size()-1; i>=0; i--) {
10153 Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(i);
10154 pw.print(" Waiting #"); pw.print(i); pw.print(' '); pw.print(pair.first);
10155 pw.print(": "); pw.println(pair.second);
10156 }
10157 }
Dianne Hackborn77119bc2012-10-23 14:32:48 -070010158 pw.println();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010159 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
10160 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
10161 if (mLastFocus != mCurrentFocus) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010162 pw.print(" mLastFocus="); pw.println(mLastFocus);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010163 }
10164 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
10165 if (mInputMethodTarget != null) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010166 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010167 }
10168 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
10169 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborna57c6952013-03-29 14:46:40 -070010170 pw.print(" mLastDisplayFreezeDuration=");
10171 TimeUtils.formatDuration(mLastDisplayFreezeDuration, pw);
10172 if ( mLastFinishedFreezeSource != null) {
10173 pw.print(" due to ");
10174 pw.print(mLastFinishedFreezeSource);
10175 }
10176 pw.println();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010177 if (dumpAll) {
Dianne Hackborn85afd1b2012-05-13 13:31:06 -070010178 pw.print(" mSystemDecorRect="); pw.print(mSystemDecorRect.toShortString());
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070010179 pw.print(" mSystemDecorLayer="); pw.print(mSystemDecorLayer);
Dianne Hackbornc652de82013-02-15 16:32:56 -080010180 pw.print(" mScreenRect="); pw.println(mScreenRect.toShortString());
Dianne Hackborndf89e652011-10-06 22:35:11 -070010181 if (mLastStatusBarVisibility != 0) {
10182 pw.print(" mLastStatusBarVisibility=0x");
10183 pw.println(Integer.toHexString(mLastStatusBarVisibility));
10184 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010185 if (mInputMethodWindow != null) {
10186 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
10187 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -070010188 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn529e7442012-11-01 14:22:28 -070010189 if (mLowerWallpaperTarget != null || mUpperWallpaperTarget != null) {
Dianne Hackborn284ac932009-08-28 10:34:25 -070010190 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
10191 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
10192 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010193 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
10194 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
10195 if (mInputMethodAnimLayerAdjustment != 0 ||
10196 mWallpaperAnimLayerAdjustment != 0) {
10197 pw.print(" mInputMethodAnimLayerAdjustment=");
10198 pw.print(mInputMethodAnimLayerAdjustment);
10199 pw.print(" mWallpaperAnimLayerAdjustment=");
10200 pw.println(mWallpaperAnimLayerAdjustment);
10201 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010202 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
10203 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
Craig Mautner19d59bc2012-09-04 11:15:56 -070010204 if (needsLayout()) {
10205 pw.print(" layoutNeeded on displays=");
Craig Mautner7c6be102013-07-16 12:30:28 -070010206 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10207 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautner19d59bc2012-09-04 11:15:56 -070010208 if (displayContent.layoutNeeded) {
10209 pw.print(displayContent.getDisplayId());
10210 }
10211 }
10212 pw.println();
10213 }
Craig Mautner69b08182012-09-05 13:07:13 -070010214 pw.print(" mTransactionSequence="); pw.println(mTransactionSequence);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010215 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -070010216 pw.print(" windows="); pw.print(mWindowsFreezingScreen);
10217 pw.print(" client="); pw.print(mClientFreezingScreen);
10218 pw.print(" apps="); pw.print(mAppsFreezingScreen);
10219 pw.print(" waitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010220 pw.print(" mRotation="); pw.print(mRotation);
Dianne Hackborndacea8c2011-04-21 17:26:39 -070010221 pw.print(" mAltOrientation="); pw.println(mAltOrientation);
Craig Mautnerf20588f2012-04-11 17:06:21 -070010222 pw.print(" mLastWindowForcedOrientation="); pw.print(mLastWindowForcedOrientation);
Dianne Hackbornbc7386c2011-06-06 17:27:54 -070010223 pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation);
Jeff Brown01a98dd2011-09-20 15:08:29 -070010224 pw.print(" mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
Dianne Hackborn4dcece82012-02-10 14:50:32 -080010225 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
10226 pw.print(" mTransitionWindowAnimationScale="); pw.print(mTransitionAnimationScale);
Chet Haasec38fa1f2012-02-01 16:37:46 -080010227 pw.print(" mAnimatorDurationScale="); pw.println(mAnimatorDurationScale);
Craig Mautner164d4bb2012-11-26 13:51:23 -080010228 pw.print(" mTraversalScheduled="); pw.println(mTraversalScheduled);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010229 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010230 pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Dianne Hackborn529e7442012-11-01 14:22:28 -070010231 pw.println(" mLayoutToAnim:");
Craig Mautner164d4bb2012-11-26 13:51:23 -080010232 mAppTransition.dump(pw);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010233 }
10234 }
10235
Jeff Brownd7a04de2012-06-17 14:17:52 -070010236 boolean dumpWindows(PrintWriter pw, String name, String[] args,
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010237 int opti, boolean dumpAll) {
Craig Mautner722285e2012-09-07 13:55:58 -070010238 WindowList windows = new WindowList();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010239 if ("visible".equals(name)) {
10240 synchronized(mWindowMap) {
Craig Mautner7c6be102013-07-16 12:30:28 -070010241 final int numDisplays = mDisplayContents.size();
10242 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10243 final WindowList windowList =
10244 mDisplayContents.valueAt(displayNdx).getWindowList();
10245 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
10246 final WindowState w = windowList.get(winNdx);
10247 if (w.mWinAnimator.mSurfaceShown) {
10248 windows.add(w);
10249 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010250 }
10251 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010252 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010253 } else {
10254 int objectId = 0;
10255 // See if this is an object ID.
10256 try {
10257 objectId = Integer.parseInt(name, 16);
10258 name = null;
10259 } catch (RuntimeException e) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010260 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010261 synchronized(mWindowMap) {
Craig Mautner7c6be102013-07-16 12:30:28 -070010262 final int numDisplays = mDisplayContents.size();
10263 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10264 final WindowList windowList = mDisplayContents.valueAt(displayNdx).getWindowList();
10265 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
10266 final WindowState w = windowList.get(winNdx);
10267 if (name != null) {
10268 if (w.mAttrs.getTitle().toString().contains(name)) {
10269 windows.add(w);
10270 }
10271 } else if (System.identityHashCode(w) == objectId) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010272 windows.add(w);
10273 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010274 }
10275 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010276 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010277 }
10278
10279 if (windows.size() <= 0) {
10280 return false;
10281 }
10282
10283 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010284 dumpWindowsLocked(pw, dumpAll, windows);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010285 }
10286 return true;
10287 }
10288
Jeff Brownd7a04de2012-06-17 14:17:52 -070010289 void dumpLastANRLocked(PrintWriter pw) {
10290 pw.println("WINDOW MANAGER LAST ANR (dumpsys window lastanr)");
10291 if (mLastANRState == null) {
10292 pw.println(" <no ANR has occurred since boot>");
10293 } else {
10294 pw.println(mLastANRState);
10295 }
10296 }
10297
10298 /**
10299 * Saves information about the state of the window manager at
10300 * the time an ANR occurred before anything else in the system changes
10301 * in response.
10302 *
Jeff Brownee172412012-06-18 12:58:03 -070010303 * @param appWindowToken The application that ANR'd, may be null.
Jeff Brownd7a04de2012-06-17 14:17:52 -070010304 * @param windowState The window that ANR'd, may be null.
10305 */
10306 public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState) {
10307 StringWriter sw = new StringWriter();
10308 PrintWriter pw = new PrintWriter(sw);
10309 pw.println(" ANR time: " + DateFormat.getInstance().format(new Date()));
Jeff Brownee172412012-06-18 12:58:03 -070010310 if (appWindowToken != null) {
10311 pw.println(" Application at fault: " + appWindowToken.stringName);
10312 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010313 if (windowState != null) {
10314 pw.println(" Window at fault: " + windowState.mAttrs.getTitle());
10315 }
10316 pw.println();
10317 dumpWindowsNoHeaderLocked(pw, true, null);
10318 pw.close();
10319 mLastANRState = sw.toString();
10320 }
10321
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010322 @Override
10323 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10324 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
10325 != PackageManager.PERMISSION_GRANTED) {
10326 pw.println("Permission Denial: can't dump WindowManager from from pid="
10327 + Binder.getCallingPid()
10328 + ", uid=" + Binder.getCallingUid());
10329 return;
10330 }
10331
10332 boolean dumpAll = false;
10333
10334 int opti = 0;
10335 while (opti < args.length) {
10336 String opt = args[opti];
10337 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10338 break;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010339 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010340 opti++;
10341 if ("-a".equals(opt)) {
10342 dumpAll = true;
10343 } else if ("-h".equals(opt)) {
10344 pw.println("Window manager dump options:");
10345 pw.println(" [-a] [-h] [cmd] ...");
10346 pw.println(" cmd may be one of:");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010347 pw.println(" l[astanr]: last ANR information");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010348 pw.println(" p[policy]: policy state");
Dianne Hackborn529e7442012-11-01 14:22:28 -070010349 pw.println(" a[animator]: animator state");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010350 pw.println(" s[essions]: active sessions");
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010351 pw.println(" d[isplays]: active display contents");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010352 pw.println(" t[okens]: token list");
10353 pw.println(" w[indows]: window list");
10354 pw.println(" cmd may also be a NAME to dump windows. NAME may");
10355 pw.println(" be a partial substring in a window name, a");
10356 pw.println(" Window hex object identifier, or");
10357 pw.println(" \"all\" for all windows, or");
10358 pw.println(" \"visible\" for the visible windows.");
10359 pw.println(" -a: include all available server state.");
10360 return;
Dianne Hackborn87fc3082010-12-03 13:09:12 -080010361 } else {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010362 pw.println("Unknown argument: " + opt + "; use -h for help");
Dianne Hackborn87fc3082010-12-03 13:09:12 -080010363 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010364 }
10365
10366 // Is the caller requesting to dump a particular piece of data?
10367 if (opti < args.length) {
10368 String cmd = args[opti];
10369 opti++;
Jeff Brownd7a04de2012-06-17 14:17:52 -070010370 if ("lastanr".equals(cmd) || "l".equals(cmd)) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010371 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010372 dumpLastANRLocked(pw);
10373 }
10374 return;
10375 } else if ("policy".equals(cmd) || "p".equals(cmd)) {
10376 synchronized(mWindowMap) {
10377 dumpPolicyLocked(pw, args, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010378 }
10379 return;
Dianne Hackborn529e7442012-11-01 14:22:28 -070010380 } else if ("animator".equals(cmd) || "a".equals(cmd)) {
10381 synchronized(mWindowMap) {
10382 dumpAnimatorLocked(pw, args, true);
10383 }
10384 return;
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010385 } else if ("sessions".equals(cmd) || "s".equals(cmd)) {
10386 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010387 dumpSessionsLocked(pw, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010388 }
10389 return;
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010390 } else if ("displays".equals(cmd) || "d".equals(cmd)) {
10391 synchronized(mWindowMap) {
10392 dumpDisplayContentsLocked(pw, true);
10393 }
10394 return;
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010395 } else if ("tokens".equals(cmd) || "t".equals(cmd)) {
10396 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010397 dumpTokensLocked(pw, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010398 }
10399 return;
10400 } else if ("windows".equals(cmd) || "w".equals(cmd)) {
10401 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010402 dumpWindowsLocked(pw, true, null);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010403 }
10404 return;
10405 } else if ("all".equals(cmd) || "a".equals(cmd)) {
10406 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010407 dumpWindowsLocked(pw, true, null);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010408 }
10409 return;
10410 } else {
10411 // Dumping a single name?
Jeff Brownd7a04de2012-06-17 14:17:52 -070010412 if (!dumpWindows(pw, cmd, args, opti, dumpAll)) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010413 pw.println("Bad window command, or no windows match: " + cmd);
10414 pw.println("Use -h for help.");
10415 }
10416 return;
10417 }
10418 }
10419
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010420 synchronized(mWindowMap) {
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010421 pw.println();
10422 if (dumpAll) {
10423 pw.println("-------------------------------------------------------------------------------");
10424 }
10425 dumpLastANRLocked(pw);
10426 pw.println();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010427 if (dumpAll) {
10428 pw.println("-------------------------------------------------------------------------------");
10429 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010430 dumpPolicyLocked(pw, args, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010431 pw.println();
10432 if (dumpAll) {
10433 pw.println("-------------------------------------------------------------------------------");
10434 }
Dianne Hackborn529e7442012-11-01 14:22:28 -070010435 dumpAnimatorLocked(pw, args, dumpAll);
10436 pw.println();
10437 if (dumpAll) {
10438 pw.println("-------------------------------------------------------------------------------");
10439 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010440 dumpSessionsLocked(pw, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010441 pw.println();
10442 if (dumpAll) {
10443 pw.println("-------------------------------------------------------------------------------");
10444 }
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010445 dumpDisplayContentsLocked(pw, dumpAll);
10446 pw.println();
10447 if (dumpAll) {
10448 pw.println("-------------------------------------------------------------------------------");
10449 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010450 dumpTokensLocked(pw, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010451 pw.println();
10452 if (dumpAll) {
10453 pw.println("-------------------------------------------------------------------------------");
10454 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010455 dumpWindowsLocked(pw, dumpAll, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010456 }
10457 }
10458
Jeff Brown349703e2010-06-22 01:27:15 -070010459 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
Craig Mautner96868332012-12-04 14:29:11 -080010460 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010461 public void monitor() {
10462 synchronized (mWindowMap) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070010463 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010464
Jeff Brown2992ea72011-01-28 22:04:14 -080010465 public interface OnHardKeyboardStatusChangeListener {
10466 public void onHardKeyboardStatusChange(boolean available, boolean enabled);
10467 }
Craig Mautnera2c77052012-03-26 12:14:43 -070010468
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070010469 void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
Craig Mautnercf8cbbe2012-03-25 21:54:36 -070010470 if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070010471 Slog.v(TAG, "Layouts looping: " + msg + ", mPendingLayoutChanges = 0x" +
10472 Integer.toHexString(pendingLayoutChanges));
Craig Mautnercf8cbbe2012-03-25 21:54:36 -070010473 }
10474 }
Craig Mautner59c00972012-07-30 12:10:24 -070010475
Dianne Hackbornc652de82013-02-15 16:32:56 -080010476 private DisplayContent newDisplayContentLocked(final Display display) {
10477 DisplayContent displayContent = new DisplayContent(display);
10478 mDisplayContents.put(display.getDisplayId(), displayContent);
10479 final Rect rect = new Rect();
10480 DisplayInfo info = displayContent.getDisplayInfo();
10481 mDisplaySettings.getOverscanLocked(info.name, rect);
10482 info.overscanLeft = rect.left;
10483 info.overscanTop = rect.top;
10484 info.overscanRight = rect.right;
10485 info.overscanBottom = rect.bottom;
10486 mDisplayManagerService.setOverscan(display.getDisplayId(), rect.left, rect.top,
10487 rect.right, rect.bottom);
10488 mPolicy.setDisplayOverscan(displayContent.getDisplay(), rect.left, rect.top,
10489 rect.right, rect.bottom);
10490 return displayContent;
10491 }
10492
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010493 public void createDisplayContentLocked(final Display display) {
Craig Mautner722285e2012-09-07 13:55:58 -070010494 if (display == null) {
10495 throw new IllegalArgumentException("getDisplayContent: display must not be null");
10496 }
Dianne Hackbornc652de82013-02-15 16:32:56 -080010497 newDisplayContentLocked(display);
Craig Mautner722285e2012-09-07 13:55:58 -070010498 }
10499
Craig Mautner2d5618c2012-10-18 13:55:47 -070010500 /**
10501 * Retrieve the DisplayContent for the specified displayId. Will create a new DisplayContent if
10502 * there is a Display for the displayId.
10503 * @param displayId The display the caller is interested in.
10504 * @return The DisplayContent associated with displayId or null if there is no Display for it.
10505 */
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010506 public DisplayContent getDisplayContentLocked(final int displayId) {
Craig Mautner59c00972012-07-30 12:10:24 -070010507 DisplayContent displayContent = mDisplayContents.get(displayId);
10508 if (displayContent == null) {
Craig Mautner2d5618c2012-10-18 13:55:47 -070010509 final Display display = mDisplayManager.getDisplay(displayId);
10510 if (display != null) {
Dianne Hackbornc652de82013-02-15 16:32:56 -080010511 displayContent = newDisplayContentLocked(display);
Craig Mautner2d5618c2012-10-18 13:55:47 -070010512 }
Craig Mautner59c00972012-07-30 12:10:24 -070010513 }
10514 return displayContent;
10515 }
10516
Craig Mautner2d5618c2012-10-18 13:55:47 -070010517 // There is an inherent assumption that this will never return null.
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010518 public DisplayContent getDefaultDisplayContentLocked() {
10519 return getDisplayContentLocked(Display.DEFAULT_DISPLAY);
Craig Mautner59c00972012-07-30 12:10:24 -070010520 }
10521
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010522 public WindowList getDefaultWindowListLocked() {
10523 return getDefaultDisplayContentLocked().getWindowList();
Craig Mautner59c00972012-07-30 12:10:24 -070010524 }
10525
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010526 public DisplayInfo getDefaultDisplayInfoLocked() {
10527 return getDefaultDisplayContentLocked().getDisplayInfo();
Craig Mautner59c00972012-07-30 12:10:24 -070010528 }
10529
Craig Mautner2d5618c2012-10-18 13:55:47 -070010530 /**
10531 * Return the list of WindowStates associated on the passed display.
10532 * @param display The screen to return windows from.
10533 * @return The list of WindowStates on the screen, or null if the there is no screen.
10534 */
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010535 public WindowList getWindowListLocked(final Display display) {
Craig Mautner96868332012-12-04 14:29:11 -080010536 return getWindowListLocked(display.getDisplayId());
10537 }
10538
10539 /**
10540 * Return the list of WindowStates associated on the passed display.
10541 * @param displayId The screen to return windows from.
10542 * @return The list of WindowStates on the screen, or null if the there is no screen.
10543 */
10544 public WindowList getWindowListLocked(final int displayId) {
10545 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -070010546 return displayContent != null ? displayContent.getWindowList() : null;
Craig Mautner39834192012-09-02 07:47:24 -070010547 }
Craig Mautner722285e2012-09-07 13:55:58 -070010548
10549 @Override
10550 public void onDisplayAdded(int displayId) {
10551 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_ADDED, displayId, 0));
10552 }
10553
10554 private void handleDisplayAddedLocked(int displayId) {
Craig Mautner2d5618c2012-10-18 13:55:47 -070010555 final Display display = mDisplayManager.getDisplay(displayId);
10556 if (display != null) {
10557 createDisplayContentLocked(display);
10558 displayReady(displayId);
10559 }
Craig Mautner722285e2012-09-07 13:55:58 -070010560 }
10561
10562 @Override
10563 public void onDisplayRemoved(int displayId) {
10564 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_REMOVED, displayId, 0));
10565 }
10566
10567 private void handleDisplayRemovedLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010568 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -070010569 if (displayContent != null) {
10570 mDisplayContents.delete(displayId);
10571 WindowList windows = displayContent.getWindowList();
10572 while (!windows.isEmpty()) {
10573 final WindowState win = windows.get(windows.size() - 1);
10574 removeWindowLocked(win.mSession, win);
10575 }
Craig Mautner722285e2012-09-07 13:55:58 -070010576 }
Craig Mautnera91f9e22012-09-14 16:22:08 -070010577 mAnimator.removeDisplayLocked(displayId);
Craig Mautner722285e2012-09-07 13:55:58 -070010578 }
10579
10580 @Override
10581 public void onDisplayChanged(int displayId) {
10582 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_CHANGED, displayId, 0));
10583 }
10584
10585 private void handleDisplayChangedLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010586 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner722285e2012-09-07 13:55:58 -070010587 if (displayContent != null) {
10588 displayContent.updateDisplayInfo();
10589 }
10590 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010591}