blob: ce40e73ab23d9cf1069306bde227a2baf30a6f8f [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
Cyril Mottier5f5882f2013-07-15 10:29:48 +02004882 scale = fixScale(scale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004883 switch (which) {
Cyril Mottier5f5882f2013-07-15 10:29:48 +02004884 case 0: mWindowAnimationScale = scale; break;
4885 case 1: mTransitionAnimationScale = scale; break;
4886 case 2: mAnimatorDurationScale = scale; break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004887 }
Romain Guy06882f82009-06-10 13:36:04 -07004888
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004889 // Persist setting
You Kimcb6291c2012-12-04 23:22:28 +09004890 mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004891 }
Romain Guy06882f82009-06-10 13:36:04 -07004892
Craig Mautner4b71aa12012-12-27 17:20:01 -08004893 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004894 public void setAnimationScales(float[] scales) {
4895 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4896 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004897 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004898 }
4899
4900 if (scales != null) {
4901 if (scales.length >= 1) {
4902 mWindowAnimationScale = fixScale(scales[0]);
4903 }
4904 if (scales.length >= 2) {
4905 mTransitionAnimationScale = fixScale(scales[1]);
4906 }
Chet Haasec38fa1f2012-02-01 16:37:46 -08004907 if (scales.length >= 3) {
Jeff Brownff7e6ef2012-08-15 02:05:18 -07004908 setAnimatorDurationScale(fixScale(scales[2]));
Chet Haasec38fa1f2012-02-01 16:37:46 -08004909 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004910 }
Romain Guy06882f82009-06-10 13:36:04 -07004911
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004912 // Persist setting
You Kimcb6291c2012-12-04 23:22:28 +09004913 mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004914 }
Romain Guy06882f82009-06-10 13:36:04 -07004915
Jeff Brownff7e6ef2012-08-15 02:05:18 -07004916 private void setAnimatorDurationScale(float scale) {
4917 mAnimatorDurationScale = scale;
4918 ValueAnimator.setDurationScale(scale);
4919 }
4920
Craig Mautner4b71aa12012-12-27 17:20:01 -08004921 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004922 public float getAnimationScale(int which) {
4923 switch (which) {
4924 case 0: return mWindowAnimationScale;
4925 case 1: return mTransitionAnimationScale;
Chet Haasec38fa1f2012-02-01 16:37:46 -08004926 case 2: return mAnimatorDurationScale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004927 }
4928 return 0;
4929 }
Romain Guy06882f82009-06-10 13:36:04 -07004930
Craig Mautner4b71aa12012-12-27 17:20:01 -08004931 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004932 public float[] getAnimationScales() {
Chet Haasec38fa1f2012-02-01 16:37:46 -08004933 return new float[] { mWindowAnimationScale, mTransitionAnimationScale,
4934 mAnimatorDurationScale };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004935 }
Romain Guy06882f82009-06-10 13:36:04 -07004936
Jeff Brownac143512012-04-05 18:57:33 -07004937 // Called by window manager policy. Not exposed externally.
4938 @Override
4939 public int getLidState() {
Jeff Brownc458ce92012-04-30 14:58:40 -07004940 int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY,
4941 InputManagerService.SW_LID);
Jeff Brownac143512012-04-05 18:57:33 -07004942 if (sw > 0) {
Jeff Brown27fd3422012-04-09 11:05:16 -07004943 // Switch state: AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL.
Jeff Brownac143512012-04-05 18:57:33 -07004944 return LID_CLOSED;
Jeff Brown27fd3422012-04-09 11:05:16 -07004945 } else if (sw == 0) {
4946 // Switch state: AKEY_STATE_UP.
4947 return LID_OPEN;
Jeff Brownac143512012-04-05 18:57:33 -07004948 } else {
Jeff Brown27fd3422012-04-09 11:05:16 -07004949 // Switch state: AKEY_STATE_UNKNOWN.
Jeff Brownac143512012-04-05 18:57:33 -07004950 return LID_ABSENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004951 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004952 }
Romain Guy06882f82009-06-10 13:36:04 -07004953
Jeff Brownac143512012-04-05 18:57:33 -07004954 // Called by window manager policy. Not exposed externally.
4955 @Override
Jeff Browna41ca772010-08-11 14:46:32 -07004956 public InputChannel monitorInput(String inputChannelName) {
Jeff Browna41ca772010-08-11 14:46:32 -07004957 return mInputManager.monitorInput(inputChannelName);
4958 }
4959
Jeff Brown7304c342012-05-11 18:42:42 -07004960 // Called by window manager policy. Not exposed externally.
4961 @Override
Jeff Browncf39bdf2012-05-18 14:41:19 -07004962 public void switchKeyboardLayout(int deviceId, int direction) {
4963 mInputManager.switchKeyboardLayout(deviceId, direction);
4964 }
4965
4966 // Called by window manager policy. Not exposed externally.
4967 @Override
Jeff Brown9a538ee2012-08-20 14:56:57 -07004968 public void shutdown(boolean confirm) {
4969 ShutdownThread.shutdown(mContext, confirm);
Jeff Brown7304c342012-05-11 18:42:42 -07004970 }
4971
4972 // Called by window manager policy. Not exposed externally.
4973 @Override
Jeff Brown9a538ee2012-08-20 14:56:57 -07004974 public void rebootSafeMode(boolean confirm) {
4975 ShutdownThread.rebootSafeMode(mContext, confirm);
Jeff Brown7304c342012-05-11 18:42:42 -07004976 }
4977
Craig Mautner6cfa7292013-01-15 09:05:42 -08004978 @Override
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07004979 public void setInputFilter(IInputFilter filter) {
4980 if (!checkCallingPermission(android.Manifest.permission.FILTER_EVENTS, "setInputFilter()")) {
4981 throw new SecurityException("Requires FILTER_EVENTS permission");
4982 }
Jeff Brown0029c662011-03-30 02:25:18 -07004983 mInputManager.setInputFilter(filter);
4984 }
4985
Craig Mautnerf1b67412012-09-19 13:18:29 -07004986 public void setCurrentUser(final int newUserId) {
4987 synchronized (mWindowMap) {
4988 mCurrentUserId = newUserId;
Amith Yamasani4befbec2013-07-10 16:18:01 -07004989 mAppTransition.setCurrentUser(newUserId);
Craig Mautnerf1b67412012-09-19 13:18:29 -07004990 mPolicy.setCurrentUserLw(newUserId);
Craig Mautner88400d32012-09-30 12:35:45 -07004991
4992 // Hide windows that should not be seen by the new user.
Craig Mautner7c6be102013-07-16 12:30:28 -07004993 final int numDisplays = mDisplayContents.size();
4994 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
4995 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
4996 final WindowList windows = displayContent.getWindowList();
Craig Mautner88400d32012-09-30 12:35:45 -07004997 for (int i = 0; i < windows.size(); i++) {
4998 final WindowState win = windows.get(i);
Craig Mautner5962b122012-10-05 14:45:52 -07004999 if (win.isHiddenFromUserLocked()) {
Craig Mautner88400d32012-09-30 12:35:45 -07005000 Slog.w(TAG, "current user violation " + newUserId + " hiding "
5001 + win + ", attrs=" + win.mAttrs.type + ", belonging to "
5002 + win.mOwnerUid);
5003 win.hideLw(false);
5004 }
5005 }
5006 }
5007 performLayoutAndPlaceSurfacesLocked();
Craig Mautnerf1b67412012-09-19 13:18:29 -07005008 }
5009 }
5010
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005011 public void enableScreenAfterBoot() {
5012 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005013 if (DEBUG_BOOT) {
5014 RuntimeException here = new RuntimeException("here");
5015 here.fillInStackTrace();
5016 Slog.i(TAG, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled
5017 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5018 + " mShowingBootMessages=" + mShowingBootMessages
5019 + " mSystemBooted=" + mSystemBooted, here);
5020 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005021 if (mSystemBooted) {
5022 return;
5023 }
5024 mSystemBooted = true;
Dianne Hackborn661cd522011-08-22 00:26:20 -07005025 hideBootMessagesLocked();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005026 // If the screen still doesn't come up after 30 seconds, give
5027 // up and turn it on.
You Kimcb6291c2012-12-04 23:22:28 +09005028 mH.sendEmptyMessageDelayed(H.BOOT_TIMEOUT, 30*1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005029 }
Romain Guy06882f82009-06-10 13:36:04 -07005030
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07005031 mPolicy.systemBooted();
5032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005033 performEnableScreen();
5034 }
Romain Guy06882f82009-06-10 13:36:04 -07005035
Dianne Hackborn661cd522011-08-22 00:26:20 -07005036 void enableScreenIfNeededLocked() {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005037 if (DEBUG_BOOT) {
5038 RuntimeException here = new RuntimeException("here");
5039 here.fillInStackTrace();
5040 Slog.i(TAG, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled
5041 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5042 + " mShowingBootMessages=" + mShowingBootMessages
5043 + " mSystemBooted=" + mSystemBooted, here);
5044 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005045 if (mDisplayEnabled) {
5046 return;
5047 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005048 if (!mSystemBooted && !mShowingBootMessages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005049 return;
5050 }
You Kimcb6291c2012-12-04 23:22:28 +09005051 mH.sendEmptyMessage(H.ENABLE_SCREEN);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005052 }
Romain Guy06882f82009-06-10 13:36:04 -07005053
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005054 public void performBootTimeout() {
5055 synchronized(mWindowMap) {
Mike Lockwoodd747dc82011-09-13 16:28:22 -04005056 if (mDisplayEnabled || mHeadless) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005057 return;
5058 }
5059 Slog.w(TAG, "***** BOOT TIMEOUT: forcing display enabled");
5060 mForceDisplayEnabled = true;
5061 }
5062 performEnableScreen();
5063 }
5064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005065 public void performEnableScreen() {
5066 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005067 if (DEBUG_BOOT) {
5068 RuntimeException here = new RuntimeException("here");
5069 here.fillInStackTrace();
5070 Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
5071 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5072 + " mShowingBootMessages=" + mShowingBootMessages
Jeff Brown780c46f2012-06-24 12:15:38 -07005073 + " mSystemBooted=" + mSystemBooted
5074 + " mOnlyCore=" + mOnlyCore, here);
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005075 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005076 if (mDisplayEnabled) {
5077 return;
5078 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005079 if (!mSystemBooted && !mShowingBootMessages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005080 return;
5081 }
Romain Guy06882f82009-06-10 13:36:04 -07005082
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005083 if (!mForceDisplayEnabled) {
5084 // Don't enable the screen until all existing windows
5085 // have been drawn.
5086 boolean haveBootMsg = false;
5087 boolean haveApp = false;
Justin Mattson4233f262012-04-09 18:23:16 -07005088 // if the wallpaper service is disabled on the device, we're never going to have
5089 // wallpaper, don't bother waiting for it
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005090 boolean haveWallpaper = false;
Justin Mattson4233f262012-04-09 18:23:16 -07005091 boolean wallpaperEnabled = mContext.getResources().getBoolean(
Jeff Brown780c46f2012-06-24 12:15:38 -07005092 com.android.internal.R.bool.config_enableWallpaperService)
5093 && !mOnlyCore;
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005094 boolean haveKeyguard = true;
Craig Mautner59c00972012-07-30 12:10:24 -07005095 // TODO(multidisplay): Expand to all displays?
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005096 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07005097 final int N = windows.size();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005098 for (int i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07005099 WindowState w = windows.get(i);
Craig Mautner65d11b32012-10-01 13:59:52 -07005100 if (w.mAttrs.type == TYPE_KEYGUARD) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005101 // Only if there is a keyguard attached to the window manager
5102 // will we consider ourselves as having a keyguard. If it
5103 // isn't attached, we don't know if it wants to be shown or
5104 // hidden. If it is attached, we will say we have a keyguard
5105 // if the window doesn't want to be visible, because in that
5106 // case it explicitly doesn't want to be shown so we should
5107 // not delay turning the screen on for it.
5108 boolean vis = w.mViewVisibility == View.VISIBLE
5109 && w.mPolicyVisibility;
5110 haveKeyguard = !vis;
5111 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005112 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
5113 return;
5114 }
5115 if (w.isDrawnLw()) {
Craig Mautner65d11b32012-10-01 13:59:52 -07005116 if (w.mAttrs.type == TYPE_BOOT_PROGRESS) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005117 haveBootMsg = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005118 } else if (w.mAttrs.type == TYPE_APPLICATION) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005119 haveApp = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005120 } else if (w.mAttrs.type == TYPE_WALLPAPER) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005121 haveWallpaper = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005122 } else if (w.mAttrs.type == TYPE_KEYGUARD) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005123 haveKeyguard = true;
5124 }
5125 }
5126 }
5127
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005128 if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005129 Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
5130 + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
Justin Mattson4233f262012-04-09 18:23:16 -07005131 + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled
5132 + " haveKeyguard=" + haveKeyguard);
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005133 }
5134
5135 // If we are turning on the screen to show the boot message,
5136 // don't do it until the boot message is actually displayed.
5137 if (!mSystemBooted && !haveBootMsg) {
5138 return;
5139 }
Craig Mautner312eac42012-11-13 10:56:22 -08005140
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005141 // If we are turning on the screen after the boot is completed
5142 // normally, don't do so until we have the application and
5143 // wallpaper.
Justin Mattson4233f262012-04-09 18:23:16 -07005144 if (mSystemBooted && ((!haveApp && !haveKeyguard) ||
5145 (wallpaperEnabled && !haveWallpaper))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005146 return;
5147 }
5148 }
Romain Guy06882f82009-06-10 13:36:04 -07005149
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005150 mDisplayEnabled = true;
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005151 if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005152 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005153 StringWriter sw = new StringWriter();
5154 PrintWriter pw = new PrintWriter(sw);
5155 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005156 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005157 }
5158 try {
5159 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
5160 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005161 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005162 Parcel data = Parcel.obtain();
5163 data.writeInterfaceToken("android.ui.ISurfaceComposer");
Jeff Brownc042ee22012-05-08 13:03:42 -07005164 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005165 data, null, 0);
5166 data.recycle();
5167 }
5168 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005169 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005170 }
Jeff Brown08a746a2012-06-24 12:14:49 -07005171
5172 // Enable input dispatch.
5173 mInputMonitor.setEventDispatchingLw(mEventDispatchingEnabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005174 }
Romain Guy06882f82009-06-10 13:36:04 -07005175
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005176 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07005177
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005178 // Make sure the last requested orientation has been applied.
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005179 updateRotationUnchecked(false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005180 }
Romain Guy06882f82009-06-10 13:36:04 -07005181
Dianne Hackborn661cd522011-08-22 00:26:20 -07005182 public void showBootMessage(final CharSequence msg, final boolean always) {
5183 boolean first = false;
5184 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005185 if (DEBUG_BOOT) {
5186 RuntimeException here = new RuntimeException("here");
5187 here.fillInStackTrace();
5188 Slog.i(TAG, "showBootMessage: msg=" + msg + " always=" + always
5189 + " mAllowBootMessages=" + mAllowBootMessages
5190 + " mShowingBootMessages=" + mShowingBootMessages
5191 + " mSystemBooted=" + mSystemBooted, here);
5192 }
Dianne Hackborn58f42a52011-10-10 13:46:34 -07005193 if (!mAllowBootMessages) {
5194 return;
5195 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005196 if (!mShowingBootMessages) {
5197 if (!always) {
5198 return;
5199 }
5200 first = true;
5201 }
5202 if (mSystemBooted) {
5203 return;
5204 }
5205 mShowingBootMessages = true;
5206 mPolicy.showBootMessage(msg, always);
5207 }
5208 if (first) {
5209 performEnableScreen();
5210 }
5211 }
5212
5213 public void hideBootMessagesLocked() {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005214 if (DEBUG_BOOT) {
5215 RuntimeException here = new RuntimeException("here");
5216 here.fillInStackTrace();
5217 Slog.i(TAG, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled
5218 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5219 + " mShowingBootMessages=" + mShowingBootMessages
5220 + " mSystemBooted=" + mSystemBooted, here);
5221 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005222 if (mShowingBootMessages) {
5223 mShowingBootMessages = false;
5224 mPolicy.hideBootMessages();
5225 }
5226 }
5227
Craig Mautner6cfa7292013-01-15 09:05:42 -08005228 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005229 public void setInTouchMode(boolean mode) {
5230 synchronized(mWindowMap) {
5231 mInTouchMode = mode;
5232 }
5233 }
5234
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005235 // TODO: more accounting of which pid(s) turned it on, keep count,
5236 // only allow disables from pids which have count on, etc.
Craig Mautner0447a812012-05-22 16:01:31 -07005237 @Override
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005238 public void showStrictModeViolation(boolean on) {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07005239 if (mHeadless) return;
Chris Craik3198ef32012-10-10 14:52:30 -07005240 int pid = Binder.getCallingPid();
5241 mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, on ? 1 : 0, pid));
Craig Mautner0447a812012-05-22 16:01:31 -07005242 }
Mike Lockwood3a74bd32011-08-12 13:55:22 -07005243
Chris Craik3198ef32012-10-10 14:52:30 -07005244 private void showStrictModeViolation(int arg, int pid) {
Craig Mautner0447a812012-05-22 16:01:31 -07005245 final boolean on = arg != 0;
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005246 synchronized(mWindowMap) {
5247 // Ignoring requests to enable the red border from clients
5248 // which aren't on screen. (e.g. Broadcast Receivers in
5249 // the background..)
5250 if (on) {
5251 boolean isVisible = false;
Craig Mautner7c6be102013-07-16 12:30:28 -07005252 final int numDisplays = mDisplayContents.size();
5253 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
5254 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
5255 final int numWindows = windows.size();
5256 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
5257 final WindowState ws = windows.get(winNdx);
5258 if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
5259 isVisible = true;
5260 break;
5261 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005262 }
5263 }
5264 if (!isVisible) {
5265 return;
5266 }
5267 }
5268
Dianne Hackborn36991742011-10-11 21:35:26 -07005269 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
5270 ">>> OPEN TRANSACTION showStrictModeViolation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -08005271 SurfaceControl.openTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005272 try {
Jeff Browne215f262012-09-10 16:01:14 -07005273 // TODO(multi-display): support multiple displays
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005274 if (mStrictModeFlash == null) {
Jeff Browne215f262012-09-10 16:01:14 -07005275 mStrictModeFlash = new StrictModeFlash(
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005276 getDefaultDisplayContentLocked().getDisplay(), mFxSession);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005277 }
5278 mStrictModeFlash.setVisibility(on);
5279 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -08005280 SurfaceControl.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -07005281 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
5282 "<<< CLOSE TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005283 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005284 }
5285 }
5286
Craig Mautner6cfa7292013-01-15 09:05:42 -08005287 @Override
Brad Fitzpatrickc1a968a2010-11-24 08:56:40 -08005288 public void setStrictModeVisualIndicatorPreference(String value) {
5289 SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
5290 }
5291
Jim Millere70d5062011-03-08 21:38:39 -08005292 /**
5293 * Takes a snapshot of the screen. In landscape mode this grabs the whole screen.
5294 * In portrait mode, it grabs the upper region of the screen based on the vertical dimension
5295 * of the target image.
Craig Mautner312eac42012-11-13 10:56:22 -08005296 *
Craig Mautner59c00972012-07-30 12:10:24 -07005297 * @param displayId the Display to take a screenshot of.
Jim Millere70d5062011-03-08 21:38:39 -08005298 * @param width the width of the target bitmap
5299 * @param height the height of the target bitmap
5300 */
Craig Mautner2d5618c2012-10-18 13:55:47 -07005301 @Override
Craig Mautner59c00972012-07-30 12:10:24 -07005302 public Bitmap screenshotApplications(IBinder appToken, int displayId, int width, int height) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005303 if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5304 "screenshotApplications()")) {
5305 throw new SecurityException("Requires READ_FRAME_BUFFER permission");
5306 }
5307
Craig Mautner24d887472013-03-20 15:40:36 -07005308 Bitmap rawss = null;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005309
Dianne Hackbornd2835932010-12-13 16:28:46 -08005310 int maxLayer = 0;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005311 final Rect frame = new Rect();
5312
Craig Mautner24d887472013-03-20 15:40:36 -07005313 float scale = 0;
Jim Millere70d5062011-03-08 21:38:39 -08005314 int dw, dh;
Craig Mautner24d887472013-03-20 15:40:36 -07005315 int rot = Surface.ROTATION_0;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005316
Craig Mautner24d887472013-03-20 15:40:36 -07005317 boolean screenshotReady;
5318 int minLayer;
5319 if (appToken == null) {
5320 screenshotReady = true;
5321 minLayer = 0;
5322 } else {
5323 screenshotReady = false;
5324 minLayer = Integer.MAX_VALUE;
5325 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005326
Craig Mautner24d887472013-03-20 15:40:36 -07005327 int retryCount = 0;
5328 WindowState appWin = null;
5329
5330 do {
5331 if (retryCount++ > 0) {
5332 try {
5333 Thread.sleep(100);
5334 } catch (InterruptedException e) {
5335 }
Craig Mautner2d5618c2012-10-18 13:55:47 -07005336 }
Craig Mautner24d887472013-03-20 15:40:36 -07005337 synchronized(mWindowMap) {
5338 final DisplayContent displayContent = getDisplayContentLocked(displayId);
5339 if (displayContent == null) {
5340 return null;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005341 }
Craig Mautner24d887472013-03-20 15:40:36 -07005342 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
5343 dw = displayInfo.logicalWidth;
5344 dh = displayInfo.logicalHeight;
5345
5346 int aboveAppLayer = mPolicy.windowTypeToLayerLw(TYPE_APPLICATION)
5347 * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
5348 aboveAppLayer += TYPE_LAYER_MULTIPLIER;
5349
5350 boolean isImeTarget = mInputMethodTarget != null
5351 && mInputMethodTarget.mAppToken != null
5352 && mInputMethodTarget.mAppToken.appToken != null
5353 && mInputMethodTarget.mAppToken.appToken.asBinder() == appToken;
5354
5355 // Figure out the part of the screen that is actually the app.
5356 boolean including = false;
5357 appWin = null;
5358 final WindowList windows = displayContent.getWindowList();
5359 for (int i = windows.size() - 1; i >= 0; i--) {
5360 WindowState ws = windows.get(i);
5361 if (!ws.mHasSurface) {
5362 continue;
5363 }
5364 if (ws.mLayer >= aboveAppLayer) {
5365 continue;
5366 }
5367 // When we will skip windows: when we are not including
5368 // ones behind a window we didn't skip, and we are actually
5369 // taking a screenshot of a specific app.
5370 if (!including && appToken != null) {
5371 // Also, we can possibly skip this window if it is not
5372 // an IME target or the application for the screenshot
5373 // is not the current IME target.
5374 if (!ws.mIsImWindow || !isImeTarget) {
5375 // And finally, this window is of no interest if it
5376 // is not associated with the screenshot app.
5377 if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
5378 continue;
5379 }
5380 appWin = ws;
5381 }
5382 }
5383
5384 // We keep on including windows until we go past a full-screen
5385 // window.
5386 boolean fullscreen = ws.isFullscreen(dw, dh);
5387 including = !ws.mIsImWindow && !fullscreen;
5388
5389 final WindowStateAnimator winAnim = ws.mWinAnimator;
5390 if (maxLayer < winAnim.mSurfaceLayer) {
5391 maxLayer = winAnim.mSurfaceLayer;
5392 }
Craig Mautner4238e3e2013-03-28 15:28:55 -07005393 if (minLayer > winAnim.mSurfaceLayer) {
5394 minLayer = winAnim.mSurfaceLayer;
5395 }
Craig Mautner24d887472013-03-20 15:40:36 -07005396
5397 // Don't include wallpaper in bounds calculation
5398 if (!ws.mIsWallpaper) {
5399 final Rect wf = ws.mFrame;
5400 final Rect cr = ws.mContentInsets;
5401 int left = wf.left + cr.left;
5402 int top = wf.top + cr.top;
5403 int right = wf.right - cr.right;
5404 int bottom = wf.bottom - cr.bottom;
5405 frame.union(left, top, right, bottom);
5406 }
5407
Craig Mautner4238e3e2013-03-28 15:28:55 -07005408 if (ws.mAppToken != null && ws.mAppToken.token == appToken &&
5409 ws.isDisplayedLw()) {
5410 screenshotReady = true;
5411 }
5412
5413 if (fullscreen) {
5414 // No point in continuing down through windows.
5415 break;
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005416 }
5417 }
5418
Craig Mautner24d887472013-03-20 15:40:36 -07005419 if (appToken != null && appWin == null) {
5420 // Can't find a window to snapshot.
5421 if (DEBUG_SCREENSHOT) Slog.i(TAG,
5422 "Screenshot: Couldn't find a surface matching " + appToken);
5423 return null;
5424 }
5425 if (!screenshotReady) {
5426 // Delay and hope that window gets drawn.
5427 if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot: No image ready for " + appToken
5428 + ", " + appWin + " drawState=" + appWin.mWinAnimator.mDrawState);
5429 continue;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005430 }
Craig Mautner312eac42012-11-13 10:56:22 -08005431
Craig Mautner24d887472013-03-20 15:40:36 -07005432 // Constrain frame to the screen size.
5433 frame.intersect(0, 0, dw, dh);
5434
5435 if (frame.isEmpty() || maxLayer == 0) {
5436 if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot of " + appToken
5437 + ": returning null frame=" + frame.toShortString() + " maxLayer="
5438 + maxLayer);
5439 return null;
Jim Miller2aded182011-03-08 15:32:42 -08005440 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005441
Craig Mautner24d887472013-03-20 15:40:36 -07005442 // The screenshot API does not apply the current screen rotation.
5443 rot = getDefaultDisplayContentLocked().getDisplay().getRotation();
5444 int fw = frame.width();
5445 int fh = frame.height();
Jim Millere70d5062011-03-08 21:38:39 -08005446
Craig Mautner24d887472013-03-20 15:40:36 -07005447 // Constrain thumbnail to smaller of screen width or height. Assumes aspect
5448 // of thumbnail is the same as the screen (in landscape) or square.
5449 float targetWidthScale = width / (float) fw;
5450 float targetHeightScale = height / (float) fh;
5451 if (dw <= dh) {
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005452 scale = targetWidthScale;
Craig Mautner24d887472013-03-20 15:40:36 -07005453 // If aspect of thumbnail is the same as the screen (in landscape),
5454 // select the slightly larger value so we fill the entire bitmap
5455 if (targetHeightScale > scale && (int) (targetHeightScale * fw) == width) {
5456 scale = targetHeightScale;
5457 }
5458 } else {
5459 scale = targetHeightScale;
5460 // If aspect of thumbnail is the same as the screen (in landscape),
5461 // select the slightly larger value so we fill the entire bitmap
5462 if (targetWidthScale > scale && (int) (targetWidthScale * fh) == height) {
5463 scale = targetWidthScale;
5464 }
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005465 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005466
Craig Mautner24d887472013-03-20 15:40:36 -07005467 // The screen shot will contain the entire screen.
5468 dw = (int)(dw*scale);
5469 dh = (int)(dh*scale);
5470 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
5471 int tmp = dw;
5472 dw = dh;
5473 dh = tmp;
5474 rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -07005475 }
Craig Mautner24d887472013-03-20 15:40:36 -07005476 if (DEBUG_SCREENSHOT) {
5477 Slog.i(TAG, "Screenshot: " + dw + "x" + dh + " from " + minLayer + " to "
5478 + maxLayer + " appToken=" + appToken);
5479 for (int i = 0; i < windows.size(); i++) {
5480 WindowState win = windows.get(i);
5481 Slog.i(TAG, win + ": " + win.mLayer
5482 + " animLayer=" + win.mWinAnimator.mAnimLayer
5483 + " surfaceLayer=" + win.mWinAnimator.mSurfaceLayer);
5484 }
5485 }
5486 rawss = SurfaceControl.screenshot(dw, dh, minLayer, maxLayer);
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -07005487 }
Craig Mautner24d887472013-03-20 15:40:36 -07005488 } while (!screenshotReady && retryCount <= MAX_SCREENSHOT_RETRIES);
Craig Mautner4238e3e2013-03-28 15:28:55 -07005489 if (retryCount > MAX_SCREENSHOT_RETRIES) Slog.i(TAG, "Screenshot max retries " +
5490 retryCount + " of " + appToken + " appWin=" + (appWin == null ?
5491 "null" : (appWin + " drawState=" + appWin.mWinAnimator.mDrawState)));
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005492
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005493 if (rawss == null) {
Craig Mautner4238e3e2013-03-28 15:28:55 -07005494 Slog.w(TAG, "Screenshot failure taking screenshot for (" + dw + "x" + dh
Dianne Hackborn88b03bd2010-12-16 11:15:18 -08005495 + ") to layer " + maxLayer);
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005496 return null;
5497 }
Jim Millere70d5062011-03-08 21:38:39 -08005498
5499 Bitmap bm = Bitmap.createBitmap(width, height, rawss.getConfig());
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005500 Matrix matrix = new Matrix();
5501 ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
Michael Jurka4accb6a2012-03-26 09:18:46 -07005502 matrix.postTranslate(-FloatMath.ceil(frame.left*scale), -FloatMath.ceil(frame.top*scale));
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005503 Canvas canvas = new Canvas(bm);
Dianne Hackbornca46b872013-04-17 18:06:22 -07005504 canvas.drawColor(0xFF000000);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005505 canvas.drawBitmap(rawss, matrix, null);
Dianne Hackborn6311d0a2011-08-02 16:37:58 -07005506 canvas.setBitmap(null);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005507
Craig Mautner4238e3e2013-03-28 15:28:55 -07005508 if (true || DEBUG_SCREENSHOT) {
Craig Mautner24d887472013-03-20 15:40:36 -07005509 // TEST IF IT's ALL BLACK
5510 int[] buffer = new int[bm.getWidth() * bm.getHeight()];
5511 bm.getPixels(buffer, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm.getHeight());
5512 boolean allBlack = true;
5513 for (int i = 0; i < buffer.length; i++) {
5514 if (buffer[i] != Color.BLACK) {
5515 allBlack = false;
5516 break;
5517 }
5518 }
5519 if (allBlack) {
5520 Slog.i(TAG, "Screenshot " + appWin + " was all black! mSurfaceLayer=" +
Craig Mautner4238e3e2013-03-28 15:28:55 -07005521 (appWin != null ? appWin.mWinAnimator.mSurfaceLayer : "null") +
5522 " minLayer=" + minLayer + " maxLayer=" + maxLayer);
Craig Mautner24d887472013-03-20 15:40:36 -07005523 }
5524 }
5525
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005526 rawss.recycle();
5527 return bm;
5528 }
5529
Jeff Brown01a98dd2011-09-20 15:08:29 -07005530 /**
5531 * Freeze rotation changes. (Enable "rotation lock".)
5532 * Persists across reboots.
Jeff Brown4dfce202011-10-05 12:00:10 -07005533 * @param rotation The desired rotation to freeze to, or -1 to use the
5534 * current rotation.
Jeff Brown01a98dd2011-09-20 15:08:29 -07005535 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005536 @Override
Jeff Brown4dfce202011-10-05 12:00:10 -07005537 public void freezeRotation(int rotation) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005538 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005539 "freezeRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005540 throw new SecurityException("Requires SET_ORIENTATION permission");
5541 }
Jeff Brown4dfce202011-10-05 12:00:10 -07005542 if (rotation < -1 || rotation > Surface.ROTATION_270) {
5543 throw new IllegalArgumentException("Rotation argument must be -1 or a valid "
5544 + "rotation constant.");
5545 }
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005546
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005547 if (DEBUG_ORIENTATION) Slog.v(TAG, "freezeRotation: mRotation=" + mRotation);
5548
Daniel Sandler3de830b2013-02-20 15:23:52 -05005549 long origId = Binder.clearCallingIdentity();
5550 try {
5551 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED,
5552 rotation == -1 ? mRotation : rotation);
5553 } finally {
5554 Binder.restoreCallingIdentity(origId);
5555 }
5556
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005557 updateRotationUnchecked(false, false);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005558 }
5559
Jeff Brown01a98dd2011-09-20 15:08:29 -07005560 /**
5561 * Thaw rotation changes. (Disable "rotation lock".)
5562 * Persists across reboots.
5563 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005564 @Override
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005565 public void thawRotation() {
5566 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005567 "thawRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005568 throw new SecurityException("Requires SET_ORIENTATION permission");
5569 }
5570
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005571 if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation);
5572
Daniel Sandler3de830b2013-02-20 15:23:52 -05005573 long origId = Binder.clearCallingIdentity();
5574 try {
5575 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE,
5576 777); // rot not used
5577 } finally {
5578 Binder.restoreCallingIdentity(origId);
5579 }
5580
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005581 updateRotationUnchecked(false, false);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005582 }
5583
Jeff Brown01a98dd2011-09-20 15:08:29 -07005584 /**
5585 * Recalculate the current rotation.
5586 *
5587 * Called by the window manager policy whenever the state of the system changes
5588 * such that the current rotation might need to be updated, such as when the
5589 * device is docked or rotated into a new posture.
5590 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005591 @Override
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005592 public void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
5593 updateRotationUnchecked(alwaysSendConfiguration, forceRelayout);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005594 }
5595
5596 /**
5597 * Temporarily pauses rotation changes until resumed.
5598 *
5599 * This can be used to prevent rotation changes from occurring while the user is
5600 * performing certain operations, such as drag and drop.
5601 *
Craig Mautner6cfa7292013-01-15 09:05:42 -08005602 * This call nests and must be matched by an equal number of calls to
5603 * {@link #resumeRotationLocked}.
Jeff Brown01a98dd2011-09-20 15:08:29 -07005604 */
5605 void pauseRotationLocked() {
5606 mDeferredRotationPauseCount += 1;
5607 }
5608
5609 /**
5610 * Resumes normal rotation changes after being paused.
5611 */
5612 void resumeRotationLocked() {
5613 if (mDeferredRotationPauseCount > 0) {
5614 mDeferredRotationPauseCount -= 1;
5615 if (mDeferredRotationPauseCount == 0) {
5616 boolean changed = updateRotationUncheckedLocked(false);
5617 if (changed) {
5618 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
5619 }
5620 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005621 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005622 }
Romain Guy06882f82009-06-10 13:36:04 -07005623
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005624 public void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005625 if(DEBUG_ORIENTATION) Slog.v(TAG, "updateRotationUnchecked("
5626 + "alwaysSendConfiguration=" + alwaysSendConfiguration + ")");
Romain Guy06882f82009-06-10 13:36:04 -07005627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005628 long origId = Binder.clearCallingIdentity();
5629 boolean changed;
5630 synchronized(mWindowMap) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005631 changed = updateRotationUncheckedLocked(false);
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005632 if (!changed || forceRelayout) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005633 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005634 performLayoutAndPlaceSurfacesLocked();
5635 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005636 }
Romain Guy06882f82009-06-10 13:36:04 -07005637
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005638 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005639 sendNewConfiguration();
5640 }
Romain Guy06882f82009-06-10 13:36:04 -07005641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005642 Binder.restoreCallingIdentity(origId);
5643 }
Romain Guy06882f82009-06-10 13:36:04 -07005644
Craig Mautner59c00972012-07-30 12:10:24 -07005645 // TODO(multidisplay): Rotate any display?
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005646 /**
Jeff Brown01a98dd2011-09-20 15:08:29 -07005647 * Updates the current rotation.
5648 *
5649 * Returns true if the rotation has been changed. In this case YOU
5650 * MUST CALL sendNewConfiguration() TO UNFREEZE THE SCREEN.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005651 */
Jeff Brown01a98dd2011-09-20 15:08:29 -07005652 public boolean updateRotationUncheckedLocked(boolean inTransaction) {
5653 if (mDeferredRotationPauseCount > 0) {
5654 // Rotation updates have been paused temporarily. Defer the update until
5655 // updates have been resumed.
5656 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, rotation is paused.");
Christopher Tateccd24de2011-01-12 15:02:55 -08005657 return false;
5658 }
5659
Craig Mautnera91f9e22012-09-14 16:22:08 -07005660 ScreenRotationAnimation screenRotationAnimation =
5661 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
5662 if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005663 // Rotation updates cannot be performed while the previous rotation change
5664 // animation is still in progress. Skip this update. We will try updating
5665 // again after the animation is finished and the display is unfrozen.
5666 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, animation in progress.");
5667 return false;
5668 }
5669
5670 if (!mDisplayEnabled) {
5671 // No point choosing a rotation if the display is not enabled.
5672 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, display is not enabled.");
5673 return false;
5674 }
5675
5676 // TODO: Implement forced rotation changes.
5677 // Set mAltOrientation to indicate that the application is receiving
5678 // an orientation that has different metrics than it expected.
5679 // eg. Portrait instead of Landscape.
5680
5681 int rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, mRotation);
5682 boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
5683 mForcedAppOrientation, rotation);
5684
5685 if (DEBUG_ORIENTATION) {
5686 Slog.v(TAG, "Application requested orientation "
5687 + mForcedAppOrientation + ", got rotation " + rotation
5688 + " which has " + (altOrientation ? "incompatible" : "compatible")
5689 + " metrics");
5690 }
5691
5692 if (mRotation == rotation && mAltOrientation == altOrientation) {
5693 // No change.
5694 return false;
5695 }
5696
5697 if (DEBUG_ORIENTATION) {
5698 Slog.v(TAG,
5699 "Rotation changed to " + rotation + (altOrientation ? " (alt)" : "")
5700 + " from " + mRotation + (mAltOrientation ? " (alt)" : "")
5701 + ", forceApp=" + mForcedAppOrientation);
5702 }
5703
5704 mRotation = rotation;
5705 mAltOrientation = altOrientation;
Jeff Brownc0347aa2011-09-23 17:26:09 -07005706 mPolicy.setRotationLw(mRotation);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005707
5708 mWindowsFreezingScreen = true;
5709 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
Craig Mautner0bf6ec92012-12-18 08:33:27 -08005710 mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT, WINDOW_FREEZE_TIMEOUT_DURATION);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005711 mWaitingForConfig = true;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005712 getDefaultDisplayContentLocked().layoutNeeded = true;
Craig Mautner3c174372013-02-21 17:54:37 -08005713 final int[] anim = new int[2];
5714 if (mAnimator.isDimmingLocked(Display.DEFAULT_DISPLAY)) {
5715 anim[0] = anim[1] = 0;
5716 } else {
5717 mPolicy.selectRotationAnimationLw(anim);
5718 }
5719 startFreezingDisplayLocked(inTransaction, anim[0], anim[1]);
Craig Mautnera91f9e22012-09-14 16:22:08 -07005720 // startFreezingDisplayLocked can reset the ScreenRotationAnimation.
5721 screenRotationAnimation =
5722 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005723
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08005724 // We need to update our screen size information to match the new
5725 // rotation. Note that this is redundant with the later call to
5726 // sendNewConfiguration() that must be called after this function
5727 // returns... however we need to do the screen size part of that
Jeff Brown4ed8fe72012-08-30 18:18:29 -07005728 // before then so we have the correct size to use when initializing
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08005729 // the rotation animation for the new rotation.
5730 computeScreenConfigurationLocked(null);
5731
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005732 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07005733 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07005734 if (!inTransaction) {
5735 if (SHOW_TRANSACTIONS) {
5736 Slog.i(TAG, ">>> OPEN TRANSACTION setRotationUnchecked");
5737 }
Mathias Agopian3866f0d2013-02-11 22:08:48 -08005738 SurfaceControl.openTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07005739 }
Jamie Gennise2909e12011-10-10 15:48:06 -07005740 try {
5741 // NOTE: We disable the rotation in the emulator because
5742 // it doesn't support hardware OpenGL emulation yet.
Craig Mautnera91f9e22012-09-14 16:22:08 -07005743 if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
5744 && screenRotationAnimation.hasScreenshot()) {
5745 if (screenRotationAnimation.setRotationInTransaction(
Jeff Brown4ed8fe72012-08-30 18:18:29 -07005746 rotation, mFxSession,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08005747 MAX_ANIMATION_DURATION, mTransitionAnimationScale,
Craig Mautner59c00972012-07-30 12:10:24 -07005748 displayInfo.logicalWidth, displayInfo.logicalHeight)) {
Craig Mautner96868332012-12-04 14:29:11 -08005749 scheduleAnimationLocked();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08005750 }
Jamie Gennise2909e12011-10-10 15:48:06 -07005751 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07005752
5753 mDisplayManagerService.performTraversalInTransactionFromWindowManager();
Jamie Gennise2909e12011-10-10 15:48:06 -07005754 } finally {
5755 if (!inTransaction) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -08005756 SurfaceControl.closeTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07005757 if (SHOW_LIGHT_TRANSACTIONS) {
5758 Slog.i(TAG, "<<< CLOSE TRANSACTION setRotationUnchecked");
5759 }
Jamie Gennise2909e12011-10-10 15:48:06 -07005760 }
5761 }
5762
Craig Mautner59c00972012-07-30 12:10:24 -07005763 final WindowList windows = displayContent.getWindowList();
5764 for (int i = windows.size() - 1; i >= 0; i--) {
5765 WindowState w = windows.get(i);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07005766 if (w.mHasSurface) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07005767 if (DEBUG_ORIENTATION) Slog.v(TAG, "Set mOrientationChanging of " + w);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005768 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07005769 mInnerFields.mOrientationChangeComplete = false;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005770 }
Dianne Hackborna57c6952013-03-29 14:46:40 -07005771 w.mLastFreezeDuration = 0;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005772 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07005773
Jeff Brown01a98dd2011-09-20 15:08:29 -07005774 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
5775 try {
5776 mRotationWatchers.get(i).onRotationChanged(rotation);
5777 } catch (RemoteException e) {
5778 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005779 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07005780
Svetoslav Ganov545252f2012-12-10 18:29:24 -08005781 //TODO (multidisplay): Magnification is supported only for the default display.
5782 if (mDisplayMagnifier != null
5783 && displayContent.getDisplayId() == Display.DEFAULT_DISPLAY) {
5784 mDisplayMagnifier.onRotationChangedLocked(getDefaultDisplayContentLocked(), rotation);
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07005785 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07005786
Jeff Brown01a98dd2011-09-20 15:08:29 -07005787 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005788 }
Romain Guy06882f82009-06-10 13:36:04 -07005789
Craig Mautner0bf6ec92012-12-18 08:33:27 -08005790 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005791 public int getRotation() {
5792 return mRotation;
5793 }
5794
Craig Mautner0bf6ec92012-12-18 08:33:27 -08005795 @Override
Svetoslav Ganov80943d82013-01-02 10:25:37 -08005796 public boolean isRotationFrozen() {
5797 return mPolicy.getUserRotationMode() == WindowManagerPolicy.USER_ROTATION_LOCKED;
5798 }
5799
5800 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005801 public int watchRotation(IRotationWatcher watcher) {
5802 final IBinder watcherBinder = watcher.asBinder();
5803 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
Craig Mautner0bf6ec92012-12-18 08:33:27 -08005804 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005805 public void binderDied() {
5806 synchronized (mWindowMap) {
5807 for (int i=0; i<mRotationWatchers.size(); i++) {
5808 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07005809 IRotationWatcher removed = mRotationWatchers.remove(i);
5810 if (removed != null) {
5811 removed.asBinder().unlinkToDeath(this, 0);
5812 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005813 i--;
5814 }
5815 }
5816 }
5817 }
5818 };
Romain Guy06882f82009-06-10 13:36:04 -07005819
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005820 synchronized (mWindowMap) {
5821 try {
5822 watcher.asBinder().linkToDeath(dr, 0);
5823 mRotationWatchers.add(watcher);
5824 } catch (RemoteException e) {
5825 // Client died, no cleanup needed.
5826 }
Romain Guy06882f82009-06-10 13:36:04 -07005827
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005828 return mRotation;
5829 }
5830 }
5831
Brian Colonnab1b9a8a2013-03-29 11:52:42 -04005832 @Override
5833 public void removeRotationWatcher(IRotationWatcher watcher) {
5834 final IBinder watcherBinder = watcher.asBinder();
5835 synchronized (mWindowMap) {
5836 for (int i=0; i<mRotationWatchers.size(); i++) {
5837 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
5838 mRotationWatchers.remove(i);
5839 i--;
5840 }
5841 }
5842 }
5843 }
5844
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005845 /**
Adam Powelldfee59a2011-08-05 20:48:30 -07005846 * Apps that use the compact menu panel (as controlled by the panelMenuIsCompact
5847 * theme attribute) on devices that feature a physical options menu key attempt to position
5848 * their menu panel window along the edge of the screen nearest the physical menu key.
5849 * This lowers the travel distance between invoking the menu panel and selecting
5850 * a menu option.
5851 *
5852 * This method helps control where that menu is placed. Its current implementation makes
5853 * assumptions about the menu key and its relationship to the screen based on whether
5854 * the device's natural orientation is portrait (width < height) or landscape.
5855 *
5856 * The menu key is assumed to be located along the bottom edge of natural-portrait
5857 * devices and along the right edge of natural-landscape devices. If these assumptions
5858 * do not hold for the target device, this method should be changed to reflect that.
5859 *
5860 * @return A {@link Gravity} value for placing the options menu window
5861 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005862 @Override
Adam Powelldfee59a2011-08-05 20:48:30 -07005863 public int getPreferredOptionsPanelGravity() {
5864 synchronized (mWindowMap) {
5865 final int rotation = getRotation();
5866
Craig Mautner59c00972012-07-30 12:10:24 -07005867 // TODO(multidisplay): Assume that such devices physical keys are on the main screen.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005868 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07005869 if (displayContent.mInitialDisplayWidth < displayContent.mInitialDisplayHeight) {
Adam Powelldfee59a2011-08-05 20:48:30 -07005870 // On devices with a natural orientation of portrait
5871 switch (rotation) {
5872 default:
5873 case Surface.ROTATION_0:
5874 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
5875 case Surface.ROTATION_90:
Adam Powell67ed6c72011-08-28 13:21:56 -07005876 return Gravity.RIGHT | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07005877 case Surface.ROTATION_180:
Adam Powell67ed6c72011-08-28 13:21:56 -07005878 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07005879 case Surface.ROTATION_270:
Fabrice Di Meglioaac0d4e2012-07-19 19:21:26 -07005880 return Gravity.START | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07005881 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08005882 }
5883
5884 // On devices with a natural orientation of landscape
5885 switch (rotation) {
5886 default:
5887 case Surface.ROTATION_0:
5888 return Gravity.RIGHT | Gravity.BOTTOM;
5889 case Surface.ROTATION_90:
5890 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
5891 case Surface.ROTATION_180:
5892 return Gravity.START | Gravity.BOTTOM;
5893 case Surface.ROTATION_270:
5894 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07005895 }
5896 }
5897 }
5898
5899 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005900 * Starts the view server on the specified port.
5901 *
5902 * @param port The port to listener to.
5903 *
5904 * @return True if the server was successfully started, false otherwise.
5905 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08005906 * @see com.android.server.wm.ViewServer
5907 * @see com.android.server.wm.ViewServer#VIEW_SERVER_DEFAULT_PORT
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005908 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005909 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005910 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07005911 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005912 return false;
5913 }
5914
5915 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
5916 return false;
5917 }
5918
5919 if (port < 1024) {
5920 return false;
5921 }
5922
5923 if (mViewServer != null) {
5924 if (!mViewServer.isRunning()) {
5925 try {
5926 return mViewServer.start();
5927 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005928 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005929 }
5930 }
5931 return false;
5932 }
5933
5934 try {
5935 mViewServer = new ViewServer(this, port);
5936 return mViewServer.start();
5937 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005938 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005939 }
5940 return false;
5941 }
5942
Romain Guy06882f82009-06-10 13:36:04 -07005943 private boolean isSystemSecure() {
5944 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
5945 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5946 }
5947
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005948 /**
5949 * Stops the view server if it exists.
5950 *
5951 * @return True if the server stopped, false if it wasn't started or
5952 * couldn't be stopped.
5953 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08005954 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005955 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005956 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005957 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07005958 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005959 return false;
5960 }
5961
5962 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
5963 return false;
5964 }
5965
5966 if (mViewServer != null) {
5967 return mViewServer.stop();
5968 }
5969 return false;
5970 }
5971
5972 /**
5973 * Indicates whether the view server is running.
5974 *
5975 * @return True if the server is running, false otherwise.
5976 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08005977 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005978 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005979 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005980 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07005981 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005982 return false;
5983 }
5984
5985 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
5986 return false;
5987 }
5988
5989 return mViewServer != null && mViewServer.isRunning();
5990 }
5991
5992 /**
5993 * Lists all availble windows in the system. The listing is written in the
5994 * specified Socket's output stream with the following syntax:
5995 * windowHashCodeInHexadecimal windowName
5996 * Each line of the ouput represents a different window.
5997 *
5998 * @param client The remote client to send the listing to.
5999 * @return False if an error occured, true otherwise.
6000 */
6001 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07006002 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006003 return false;
6004 }
6005
6006 boolean result = true;
6007
Craig Mautner59c00972012-07-30 12:10:24 -07006008 WindowList windows = new WindowList();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006009 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006010 //noinspection unchecked
Craig Mautner7c6be102013-07-16 12:30:28 -07006011 final int numDisplays = mDisplayContents.size();
6012 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
6013 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
6014 windows.addAll(displayContent.getWindowList());
Craig Mautner59c00972012-07-30 12:10:24 -07006015 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006016 }
6017
6018 BufferedWriter out = null;
6019
6020 // Any uncaught exception will crash the system process
6021 try {
6022 OutputStream clientStream = client.getOutputStream();
6023 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
6024
Craig Mautner59c00972012-07-30 12:10:24 -07006025 final int count = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006026 for (int i = 0; i < count; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07006027 final WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006028 out.write(Integer.toHexString(System.identityHashCode(w)));
6029 out.write(' ');
6030 out.append(w.mAttrs.getTitle());
6031 out.write('\n');
6032 }
6033
6034 out.write("DONE.\n");
6035 out.flush();
6036 } catch (Exception e) {
6037 result = false;
6038 } finally {
6039 if (out != null) {
6040 try {
6041 out.close();
6042 } catch (IOException e) {
6043 result = false;
6044 }
6045 }
6046 }
6047
6048 return result;
6049 }
6050
Craig Mautner59c00972012-07-30 12:10:24 -07006051 // TODO(multidisplay): Extend to multiple displays.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006052 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07006053 * Returns the focused window in the following format:
6054 * windowHashCodeInHexadecimal windowName
6055 *
6056 * @param client The remote client to send the listing to.
6057 * @return False if an error occurred, true otherwise.
6058 */
6059 boolean viewServerGetFocusedWindow(Socket client) {
6060 if (isSystemSecure()) {
6061 return false;
6062 }
6063
6064 boolean result = true;
6065
6066 WindowState focusedWindow = getFocusedWindow();
6067
6068 BufferedWriter out = null;
6069
6070 // Any uncaught exception will crash the system process
6071 try {
6072 OutputStream clientStream = client.getOutputStream();
6073 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
6074
6075 if(focusedWindow != null) {
6076 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
6077 out.write(' ');
6078 out.append(focusedWindow.mAttrs.getTitle());
6079 }
6080 out.write('\n');
6081 out.flush();
6082 } catch (Exception e) {
6083 result = false;
6084 } finally {
6085 if (out != null) {
6086 try {
6087 out.close();
6088 } catch (IOException e) {
6089 result = false;
6090 }
6091 }
6092 }
6093
6094 return result;
6095 }
6096
6097 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006098 * Sends a command to a target window. The result of the command, if any, will be
6099 * written in the output stream of the specified socket.
6100 *
6101 * The parameters must follow this syntax:
6102 * windowHashcode extra
6103 *
6104 * Where XX is the length in characeters of the windowTitle.
6105 *
6106 * The first parameter is the target window. The window with the specified hashcode
6107 * will be the target. If no target can be found, nothing happens. The extra parameters
6108 * will be delivered to the target window and as parameters to the command itself.
6109 *
6110 * @param client The remote client to sent the result, if any, to.
6111 * @param command The command to execute.
6112 * @param parameters The command parameters.
6113 *
6114 * @return True if the command was successfully delivered, false otherwise. This does
6115 * not indicate whether the command itself was successful.
6116 */
6117 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07006118 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006119 return false;
6120 }
6121
6122 boolean success = true;
6123 Parcel data = null;
6124 Parcel reply = null;
6125
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006126 BufferedWriter out = null;
6127
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006128 // Any uncaught exception will crash the system process
6129 try {
6130 // Find the hashcode of the window
6131 int index = parameters.indexOf(' ');
6132 if (index == -1) {
6133 index = parameters.length();
6134 }
6135 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08006136 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006137
6138 // Extract the command's parameter after the window description
6139 if (index < parameters.length()) {
6140 parameters = parameters.substring(index + 1);
6141 } else {
6142 parameters = "";
6143 }
6144
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006145 final WindowState window = findWindow(hashCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006146 if (window == null) {
6147 return false;
6148 }
6149
6150 data = Parcel.obtain();
6151 data.writeInterfaceToken("android.view.IWindow");
6152 data.writeString(command);
6153 data.writeString(parameters);
6154 data.writeInt(1);
6155 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
6156
6157 reply = Parcel.obtain();
6158
6159 final IBinder binder = window.mClient.asBinder();
6160 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
6161 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
6162
6163 reply.readException();
6164
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006165 if (!client.isOutputShutdown()) {
6166 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
6167 out.write("DONE\n");
6168 out.flush();
6169 }
6170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006171 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006172 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006173 success = false;
6174 } finally {
6175 if (data != null) {
6176 data.recycle();
6177 }
6178 if (reply != null) {
6179 reply.recycle();
6180 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006181 if (out != null) {
6182 try {
6183 out.close();
6184 } catch (IOException e) {
6185
6186 }
6187 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006188 }
6189
6190 return success;
6191 }
6192
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07006193 public void addWindowChangeListener(WindowChangeListener listener) {
6194 synchronized(mWindowMap) {
6195 mWindowChangeListeners.add(listener);
6196 }
6197 }
6198
6199 public void removeWindowChangeListener(WindowChangeListener listener) {
6200 synchronized(mWindowMap) {
6201 mWindowChangeListeners.remove(listener);
6202 }
6203 }
6204
6205 private void notifyWindowsChanged() {
6206 WindowChangeListener[] windowChangeListeners;
6207 synchronized(mWindowMap) {
6208 if(mWindowChangeListeners.isEmpty()) {
6209 return;
6210 }
6211 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
6212 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
6213 }
6214 int N = windowChangeListeners.length;
6215 for(int i = 0; i < N; i++) {
6216 windowChangeListeners[i].windowsChanged();
6217 }
6218 }
6219
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07006220 private void notifyFocusChanged() {
6221 WindowChangeListener[] windowChangeListeners;
6222 synchronized(mWindowMap) {
6223 if(mWindowChangeListeners.isEmpty()) {
6224 return;
6225 }
6226 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
6227 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
6228 }
6229 int N = windowChangeListeners.length;
6230 for(int i = 0; i < N; i++) {
6231 windowChangeListeners[i].focusChanged();
6232 }
6233 }
6234
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006235 private WindowState findWindow(int hashCode) {
6236 if (hashCode == -1) {
Craig Mautner59c00972012-07-30 12:10:24 -07006237 // TODO(multidisplay): Extend to multiple displays.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006238 return getFocusedWindow();
6239 }
6240
6241 synchronized (mWindowMap) {
Craig Mautner7c6be102013-07-16 12:30:28 -07006242 final int numDisplays = mDisplayContents.size();
6243 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
6244 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
6245 final int numWindows = windows.size();
6246 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
6247 final WindowState w = windows.get(winNdx);
6248 if (System.identityHashCode(w) == hashCode) {
6249 return w;
6250 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006251 }
6252 }
6253 }
6254
6255 return null;
6256 }
6257
6258 /*
6259 * Instruct the Activity Manager to fetch the current configuration and broadcast
6260 * that to config-changed listeners if appropriate.
6261 */
6262 void sendNewConfiguration() {
6263 try {
6264 mActivityManager.updateConfiguration(null);
6265 } catch (RemoteException e) {
6266 }
6267 }
Romain Guy06882f82009-06-10 13:36:04 -07006268
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006269 public Configuration computeNewConfiguration() {
6270 synchronized (mWindowMap) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006271 Configuration config = computeNewConfigurationLocked();
6272 if (config == null && mWaitingForConfig) {
6273 // Nothing changed but we are waiting for something... stop that!
6274 mWaitingForConfig = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07006275 mLastFinishedFreezeSource = "new-config";
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006276 performLayoutAndPlaceSurfacesLocked();
6277 }
6278 return config;
Dianne Hackbornc485a602009-03-24 22:39:49 -07006279 }
6280 }
Romain Guy06882f82009-06-10 13:36:04 -07006281
Dianne Hackbornc485a602009-03-24 22:39:49 -07006282 Configuration computeNewConfigurationLocked() {
6283 Configuration config = new Configuration();
Dianne Hackborn09e5b9d2011-10-04 16:32:01 -07006284 config.fontScale = 0;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006285 if (!computeScreenConfigurationLocked(config)) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07006286 return null;
6287 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07006288 return config;
6289 }
Romain Guy06882f82009-06-10 13:36:04 -07006290
Craig Mautner59c00972012-07-30 12:10:24 -07006291 private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation, int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006292 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006293 final int width = mPolicy.getConfigDisplayWidth(dw, dh, rotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006294 if (width < displayInfo.smallestNominalAppWidth) {
6295 displayInfo.smallestNominalAppWidth = width;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006296 }
Craig Mautner59c00972012-07-30 12:10:24 -07006297 if (width > displayInfo.largestNominalAppWidth) {
6298 displayInfo.largestNominalAppWidth = width;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006299 }
6300 final int height = mPolicy.getConfigDisplayHeight(dw, dh, rotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006301 if (height < displayInfo.smallestNominalAppHeight) {
6302 displayInfo.smallestNominalAppHeight = height;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006303 }
Craig Mautner59c00972012-07-30 12:10:24 -07006304 if (height > displayInfo.largestNominalAppHeight) {
6305 displayInfo.largestNominalAppHeight = height;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006306 }
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006307 }
6308
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006309 private int reduceConfigLayout(int curLayout, int rotation, float density,
6310 int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006311 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006312 // Get the app screen size at this rotation.
6313 int w = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
6314 int h = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
6315
6316 // Compute the screen layout size class for this rotation.
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006317 int longSize = w;
6318 int shortSize = h;
6319 if (longSize < shortSize) {
6320 int tmp = longSize;
6321 longSize = shortSize;
6322 shortSize = tmp;
6323 }
6324 longSize = (int)(longSize/density);
6325 shortSize = (int)(shortSize/density);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006326 return Configuration.reduceScreenLayout(curLayout, longSize, shortSize);
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006327 }
6328
Craig Mautner59c00972012-07-30 12:10:24 -07006329 private void computeSizeRangesAndScreenLayout(DisplayInfo displayInfo, boolean rotated,
6330 int dw, int dh, float density, Configuration outConfig) {
Craig Mautner69b08182012-09-05 13:07:13 -07006331 // TODO: Multidisplay: for now only use with default display.
6332
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006333 // We need to determine the smallest width that will occur under normal
6334 // operation. To this, start with the base screen size and compute the
6335 // width under the different possible rotations. We need to un-rotate
6336 // the current screen dimensions before doing this.
6337 int unrotDw, unrotDh;
6338 if (rotated) {
6339 unrotDw = dh;
6340 unrotDh = dw;
6341 } else {
6342 unrotDw = dw;
6343 unrotDh = dh;
6344 }
Craig Mautner59c00972012-07-30 12:10:24 -07006345 displayInfo.smallestNominalAppWidth = 1<<30;
6346 displayInfo.smallestNominalAppHeight = 1<<30;
6347 displayInfo.largestNominalAppWidth = 0;
6348 displayInfo.largestNominalAppHeight = 0;
6349 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, unrotDw, unrotDh);
6350 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, unrotDh, unrotDw);
6351 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, unrotDw, unrotDh);
6352 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, unrotDh, unrotDw);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006353 int sl = Configuration.resetScreenLayout(outConfig.screenLayout);
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006354 sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh);
6355 sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw);
6356 sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh);
6357 sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw);
Craig Mautner59c00972012-07-30 12:10:24 -07006358 outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006359 outConfig.screenLayout = sl;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006360 }
6361
Dianne Hackborn48a76512011-06-08 21:51:44 -07006362 private int reduceCompatConfigWidthSize(int curSize, int rotation, DisplayMetrics dm,
6363 int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006364 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn1f903c32011-09-13 19:18:06 -07006365 dm.noncompatWidthPixels = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
6366 dm.noncompatHeightPixels = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006367 float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
Dianne Hackborn2b31d532011-06-23 11:58:50 -07006368 int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006369 if (curSize == 0 || size < curSize) {
6370 curSize = size;
6371 }
6372 return curSize;
6373 }
6374
6375 private int computeCompatSmallestWidth(boolean rotated, DisplayMetrics dm, int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006376 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn48a76512011-06-08 21:51:44 -07006377 mTmpDisplayMetrics.setTo(dm);
Craig Mautner69b08182012-09-05 13:07:13 -07006378 final DisplayMetrics tmpDm = mTmpDisplayMetrics;
6379 final int unrotDw, unrotDh;
Dianne Hackborn48a76512011-06-08 21:51:44 -07006380 if (rotated) {
6381 unrotDw = dh;
6382 unrotDh = dw;
6383 } else {
6384 unrotDw = dw;
6385 unrotDh = dh;
6386 }
Craig Mautner69b08182012-09-05 13:07:13 -07006387 int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, tmpDm, unrotDw, unrotDh);
6388 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, tmpDm, unrotDh, unrotDw);
6389 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, tmpDm, unrotDw, unrotDh);
6390 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, tmpDm, unrotDh, unrotDw);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006391 return sw;
6392 }
6393
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006394 boolean computeScreenConfigurationLocked(Configuration config) {
Jeff Browne215f262012-09-10 16:01:14 -07006395 if (!mDisplayReady) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07006396 return false;
6397 }
Christopher Tateb696aee2010-04-02 19:08:30 -07006398
Craig Mautner59c00972012-07-30 12:10:24 -07006399 // TODO(multidisplay): For now, apply Configuration to main screen only.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006400 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07006401
Christopher Tateb696aee2010-04-02 19:08:30 -07006402 // Use the effective "visual" dimensions based on current rotation
6403 final boolean rotated = (mRotation == Surface.ROTATION_90
6404 || mRotation == Surface.ROTATION_270);
Craig Mautner59c00972012-07-30 12:10:24 -07006405 final int realdw = rotated ?
6406 displayContent.mBaseDisplayHeight : displayContent.mBaseDisplayWidth;
6407 final int realdh = rotated ?
6408 displayContent.mBaseDisplayWidth : displayContent.mBaseDisplayHeight;
Jeff Brownfa25bf52012-07-23 19:26:30 -07006409 int dw = realdw;
6410 int dh = realdh;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006411
Jeff Brownfa25bf52012-07-23 19:26:30 -07006412 if (mAltOrientation) {
6413 if (realdw > realdh) {
6414 // Turn landscape into portrait.
6415 int maxw = (int)(realdh/1.3f);
6416 if (maxw < realdw) {
6417 dw = maxw;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006418 }
6419 } else {
Jeff Brownfa25bf52012-07-23 19:26:30 -07006420 // Turn portrait into landscape.
6421 int maxh = (int)(realdw/1.3f);
6422 if (maxh < realdh) {
6423 dh = maxh;
6424 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006425 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006426 }
6427
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006428 if (config != null) {
Jeff Browne215f262012-09-10 16:01:14 -07006429 config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
6430 Configuration.ORIENTATION_LANDSCAPE;
Dianne Hackbornc485a602009-03-24 22:39:49 -07006431 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006432
Jeff Brownbc68a592011-07-25 12:58:12 -07006433 // Update application display metrics.
Dianne Hackborn1fbee792011-11-30 11:29:58 -08006434 final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation);
6435 final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006436 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
6437 synchronized(displayContent.mDisplaySizeLock) {
6438 displayInfo.rotation = mRotation;
6439 displayInfo.logicalWidth = dw;
6440 displayInfo.logicalHeight = dh;
Dianne Hackborndde331c2012-08-03 14:01:57 -07006441 displayInfo.logicalDensityDpi = displayContent.mBaseDisplayDensity;
Craig Mautner59c00972012-07-30 12:10:24 -07006442 displayInfo.appWidth = appWidth;
6443 displayInfo.appHeight = appHeight;
6444 displayInfo.getLogicalMetrics(mRealDisplayMetrics, null);
6445 displayInfo.getAppMetrics(mDisplayMetrics, null);
Jeff Brownbd6e1502012-08-28 03:27:37 -07006446 mDisplayManagerService.setDisplayInfoOverrideFromWindowManager(
6447 displayContent.getDisplayId(), displayInfo);
Dianne Hackborn1fbee792011-11-30 11:29:58 -08006448 }
Dianne Hackborn36991742011-10-11 21:35:26 -07006449 if (false) {
Jeff Brownfa25bf52012-07-23 19:26:30 -07006450 Slog.i(TAG, "Set app display size: " + appWidth + " x " + appHeight);
Dianne Hackborn36991742011-10-11 21:35:26 -07006451 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006452
Jeff Brownfa25bf52012-07-23 19:26:30 -07006453 final DisplayMetrics dm = mDisplayMetrics;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006454 mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm,
6455 mCompatDisplayMetrics);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006456
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006457 if (config != null) {
6458 config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation)
6459 / dm.density);
6460 config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation)
6461 / dm.density);
Craig Mautner59c00972012-07-30 12:10:24 -07006462 computeSizeRangesAndScreenLayout(displayInfo, rotated, dw, dh, dm.density, config);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006463
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006464 config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
6465 config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
6466 config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dm, dw, dh);
Dianne Hackborndde331c2012-08-03 14:01:57 -07006467 config.densityDpi = displayContent.mBaseDisplayDensity;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006468
Jeff Browndaa37532012-05-01 15:54:03 -07006469 // Update the configuration based on available input devices, lid switch,
6470 // and platform configuration.
6471 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
6472 config.keyboard = Configuration.KEYBOARD_NOKEYS;
6473 config.navigation = Configuration.NAVIGATION_NONAV;
6474
6475 int keyboardPresence = 0;
6476 int navigationPresence = 0;
Craig Mautner1d961d42012-05-27 12:02:11 -07006477 final InputDevice[] devices = mInputManager.getInputDevices();
6478 final int len = devices.length;
6479 for (int i = 0; i < len; i++) {
6480 InputDevice device = devices[i];
Jeff Browndaa37532012-05-01 15:54:03 -07006481 if (!device.isVirtual()) {
6482 final int sources = device.getSources();
6483 final int presenceFlag = device.isExternal() ?
6484 WindowManagerPolicy.PRESENCE_EXTERNAL :
6485 WindowManagerPolicy.PRESENCE_INTERNAL;
6486
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -07006487 if (mIsTouchDevice) {
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006488 if ((sources & InputDevice.SOURCE_TOUCHSCREEN) ==
6489 InputDevice.SOURCE_TOUCHSCREEN) {
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -07006490 config.touchscreen = Configuration.TOUCHSCREEN_FINGER;
6491 }
6492 } else {
6493 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
Jeff Browndaa37532012-05-01 15:54:03 -07006494 }
6495
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006496 if ((sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) {
Jeff Browndaa37532012-05-01 15:54:03 -07006497 config.navigation = Configuration.NAVIGATION_TRACKBALL;
6498 navigationPresence |= presenceFlag;
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006499 } else if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD
Jeff Browndaa37532012-05-01 15:54:03 -07006500 && config.navigation == Configuration.NAVIGATION_NONAV) {
6501 config.navigation = Configuration.NAVIGATION_DPAD;
6502 navigationPresence |= presenceFlag;
6503 }
6504
6505 if (device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) {
6506 config.keyboard = Configuration.KEYBOARD_QWERTY;
6507 keyboardPresence |= presenceFlag;
6508 }
6509 }
6510 }
6511
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006512 // Determine whether a hard keyboard is available and enabled.
6513 boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
6514 if (hardKeyboardAvailable != mHardKeyboardAvailable) {
6515 mHardKeyboardAvailable = hardKeyboardAvailable;
6516 mHardKeyboardEnabled = hardKeyboardAvailable;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006517 mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
6518 mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
6519 }
6520 if (!mHardKeyboardEnabled) {
6521 config.keyboard = Configuration.KEYBOARD_NOKEYS;
6522 }
6523
Jeff Browndaa37532012-05-01 15:54:03 -07006524 // Let the policy update hidden states.
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006525 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
6526 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
6527 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO;
Jeff Browndaa37532012-05-01 15:54:03 -07006528 mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence);
Jeff Brown2992ea72011-01-28 22:04:14 -08006529 }
Jeff Brown597eec82011-01-31 17:12:25 -08006530
Dianne Hackbornc485a602009-03-24 22:39:49 -07006531 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006532 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006533
Jeff Brown2992ea72011-01-28 22:04:14 -08006534 public boolean isHardKeyboardAvailable() {
6535 synchronized (mWindowMap) {
6536 return mHardKeyboardAvailable;
6537 }
6538 }
6539
6540 public boolean isHardKeyboardEnabled() {
6541 synchronized (mWindowMap) {
6542 return mHardKeyboardEnabled;
6543 }
6544 }
6545
6546 public void setHardKeyboardEnabled(boolean enabled) {
6547 synchronized (mWindowMap) {
6548 if (mHardKeyboardEnabled != enabled) {
6549 mHardKeyboardEnabled = enabled;
6550 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
6551 }
6552 }
6553 }
6554
6555 public void setOnHardKeyboardStatusChangeListener(
6556 OnHardKeyboardStatusChangeListener listener) {
6557 synchronized (mWindowMap) {
6558 mHardKeyboardStatusChangeListener = listener;
6559 }
6560 }
6561
6562 void notifyHardKeyboardStatusChange() {
6563 final boolean available, enabled;
6564 final OnHardKeyboardStatusChangeListener listener;
6565 synchronized (mWindowMap) {
6566 listener = mHardKeyboardStatusChangeListener;
6567 available = mHardKeyboardAvailable;
6568 enabled = mHardKeyboardEnabled;
6569 }
6570 if (listener != null) {
6571 listener.onHardKeyboardStatusChange(available, enabled);
6572 }
6573 }
6574
Christopher Tatea53146c2010-09-07 11:57:52 -07006575 // -------------------------------------------------------------
6576 // Drag and drop
6577 // -------------------------------------------------------------
6578
6579 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006580 int flags, int width, int height, Surface outSurface) {
Christopher Tatea53146c2010-09-07 11:57:52 -07006581 if (DEBUG_DRAG) {
6582 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006583 + " flags=" + Integer.toHexString(flags) + " win=" + window
Christopher Tatea53146c2010-09-07 11:57:52 -07006584 + " asbinder=" + window.asBinder());
6585 }
6586
6587 final int callerPid = Binder.getCallingPid();
6588 final long origId = Binder.clearCallingIdentity();
6589 IBinder token = null;
6590
6591 try {
6592 synchronized (mWindowMap) {
6593 try {
Christopher Tatea53146c2010-09-07 11:57:52 -07006594 if (mDragState == null) {
Jeff Browne215f262012-09-10 16:01:14 -07006595 // TODO(multi-display): support other displays
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006596 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07006597 final Display display = displayContent.getDisplay();
Mathias Agopian3866f0d2013-02-11 22:08:48 -08006598 SurfaceControl surface = new SurfaceControl(session, "drag surface",
6599 width, height, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
Jeff Browne215f262012-09-10 16:01:14 -07006600 surface.setLayerStack(display.getLayerStack());
Dianne Hackbornac1471a2011-02-03 13:46:06 -08006601 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DRAG "
6602 + surface + ": CREATE");
Christopher Tatea53146c2010-09-07 11:57:52 -07006603 outSurface.copyFrom(surface);
Chris Tate7b362e42010-11-04 16:02:52 -07006604 final IBinder winBinder = window.asBinder();
Christopher Tatea53146c2010-09-07 11:57:52 -07006605 token = new Binder();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006606 mDragState = new DragState(this, token, surface, /*flags*/ 0, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07006607 token = mDragState.mToken = new Binder();
6608
6609 // 5 second timeout for this window to actually begin the drag
Chris Tate7b362e42010-11-04 16:02:52 -07006610 mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
6611 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07006612 mH.sendMessageDelayed(msg, 5000);
6613 } else {
6614 Slog.w(TAG, "Drag already in progress");
6615 }
Mathias Agopian3866f0d2013-02-11 22:08:48 -08006616 } catch (SurfaceControl.OutOfResourcesException e) {
Christopher Tatea53146c2010-09-07 11:57:52 -07006617 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
6618 if (mDragState != null) {
6619 mDragState.reset();
6620 mDragState = null;
6621 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006622 }
6623 }
6624 } finally {
6625 Binder.restoreCallingIdentity(origId);
6626 }
6627
6628 return token;
6629 }
6630
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006631 // -------------------------------------------------------------
6632 // Input Events and Focus Management
6633 // -------------------------------------------------------------
Craig Mautner6cfa7292013-01-15 09:05:42 -08006634
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006635 final InputMonitor mInputMonitor = new InputMonitor(this);
Jeff Brown08a746a2012-06-24 12:14:49 -07006636 private boolean mEventDispatchingEnabled;
6637
Craig Mautner6cfa7292013-01-15 09:05:42 -08006638 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006639 public void pauseKeyDispatching(IBinder _token) {
6640 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6641 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006642 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006643 }
6644
6645 synchronized (mWindowMap) {
6646 WindowToken token = mTokenMap.get(_token);
6647 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006648 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006649 }
6650 }
6651 }
6652
Craig Mautner6cfa7292013-01-15 09:05:42 -08006653 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006654 public void resumeKeyDispatching(IBinder _token) {
6655 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6656 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006657 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006658 }
6659
6660 synchronized (mWindowMap) {
6661 WindowToken token = mTokenMap.get(_token);
6662 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006663 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006664 }
6665 }
6666 }
6667
Craig Mautner6cfa7292013-01-15 09:05:42 -08006668 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006669 public void setEventDispatching(boolean enabled) {
6670 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner3d7b7d52012-05-24 11:28:26 -07006671 "setEventDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006672 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006673 }
6674
6675 synchronized (mWindowMap) {
Jeff Brown08a746a2012-06-24 12:14:49 -07006676 mEventDispatchingEnabled = enabled;
6677 if (mDisplayEnabled) {
6678 mInputMonitor.setEventDispatchingLw(enabled);
6679 }
Craig Mautner3d7b7d52012-05-24 11:28:26 -07006680 sendScreenStatusToClientsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006681 }
6682 }
Romain Guy06882f82009-06-10 13:36:04 -07006683
Craig Mautner6cfa7292013-01-15 09:05:42 -08006684 @Override
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07006685 public IBinder getFocusedWindowToken() {
6686 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
6687 "getFocusedWindowToken()")) {
6688 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
6689 }
Svetoslav Ganove15ccb92012-05-16 15:48:55 -07006690 synchronized (mWindowMap) {
6691 WindowState windowState = getFocusedWindowLocked();
6692 if (windowState != null) {
6693 return windowState.mClient.asBinder();
6694 }
6695 return null;
6696 }
6697 }
6698
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006699 private WindowState getFocusedWindow() {
6700 synchronized (mWindowMap) {
6701 return getFocusedWindowLocked();
6702 }
6703 }
6704
6705 private WindowState getFocusedWindowLocked() {
6706 return mCurrentFocus;
6707 }
Romain Guy06882f82009-06-10 13:36:04 -07006708
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006709 public boolean detectSafeMode() {
Jeff Brownb09abc12011-01-13 21:08:27 -08006710 if (!mInputMonitor.waitForInputDevicesReady(
6711 INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
6712 Slog.w(TAG, "Devices still not ready after waiting "
Jeff Brownac143512012-04-05 18:57:33 -07006713 + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
6714 + " milliseconds before attempting to detect safe mode.");
Jeff Brownb09abc12011-01-13 21:08:27 -08006715 }
6716
Jeff Brownac143512012-04-05 18:57:33 -07006717 int menuState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
6718 KeyEvent.KEYCODE_MENU);
6719 int sState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, KeyEvent.KEYCODE_S);
6720 int dpadState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD,
6721 KeyEvent.KEYCODE_DPAD_CENTER);
6722 int trackballState = mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL,
Jeff Brownc458ce92012-04-30 14:58:40 -07006723 InputManagerService.BTN_MOUSE);
Jeff Brownac143512012-04-05 18:57:33 -07006724 int volumeDownState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
6725 KeyEvent.KEYCODE_VOLUME_DOWN);
6726 mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
6727 || volumeDownState > 0;
Dianne Hackborn19caadc2012-04-20 17:49:10 -07006728 try {
6729 if (SystemProperties.getInt(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, 0) != 0) {
6730 mSafeMode = true;
6731 SystemProperties.set(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, "");
6732 }
6733 } catch (IllegalArgumentException e) {
6734 }
Jeff Brownac143512012-04-05 18:57:33 -07006735 if (mSafeMode) {
6736 Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
6737 + " dpad=" + dpadState + " trackball=" + trackballState + ")");
6738 } else {
6739 Log.i(TAG, "SAFE MODE not enabled");
6740 }
6741 mPolicy.setSafeMode(mSafeMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006742 return mSafeMode;
6743 }
Romain Guy06882f82009-06-10 13:36:04 -07006744
Dianne Hackborn661cd522011-08-22 00:26:20 -07006745 public void displayReady() {
Jeff Browne215f262012-09-10 16:01:14 -07006746 displayReady(Display.DEFAULT_DISPLAY);
Craig Mautner4f67ba62012-08-02 11:23:00 -07006747
6748 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006749 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07006750 readForcedDisplaySizeAndDensityLocked(displayContent);
Dianne Hackborn5a052a42012-08-15 18:49:23 -07006751
Jeff Browne215f262012-09-10 16:01:14 -07006752 mDisplayReady = true;
Craig Mautner4f67ba62012-08-02 11:23:00 -07006753 mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
Jeff Browne215f262012-09-10 16:01:14 -07006754 PackageManager.FEATURE_TOUCHSCREEN);
Craig Mautner4f67ba62012-08-02 11:23:00 -07006755
Jeff Browne215f262012-09-10 16:01:14 -07006756 mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
6757 displayContent.mInitialDisplayWidth,
6758 displayContent.mInitialDisplayHeight,
6759 displayContent.mInitialDisplayDensity);
Craig Mautner4f67ba62012-08-02 11:23:00 -07006760 }
Dianne Hackborn5a052a42012-08-15 18:49:23 -07006761
6762 try {
6763 mActivityManager.updateConfiguration(null);
6764 } catch (RemoteException e) {
6765 }
Craig Mautner59c00972012-07-30 12:10:24 -07006766 }
6767
Craig Mautner2d5618c2012-10-18 13:55:47 -07006768 private void displayReady(int displayId) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07006769 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006770 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07006771 if (displayContent != null) {
6772 mAnimator.addDisplayLocked(displayId);
6773 synchronized(displayContent.mDisplaySizeLock) {
6774 // Bootstrap the default logical display from the display manager.
6775 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
6776 DisplayInfo newDisplayInfo = mDisplayManagerService.getDisplayInfo(displayId);
6777 if (newDisplayInfo != null) {
6778 displayInfo.copyFrom(newDisplayInfo);
6779 }
6780 displayContent.mInitialDisplayWidth = displayInfo.logicalWidth;
6781 displayContent.mInitialDisplayHeight = displayInfo.logicalHeight;
6782 displayContent.mInitialDisplayDensity = displayInfo.logicalDensityDpi;
6783 displayContent.mBaseDisplayWidth = displayContent.mInitialDisplayWidth;
6784 displayContent.mBaseDisplayHeight = displayContent.mInitialDisplayHeight;
6785 displayContent.mBaseDisplayDensity = displayContent.mInitialDisplayDensity;
Jeff Brownbd6e1502012-08-28 03:27:37 -07006786 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07006787 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07006788 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07006789 }
6790
Dianne Hackborn661cd522011-08-22 00:26:20 -07006791 public void systemReady() {
6792 mPolicy.systemReady();
6793 }
6794
Craig Mautner59c00972012-07-30 12:10:24 -07006795 // TODO(multidisplay): Call isScreenOn for each display.
Craig Mautner3d7b7d52012-05-24 11:28:26 -07006796 private void sendScreenStatusToClientsLocked() {
Craig Mautner59c00972012-07-30 12:10:24 -07006797 final boolean on = mPowerManager.isScreenOn();
Craig Mautner7c6be102013-07-16 12:30:28 -07006798 final int numDisplays = mDisplayContents.size();
6799 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
6800 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
6801 final int numWindows = windows.size();
6802 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
6803 try {
6804 windows.get(winNdx).mClient.dispatchScreenState(on);
6805 } catch (RemoteException e) {
6806 // Ignored
6807 }
Romain Guy7e4e5612012-03-05 14:37:29 -08006808 }
6809 }
6810 }
6811
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006812 // -------------------------------------------------------------
6813 // Async Handler
6814 // -------------------------------------------------------------
6815
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006816 final class H extends Handler {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006817 public static final int REPORT_FOCUS_CHANGE = 2;
6818 public static final int REPORT_LOSING_FOCUS = 3;
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08006819 public static final int DO_TRAVERSAL = 4;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006820 public static final int ADD_STARTING = 5;
6821 public static final int REMOVE_STARTING = 6;
6822 public static final int FINISHED_STARTING = 7;
6823 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07006824 public static final int REPORT_APPLICATION_TOKEN_DRAWN = 9;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006825 public static final int WINDOW_FREEZE_TIMEOUT = 11;
Craig Mautner259328c2012-08-21 19:30:58 -07006826
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006827 public static final int APP_TRANSITION_TIMEOUT = 13;
6828 public static final int PERSIST_ANIMATION_SCALE = 14;
6829 public static final int FORCE_GC = 15;
6830 public static final int ENABLE_SCREEN = 16;
6831 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006832 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07006833 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07006834 public static final int DRAG_START_TIMEOUT = 20;
Chris Tated4533f12010-10-19 15:15:08 -07006835 public static final int DRAG_END_TIMEOUT = 21;
Jeff Brown2992ea72011-01-28 22:04:14 -08006836 public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006837 public static final int BOOT_TIMEOUT = 23;
Dianne Hackborn38e29a62011-09-18 14:43:08 -07006838 public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
Craig Mautner96868332012-12-04 14:29:11 -08006839 public static final int SHOW_STRICT_MODE_VIOLATION = 25;
6840 public static final int DO_ANIMATION_CALLBACK = 26;
Romain Guy06882f82009-06-10 13:36:04 -07006841
Craig Mautner96868332012-12-04 14:29:11 -08006842 public static final int DO_DISPLAY_ADDED = 27;
6843 public static final int DO_DISPLAY_REMOVED = 28;
6844 public static final int DO_DISPLAY_CHANGED = 29;
Craig Mautner722285e2012-09-07 13:55:58 -07006845
Craig Mautner96868332012-12-04 14:29:11 -08006846 public static final int CLIENT_FREEZE_TIMEOUT = 30;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07006847
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006848 @Override
6849 public void handleMessage(Message msg) {
Craig Mautner7d8df392012-04-06 15:26:23 -07006850 if (DEBUG_WINDOW_TRACE) {
6851 Slog.v(TAG, "handleMessage: entry what=" + msg.what);
6852 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006853 switch (msg.what) {
6854 case REPORT_FOCUS_CHANGE: {
6855 WindowState lastFocus;
6856 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07006857
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006858 synchronized(mWindowMap) {
6859 lastFocus = mLastFocus;
6860 newFocus = mCurrentFocus;
6861 if (lastFocus == newFocus) {
6862 // Focus is not changing, so nothing to do.
6863 return;
6864 }
6865 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006866 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006867 // + " to " + newFocus);
6868 if (newFocus != null && lastFocus != null
6869 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006870 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006871 mLosingFocus.add(lastFocus);
6872 lastFocus = null;
6873 }
6874 }
6875
6876 if (lastFocus != newFocus) {
6877 //System.out.println("Changing focus from " + lastFocus
6878 // + " to " + newFocus);
6879 if (newFocus != null) {
Dianne Hackborne3f23a32013-03-01 13:25:35 -08006880 //Slog.i(TAG, "Gaining focus: " + newFocus);
6881 newFocus.reportFocusChangedSerialized(true, mInTouchMode);
Konstantin Lopyrev5e7833a2010-08-09 17:01:11 -07006882 notifyFocusChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006883 }
6884
6885 if (lastFocus != null) {
Dianne Hackborne3f23a32013-03-01 13:25:35 -08006886 //Slog.i(TAG, "Losing focus: " + lastFocus);
6887 lastFocus.reportFocusChangedSerialized(false, mInTouchMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006888 }
6889 }
6890 } break;
6891
6892 case REPORT_LOSING_FOCUS: {
6893 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07006894
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006895 synchronized(mWindowMap) {
6896 losers = mLosingFocus;
6897 mLosingFocus = new ArrayList<WindowState>();
6898 }
6899
6900 final int N = losers.size();
6901 for (int i=0; i<N; i++) {
Dianne Hackborne3f23a32013-03-01 13:25:35 -08006902 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
6903 losers.get(i).reportFocusChangedSerialized(false, mInTouchMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006904 }
6905 } break;
6906
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08006907 case DO_TRAVERSAL: {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006908 synchronized(mWindowMap) {
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08006909 mTraversalScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006910 performLayoutAndPlaceSurfacesLocked();
6911 }
6912 } break;
6913
6914 case ADD_STARTING: {
6915 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
6916 final StartingData sd = wtoken.startingData;
6917
6918 if (sd == null) {
6919 // Animation has been canceled... do nothing.
6920 return;
6921 }
Romain Guy06882f82009-06-10 13:36:04 -07006922
Joe Onorato8a9b2202010-02-26 18:56:32 -08006923 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006924 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07006925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006926 View view = null;
6927 try {
6928 view = mPolicy.addStartingWindow(
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07006929 wtoken.token, sd.pkg, sd.theme, sd.compatInfo,
6930 sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006931 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006932 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006933 }
6934
6935 if (view != null) {
6936 boolean abort = false;
6937
6938 synchronized(mWindowMap) {
6939 if (wtoken.removed || wtoken.startingData == null) {
6940 // If the window was successfully added, then
6941 // we need to remove it.
6942 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006943 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006944 "Aborted starting " + wtoken
6945 + ": removed=" + wtoken.removed
6946 + " startingData=" + wtoken.startingData);
6947 wtoken.startingWindow = null;
6948 wtoken.startingData = null;
6949 abort = true;
6950 }
6951 } else {
6952 wtoken.startingView = view;
6953 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006954 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006955 "Added starting " + wtoken
6956 + ": startingWindow="
6957 + wtoken.startingWindow + " startingView="
6958 + wtoken.startingView);
6959 }
6960
6961 if (abort) {
6962 try {
6963 mPolicy.removeStartingWindow(wtoken.token, view);
6964 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006965 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006966 }
6967 }
6968 }
6969 } break;
6970
6971 case REMOVE_STARTING: {
6972 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
6973 IBinder token = null;
6974 View view = null;
6975 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006976 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006977 + wtoken + ": startingWindow="
6978 + wtoken.startingWindow + " startingView="
6979 + wtoken.startingView);
6980 if (wtoken.startingWindow != null) {
6981 view = wtoken.startingView;
6982 token = wtoken.token;
6983 wtoken.startingData = null;
6984 wtoken.startingView = null;
6985 wtoken.startingWindow = null;
Craig Mautner38b24782012-07-02 16:21:28 -07006986 wtoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006987 }
6988 }
6989 if (view != null) {
6990 try {
6991 mPolicy.removeStartingWindow(token, view);
6992 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006993 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006994 }
6995 }
6996 } break;
6997
6998 case FINISHED_STARTING: {
6999 IBinder token = null;
7000 View view = null;
7001 while (true) {
7002 synchronized (mWindowMap) {
7003 final int N = mFinishedStarting.size();
7004 if (N <= 0) {
7005 break;
7006 }
7007 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
7008
Joe Onorato8a9b2202010-02-26 18:56:32 -08007009 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007010 "Finished starting " + wtoken
7011 + ": startingWindow=" + wtoken.startingWindow
7012 + " startingView=" + wtoken.startingView);
7013
7014 if (wtoken.startingWindow == null) {
7015 continue;
7016 }
7017
7018 view = wtoken.startingView;
7019 token = wtoken.token;
7020 wtoken.startingData = null;
7021 wtoken.startingView = null;
7022 wtoken.startingWindow = null;
Craig Mautner38b24782012-07-02 16:21:28 -07007023 wtoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007024 }
7025
7026 try {
7027 mPolicy.removeStartingWindow(token, view);
7028 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007029 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007030 }
7031 }
7032 } break;
7033
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07007034 case REPORT_APPLICATION_TOKEN_DRAWN: {
7035 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7036
7037 try {
7038 if (DEBUG_VISIBILITY) Slog.v(
7039 TAG, "Reporting drawn in " + wtoken);
7040 wtoken.appToken.windowsDrawn();
7041 } catch (RemoteException ex) {
7042 }
7043 } break;
7044
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007045 case REPORT_APPLICATION_TOKEN_WINDOWS: {
7046 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7047
7048 boolean nowVisible = msg.arg1 != 0;
7049 boolean nowGone = msg.arg2 != 0;
7050
7051 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007052 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007053 TAG, "Reporting visible in " + wtoken
7054 + " visible=" + nowVisible
7055 + " gone=" + nowGone);
7056 if (nowVisible) {
7057 wtoken.appToken.windowsVisible();
7058 } else {
7059 wtoken.appToken.windowsGone();
7060 }
7061 } catch (RemoteException ex) {
7062 }
7063 } break;
Romain Guy06882f82009-06-10 13:36:04 -07007064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007065 case WINDOW_FREEZE_TIMEOUT: {
Craig Mautner59c00972012-07-30 12:10:24 -07007066 // TODO(multidisplay): Can non-default displays rotate?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007067 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007068 Slog.w(TAG, "Window freeze timeout expired.");
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007069 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07007070 int i = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007071 while (i > 0) {
7072 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07007073 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007074 if (w.mOrientationChanging) {
7075 w.mOrientationChanging = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07007076 w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
7077 - mDisplayFreezeTime);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007078 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007079 }
7080 }
7081 performLayoutAndPlaceSurfacesLocked();
7082 }
7083 break;
7084 }
Romain Guy06882f82009-06-10 13:36:04 -07007085
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007086 case APP_TRANSITION_TIMEOUT: {
7087 synchronized (mWindowMap) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08007088 if (mAppTransition.isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08007089 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** APP TRANSITION TIMEOUT");
7090 mAppTransition.setTimeout();
Craig Mautner2ad92072013-02-25 16:19:24 -08007091 mAnimatingAppTokens.clear();
7092 mAnimatingAppTokens.addAll(mAppTokens);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007093 performLayoutAndPlaceSurfacesLocked();
7094 }
7095 }
7096 break;
7097 }
Romain Guy06882f82009-06-10 13:36:04 -07007098
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007099 case PERSIST_ANIMATION_SCALE: {
Jeff Sharkey6e2bee72012-10-01 13:39:08 -07007100 Settings.Global.putFloat(mContext.getContentResolver(),
7101 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
7102 Settings.Global.putFloat(mContext.getContentResolver(),
7103 Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
7104 Settings.Global.putFloat(mContext.getContentResolver(),
7105 Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007106 break;
7107 }
Romain Guy06882f82009-06-10 13:36:04 -07007108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007109 case FORCE_GC: {
Craig Mautner1caa3992012-06-22 09:46:48 -07007110 synchronized (mWindowMap) {
Craig Mautner96868332012-12-04 14:29:11 -08007111 // Since we're holding both mWindowMap and mAnimator we don't need to
7112 // hold mAnimator.mLayoutToAnim.
7113 if (mAnimator.mAnimating || mAnimationScheduled) {
7114 // If we are animating, don't do the gc now but
7115 // delay a bit so we don't interrupt the animation.
7116 sendEmptyMessageDelayed(H.FORCE_GC, 2000);
7117 return;
7118 }
7119 // If we are currently rotating the display, it will
7120 // schedule a new message when done.
7121 if (mDisplayFrozen) {
7122 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007123 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007124 }
7125 Runtime.getRuntime().gc();
7126 break;
7127 }
Romain Guy06882f82009-06-10 13:36:04 -07007128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007129 case ENABLE_SCREEN: {
7130 performEnableScreen();
7131 break;
7132 }
Romain Guy06882f82009-06-10 13:36:04 -07007133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007134 case APP_FREEZE_TIMEOUT: {
7135 synchronized (mWindowMap) {
Craig Mautner96868332012-12-04 14:29:11 -08007136 Slog.w(TAG, "App freeze timeout expired.");
Craig Mautner2ad92072013-02-25 16:19:24 -08007137 int i = mAppTokens.size();
7138 while (i > 0) {
7139 i--;
7140 AppWindowToken tok = mAppTokens.get(i);
Craig Mautner96868332012-12-04 14:29:11 -08007141 if (tok.mAppAnimator.freezingScreen) {
7142 Slog.w(TAG, "Force clearing freeze: " + tok);
7143 unsetAppFreezingScreenLocked(tok, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007144 }
7145 }
7146 }
7147 break;
7148 }
Romain Guy06882f82009-06-10 13:36:04 -07007149
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007150 case CLIENT_FREEZE_TIMEOUT: {
7151 synchronized (mWindowMap) {
7152 if (mClientFreezingScreen) {
7153 mClientFreezingScreen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07007154 mLastFinishedFreezeSource = "client-timeout";
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007155 stopFreezingDisplayLocked();
7156 }
7157 }
7158 break;
7159 }
7160
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007161 case SEND_NEW_CONFIGURATION: {
7162 removeMessages(SEND_NEW_CONFIGURATION);
7163 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07007164 break;
7165 }
Romain Guy06882f82009-06-10 13:36:04 -07007166
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07007167 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007168 if (mWindowsChanged) {
7169 synchronized (mWindowMap) {
7170 mWindowsChanged = false;
7171 }
7172 notifyWindowsChanged();
7173 }
7174 break;
7175 }
7176
Christopher Tatea53146c2010-09-07 11:57:52 -07007177 case DRAG_START_TIMEOUT: {
7178 IBinder win = (IBinder)msg.obj;
7179 if (DEBUG_DRAG) {
7180 Slog.w(TAG, "Timeout starting drag by win " + win);
7181 }
7182 synchronized (mWindowMap) {
7183 // !!! TODO: ANR the app that has failed to start the drag in time
7184 if (mDragState != null) {
Chris Tated4533f12010-10-19 15:15:08 -07007185 mDragState.unregister();
Jeff Brown2e44b072011-01-24 15:21:56 -08007186 mInputMonitor.updateInputWindowsLw(true /*force*/);
Christopher Tatea53146c2010-09-07 11:57:52 -07007187 mDragState.reset();
7188 mDragState = null;
7189 }
7190 }
Chris Tated4533f12010-10-19 15:15:08 -07007191 break;
Christopher Tatea53146c2010-09-07 11:57:52 -07007192 }
7193
Chris Tated4533f12010-10-19 15:15:08 -07007194 case DRAG_END_TIMEOUT: {
7195 IBinder win = (IBinder)msg.obj;
7196 if (DEBUG_DRAG) {
7197 Slog.w(TAG, "Timeout ending drag to win " + win);
7198 }
7199 synchronized (mWindowMap) {
7200 // !!! TODO: ANR the drag-receiving app
Christopher Tated9be36c2011-08-16 16:09:33 -07007201 if (mDragState != null) {
7202 mDragState.mDragResult = false;
7203 mDragState.endDragLw();
7204 }
Chris Tated4533f12010-10-19 15:15:08 -07007205 }
7206 break;
7207 }
Jeff Brown2992ea72011-01-28 22:04:14 -08007208
7209 case REPORT_HARD_KEYBOARD_STATUS_CHANGE: {
7210 notifyHardKeyboardStatusChange();
7211 break;
7212 }
Dianne Hackborn38e29a62011-09-18 14:43:08 -07007213
7214 case BOOT_TIMEOUT: {
7215 performBootTimeout();
7216 break;
7217 }
7218
7219 case WAITING_FOR_DRAWN_TIMEOUT: {
7220 Pair<WindowState, IRemoteCallback> pair;
7221 synchronized (mWindowMap) {
7222 pair = (Pair<WindowState, IRemoteCallback>)msg.obj;
7223 Slog.w(TAG, "Timeout waiting for drawn: " + pair.first);
7224 if (!mWaitingForDrawn.remove(pair)) {
7225 return;
7226 }
7227 }
7228 try {
7229 pair.second.sendResult(null);
7230 } catch (RemoteException e) {
7231 }
7232 break;
7233 }
Craig Mautnera608b882012-03-30 13:03:49 -07007234
Craig Mautner0447a812012-05-22 16:01:31 -07007235 case SHOW_STRICT_MODE_VIOLATION: {
Chris Craik3198ef32012-10-10 14:52:30 -07007236 showStrictModeViolation(msg.arg1, msg.arg2);
Craig Mautner0447a812012-05-22 16:01:31 -07007237 break;
7238 }
7239
Dianne Hackborn84375872012-06-01 19:03:50 -07007240 case DO_ANIMATION_CALLBACK: {
7241 try {
7242 ((IRemoteCallback)msg.obj).sendResult(null);
7243 } catch (RemoteException e) {
7244 }
7245 break;
7246 }
Craig Mautner722285e2012-09-07 13:55:58 -07007247
Craig Mautner722285e2012-09-07 13:55:58 -07007248 case DO_DISPLAY_ADDED:
7249 synchronized (mWindowMap) {
7250 handleDisplayAddedLocked(msg.arg1);
7251 }
7252 break;
7253
7254 case DO_DISPLAY_REMOVED:
7255 synchronized (mWindowMap) {
7256 handleDisplayRemovedLocked(msg.arg1);
7257 }
7258 break;
7259
7260 case DO_DISPLAY_CHANGED:
7261 synchronized (mWindowMap) {
7262 handleDisplayChangedLocked(msg.arg1);
7263 }
7264 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007265 }
Craig Mautner7d8df392012-04-06 15:26:23 -07007266 if (DEBUG_WINDOW_TRACE) {
7267 Slog.v(TAG, "handleMessage: exit");
7268 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007269 }
7270 }
7271
7272 // -------------------------------------------------------------
7273 // IWindowManager API
7274 // -------------------------------------------------------------
7275
Craig Mautner7d8df392012-04-06 15:26:23 -07007276 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007277 public IWindowSession openSession(IInputMethodClient client,
7278 IInputContext inputContext) {
7279 if (client == null) throw new IllegalArgumentException("null client");
7280 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08007281 Session session = new Session(this, client, inputContext);
Jeff Brown46b9ac02010-04-22 18:58:52 -07007282 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007283 }
7284
Craig Mautner7d8df392012-04-06 15:26:23 -07007285 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007286 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
7287 synchronized (mWindowMap) {
7288 // The focus for the client is the window immediately below
7289 // where we would place the input method window.
7290 int idx = findDesiredInputMethodWindowIndexLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007291 if (idx > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07007292 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007293 WindowState imFocus = getDefaultWindowListLocked().get(idx-1);
Dianne Hackbornac920872012-05-22 11:49:49 -07007294 if (DEBUG_INPUT_METHOD) {
7295 Slog.i(TAG, "Desired input method target: " + imFocus);
Craig Mautner59c00972012-07-30 12:10:24 -07007296 Slog.i(TAG, "Current focus: " + mCurrentFocus);
7297 Slog.i(TAG, "Last focus: " + mLastFocus);
Dianne Hackbornac920872012-05-22 11:49:49 -07007298 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007299 if (imFocus != null) {
Dianne Hackborne75d8722011-01-27 19:37:40 -08007300 // This may be a starting window, in which case we still want
7301 // to count it as okay.
7302 if (imFocus.mAttrs.type == LayoutParams.TYPE_APPLICATION_STARTING
7303 && imFocus.mAppToken != null) {
7304 // The client has definitely started, so it really should
7305 // have a window in this app token. Let's look for it.
7306 for (int i=0; i<imFocus.mAppToken.windows.size(); i++) {
7307 WindowState w = imFocus.mAppToken.windows.get(i);
7308 if (w != imFocus) {
Dianne Hackbornac920872012-05-22 11:49:49 -07007309 Log.i(TAG, "Switching to real app window: " + w);
Dianne Hackborne75d8722011-01-27 19:37:40 -08007310 imFocus = w;
7311 break;
7312 }
7313 }
7314 }
Dianne Hackbornac920872012-05-22 11:49:49 -07007315 if (DEBUG_INPUT_METHOD) {
7316 Slog.i(TAG, "IM target client: " + imFocus.mSession.mClient);
7317 if (imFocus.mSession.mClient != null) {
7318 Slog.i(TAG, "IM target client binder: "
7319 + imFocus.mSession.mClient.asBinder());
7320 Slog.i(TAG, "Requesting client binder: " + client.asBinder());
7321 }
7322 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007323 if (imFocus.mSession.mClient != null &&
7324 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
7325 return true;
7326 }
7327 }
7328 }
Craig Mautner59c00972012-07-30 12:10:24 -07007329
7330 // Okay, how about this... what is the current focus?
7331 // It seems in some cases we may not have moved the IM
7332 // target window, such as when it was in a pop-up window,
7333 // so let's also look at the current focus. (An example:
7334 // go to Gmail, start searching so the keyboard goes up,
7335 // press home. Sometimes the IME won't go down.)
7336 // Would be nice to fix this more correctly, but it's
7337 // way at the end of a release, and this should be good enough.
7338 if (mCurrentFocus != null && mCurrentFocus.mSession.mClient != null
7339 && mCurrentFocus.mSession.mClient.asBinder() == client.asBinder()) {
7340 return true;
7341 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007342 }
7343 return false;
7344 }
Romain Guy06882f82009-06-10 13:36:04 -07007345
Dianne Hackborn672cf452013-03-26 15:24:24 -07007346 @Override
Craig Mautner59c00972012-07-30 12:10:24 -07007347 public void getInitialDisplaySize(int displayId, Point size) {
Craig Mautner58106812012-12-28 12:27:40 -08007348 synchronized (mWindowMap) {
7349 final DisplayContent displayContent = getDisplayContentLocked(displayId);
7350 if (displayContent != null) {
7351 synchronized(displayContent.mDisplaySizeLock) {
7352 size.x = displayContent.mInitialDisplayWidth;
7353 size.y = displayContent.mInitialDisplayHeight;
7354 }
Craig Mautner2d5618c2012-10-18 13:55:47 -07007355 }
Dianne Hackborn7d608422011-08-07 16:24:18 -07007356 }
7357 }
7358
Craig Mautner2d5618c2012-10-18 13:55:47 -07007359 @Override
Dianne Hackborn672cf452013-03-26 15:24:24 -07007360 public void getBaseDisplaySize(int displayId, Point size) {
7361 synchronized (mWindowMap) {
7362 final DisplayContent displayContent = getDisplayContentLocked(displayId);
7363 if (displayContent != null) {
7364 synchronized(displayContent.mDisplaySizeLock) {
7365 size.x = displayContent.mBaseDisplayWidth;
7366 size.y = displayContent.mBaseDisplayHeight;
7367 }
7368 }
7369 }
7370 }
7371
7372 @Override
Jeff Brown43aa1592012-09-10 17:36:31 -07007373 public void setForcedDisplaySize(int displayId, int width, int height) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08007374 if (mContext.checkCallingOrSelfPermission(
7375 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7376 PackageManager.PERMISSION_GRANTED) {
7377 throw new SecurityException("Must hold permission " +
7378 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7379 }
7380 if (displayId != Display.DEFAULT_DISPLAY) {
7381 throw new IllegalArgumentException("Can only set the default display");
7382 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007383 synchronized(mWindowMap) {
Jeff Brown43aa1592012-09-10 17:36:31 -07007384 // Set some sort of reasonable bounds on the size of the display that we
7385 // will try to emulate.
7386 final int MIN_WIDTH = 200;
7387 final int MIN_HEIGHT = 200;
7388 final int MAX_SCALE = 2;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007389 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007390 if (displayContent != null) {
7391 width = Math.min(Math.max(width, MIN_WIDTH),
7392 displayContent.mInitialDisplayWidth * MAX_SCALE);
7393 height = Math.min(Math.max(height, MIN_HEIGHT),
7394 displayContent.mInitialDisplayHeight * MAX_SCALE);
7395 setForcedDisplaySizeLocked(displayContent, width, height);
7396 Settings.Global.putString(mContext.getContentResolver(),
7397 Settings.Global.DISPLAY_SIZE_FORCED, width + "," + height);
7398 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007399 }
7400 }
7401
Dianne Hackborndde331c2012-08-03 14:01:57 -07007402 private void readForcedDisplaySizeAndDensityLocked(final DisplayContent displayContent) {
Jeff Brown43aa1592012-09-10 17:36:31 -07007403 final String sizeStr = Settings.Global.getString(mContext.getContentResolver(),
7404 Settings.Global.DISPLAY_SIZE_FORCED);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007405 if (sizeStr != null && sizeStr.length() > 0) {
7406 final int pos = sizeStr.indexOf(',');
7407 if (pos > 0 && sizeStr.lastIndexOf(',') == pos) {
7408 int width, height;
7409 try {
7410 width = Integer.parseInt(sizeStr.substring(0, pos));
7411 height = Integer.parseInt(sizeStr.substring(pos+1));
7412 synchronized(displayContent.mDisplaySizeLock) {
7413 if (displayContent.mBaseDisplayWidth != width
7414 || displayContent.mBaseDisplayHeight != height) {
Dianne Hackborndde331c2012-08-03 14:01:57 -07007415 Slog.i(TAG, "FORCED DISPLAY SIZE: " + width + "x" + height);
7416 displayContent.mBaseDisplayWidth = width;
7417 displayContent.mBaseDisplayHeight = height;
7418 }
7419 }
7420 } catch (NumberFormatException ex) {
7421 }
7422 }
Joe Onorato571ae902011-05-24 13:48:43 -07007423 }
Jeff Brown43aa1592012-09-10 17:36:31 -07007424 final String densityStr = Settings.Global.getString(mContext.getContentResolver(),
7425 Settings.Global.DISPLAY_DENSITY_FORCED);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007426 if (densityStr != null && densityStr.length() > 0) {
7427 int density;
7428 try {
7429 density = Integer.parseInt(densityStr);
7430 synchronized(displayContent.mDisplaySizeLock) {
7431 if (displayContent.mBaseDisplayDensity != density) {
Dianne Hackborndde331c2012-08-03 14:01:57 -07007432 Slog.i(TAG, "FORCED DISPLAY DENSITY: " + density);
7433 displayContent.mBaseDisplayDensity = density;
7434 }
7435 }
7436 } catch (NumberFormatException ex) {
7437 }
Joe Onorato571ae902011-05-24 13:48:43 -07007438 }
Joe Onorato571ae902011-05-24 13:48:43 -07007439 }
7440
Craig Mautner2d5618c2012-10-18 13:55:47 -07007441 // displayContent must not be null
Craig Mautner59c00972012-07-30 12:10:24 -07007442 private void setForcedDisplaySizeLocked(DisplayContent displayContent, int width, int height) {
Joe Onorato571ae902011-05-24 13:48:43 -07007443 Slog.i(TAG, "Using new display size: " + width + "x" + height);
7444
Craig Mautner59c00972012-07-30 12:10:24 -07007445 synchronized(displayContent.mDisplaySizeLock) {
7446 displayContent.mBaseDisplayWidth = width;
7447 displayContent.mBaseDisplayHeight = height;
Dianne Hackborn1fbee792011-11-30 11:29:58 -08007448 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007449 reconfigureDisplayLocked(displayContent);
7450 }
7451
Craig Mautner2d5618c2012-10-18 13:55:47 -07007452 @Override
Dianne Hackborndde331c2012-08-03 14:01:57 -07007453 public void clearForcedDisplaySize(int displayId) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08007454 if (mContext.checkCallingOrSelfPermission(
7455 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7456 PackageManager.PERMISSION_GRANTED) {
7457 throw new SecurityException("Must hold permission " +
7458 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7459 }
7460 if (displayId != Display.DEFAULT_DISPLAY) {
7461 throw new IllegalArgumentException("Can only set the default display");
7462 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007463 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007464 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007465 if (displayContent != null) {
7466 setForcedDisplaySizeLocked(displayContent, displayContent.mInitialDisplayWidth,
7467 displayContent.mInitialDisplayHeight);
7468 Settings.Global.putString(mContext.getContentResolver(),
7469 Settings.Global.DISPLAY_SIZE_FORCED, "");
7470 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007471 }
7472 }
7473
Craig Mautner2d5618c2012-10-18 13:55:47 -07007474 @Override
Dianne Hackborn672cf452013-03-26 15:24:24 -07007475 public int getInitialDisplayDensity(int displayId) {
7476 synchronized (mWindowMap) {
7477 final DisplayContent displayContent = getDisplayContentLocked(displayId);
7478 if (displayContent != null) {
7479 synchronized(displayContent.mDisplaySizeLock) {
7480 return displayContent.mInitialDisplayDensity;
7481 }
7482 }
7483 }
7484 return -1;
7485 }
7486
7487 @Override
7488 public int getBaseDisplayDensity(int displayId) {
7489 synchronized (mWindowMap) {
7490 final DisplayContent displayContent = getDisplayContentLocked(displayId);
7491 if (displayContent != null) {
7492 synchronized(displayContent.mDisplaySizeLock) {
7493 return displayContent.mBaseDisplayDensity;
7494 }
7495 }
7496 }
7497 return -1;
7498 }
7499
7500 @Override
Dianne Hackborndde331c2012-08-03 14:01:57 -07007501 public void setForcedDisplayDensity(int displayId, int density) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08007502 if (mContext.checkCallingOrSelfPermission(
7503 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7504 PackageManager.PERMISSION_GRANTED) {
7505 throw new SecurityException("Must hold permission " +
7506 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7507 }
7508 if (displayId != Display.DEFAULT_DISPLAY) {
7509 throw new IllegalArgumentException("Can only set the default display");
7510 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007511 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007512 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007513 if (displayContent != null) {
7514 setForcedDisplayDensityLocked(displayContent, density);
7515 Settings.Global.putString(mContext.getContentResolver(),
7516 Settings.Global.DISPLAY_DENSITY_FORCED, Integer.toString(density));
7517 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007518 }
7519 }
7520
Craig Mautner2d5618c2012-10-18 13:55:47 -07007521 // displayContent must not be null
Dianne Hackborndde331c2012-08-03 14:01:57 -07007522 private void setForcedDisplayDensityLocked(DisplayContent displayContent, int density) {
7523 Slog.i(TAG, "Using new display density: " + density);
7524
7525 synchronized(displayContent.mDisplaySizeLock) {
7526 displayContent.mBaseDisplayDensity = density;
7527 }
7528 reconfigureDisplayLocked(displayContent);
7529 }
7530
Craig Mautner2d5618c2012-10-18 13:55:47 -07007531 @Override
Dianne Hackborndde331c2012-08-03 14:01:57 -07007532 public void clearForcedDisplayDensity(int displayId) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08007533 if (mContext.checkCallingOrSelfPermission(
7534 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7535 PackageManager.PERMISSION_GRANTED) {
7536 throw new SecurityException("Must hold permission " +
7537 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7538 }
7539 if (displayId != Display.DEFAULT_DISPLAY) {
7540 throw new IllegalArgumentException("Can only set the default display");
7541 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007542 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007543 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007544 if (displayContent != null) {
7545 setForcedDisplayDensityLocked(displayContent, displayContent.mInitialDisplayDensity);
7546 Settings.Global.putString(mContext.getContentResolver(),
7547 Settings.Global.DISPLAY_DENSITY_FORCED, "");
7548 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007549 }
7550 }
7551
Craig Mautner2d5618c2012-10-18 13:55:47 -07007552 // displayContent must not be null
Dianne Hackborndde331c2012-08-03 14:01:57 -07007553 private void reconfigureDisplayLocked(DisplayContent displayContent) {
Craig Mautner69b08182012-09-05 13:07:13 -07007554 // TODO: Multidisplay: for now only use with default display.
Jeff Browne215f262012-09-10 16:01:14 -07007555 mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
7556 displayContent.mBaseDisplayWidth,
7557 displayContent.mBaseDisplayHeight,
7558 displayContent.mBaseDisplayDensity);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007559
Craig Mautner19d59bc2012-09-04 11:15:56 -07007560 displayContent.layoutNeeded = true;
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007561
7562 boolean configChanged = updateOrientationFromAppTokensLocked(false);
7563 mTempConfiguration.setToDefaults();
7564 mTempConfiguration.fontScale = mCurConfiguration.fontScale;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08007565 if (computeScreenConfigurationLocked(mTempConfiguration)) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007566 if (mCurConfiguration.diff(mTempConfiguration) != 0) {
7567 configChanged = true;
7568 }
7569 }
7570
7571 if (configChanged) {
7572 mWaitingForConfig = true;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007573 startFreezingDisplayLocked(false, 0, 0);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007574 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
7575 }
7576
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007577 performLayoutAndPlaceSurfacesLocked();
7578 }
7579
Craig Mautner24d887472013-03-20 15:40:36 -07007580 @Override
Dianne Hackbornc652de82013-02-15 16:32:56 -08007581 public void setOverscan(int displayId, int left, int top, int right, int bottom) {
7582 if (mContext.checkCallingOrSelfPermission(
7583 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7584 PackageManager.PERMISSION_GRANTED) {
7585 throw new SecurityException("Must hold permission " +
7586 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7587 }
7588 synchronized(mWindowMap) {
7589 DisplayContent displayContent = getDisplayContentLocked(displayId);
7590 if (displayContent != null) {
7591 mDisplayManagerService.setOverscan(displayId, left, top, right, bottom);
7592 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
7593 synchronized(displayContent.mDisplaySizeLock) {
7594 displayInfo.overscanLeft = left;
7595 displayInfo.overscanTop = top;
7596 displayInfo.overscanRight = right;
7597 displayInfo.overscanBottom = bottom;
7598 }
7599 mPolicy.setDisplayOverscan(displayContent.getDisplay(), left, top, right, bottom);
7600 displayContent.layoutNeeded = true;
7601 mDisplaySettings.setOverscanLocked(displayInfo.name, left, top, right, bottom);
7602 mDisplaySettings.writeSettingsLocked();
7603 performLayoutAndPlaceSurfacesLocked();
7604 }
7605 }
7606 }
7607
Craig Mautner6cfa7292013-01-15 09:05:42 -08007608 @Override
Dianne Hackbornf87d1962012-04-04 12:48:24 -07007609 public boolean hasSystemNavBar() {
7610 return mPolicy.hasSystemNavBar();
Dianne Hackborn81e56d52011-05-26 00:55:58 -07007611 }
7612
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007613 // -------------------------------------------------------------
7614 // Internals
7615 // -------------------------------------------------------------
7616
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007617 final WindowState windowForClientLocked(Session session, IWindow client,
7618 boolean throwOnError) {
7619 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007620 }
Romain Guy06882f82009-06-10 13:36:04 -07007621
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007622 final WindowState windowForClientLocked(Session session, IBinder client,
7623 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007624 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007625 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007626 TAG, "Looking up client " + client + ": " + win);
7627 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007628 RuntimeException ex = new IllegalArgumentException(
7629 "Requested window " + client + " does not exist");
7630 if (throwOnError) {
7631 throw ex;
7632 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007633 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007634 return null;
7635 }
7636 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007637 RuntimeException ex = new IllegalArgumentException(
7638 "Requested window " + client + " is in session " +
7639 win.mSession + ", not " + session);
7640 if (throwOnError) {
7641 throw ex;
7642 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007643 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007644 return null;
7645 }
7646
7647 return win;
7648 }
7649
Dianne Hackborna8f60182009-09-01 19:01:50 -07007650 final void rebuildAppWindowListLocked() {
Craig Mautner7c6be102013-07-16 12:30:28 -07007651 final int numDisplays = mDisplayContents.size();
7652 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
7653 rebuildAppWindowListLocked(mDisplayContents.valueAt(displayNdx));
Craig Mautner59c00972012-07-30 12:10:24 -07007654 }
7655 }
7656
7657 private void rebuildAppWindowListLocked(final DisplayContent displayContent) {
7658 final WindowList windows = displayContent.getWindowList();
7659 int NW = windows.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07007660 int i;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007661 int lastBelow = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007662 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007663
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007664 if (mRebuildTmp.length < NW) {
7665 mRebuildTmp = new WindowState[NW+10];
7666 }
7667
Dianne Hackborna8f60182009-09-01 19:01:50 -07007668 // First remove all existing app windows.
7669 i=0;
7670 while (i < NW) {
Craig Mautner59c00972012-07-30 12:10:24 -07007671 WindowState w = windows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007672 if (w.mAppToken != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07007673 WindowState win = windows.remove(i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007674 win.mRebuilding = true;
7675 mRebuildTmp[numRemoved] = win;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007676 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007677 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007678 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07007679 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007680 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07007681 continue;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007682 } else if (lastBelow == i-1) {
Craig Mautner65d11b32012-10-01 13:59:52 -07007683 if (w.mAttrs.type == TYPE_WALLPAPER || w.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007684 lastBelow = i;
7685 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07007686 }
7687 i++;
7688 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007689
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007690 // Keep whatever windows were below the app windows still below,
7691 // by skipping them.
7692 lastBelow++;
7693 i = lastBelow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007694
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007695 // First add all of the exiting app tokens... these are no longer
7696 // in the main app list, but still have windows shown. We put them
7697 // in the back because now that the animation is over we no longer
7698 // will care about them.
Craig Mautner2ad92072013-02-25 16:19:24 -08007699 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07007700 for (int j=0; j<NT; j++) {
Craig Mautner2ad92072013-02-25 16:19:24 -08007701 i = reAddAppWindowsLocked(displayContent, i, mExitingAppTokens.get(j));
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007702 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007703
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007704 // And add in the still active app tokens in Z order.
Craig Mautner2ad92072013-02-25 16:19:24 -08007705 NT = mAnimatingAppTokens.size();
7706 for (int j=0; j<NT; j++) {
7707 i = reAddAppWindowsLocked(displayContent, i, mAnimatingAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07007708 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007709
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007710 i -= lastBelow;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007711 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007712 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007713 + " windows but added " + i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007714 for (i=0; i<numRemoved; i++) {
7715 WindowState ws = mRebuildTmp[i];
7716 if (ws.mRebuilding) {
7717 StringWriter sw = new StringWriter();
7718 PrintWriter pw = new PrintWriter(sw);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07007719 ws.dump(pw, "", true);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007720 pw.flush();
7721 Slog.w(TAG, "This window was lost: " + ws);
7722 Slog.w(TAG, sw.toString());
Craig Mautner96868332012-12-04 14:29:11 -08007723 ws.mWinAnimator.destroySurfaceLocked();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007724 }
7725 }
7726 Slog.w(TAG, "Current app token list:");
Craig Mautner2ad92072013-02-25 16:19:24 -08007727 dumpAnimatingAppTokensLocked();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007728 Slog.w(TAG, "Final window list:");
7729 dumpWindowsLocked();
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007730 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07007731 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007732
Craig Mautner59c00972012-07-30 12:10:24 -07007733 private final void assignLayersLocked(WindowList windows) {
7734 int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007735 int curBaseLayer = 0;
7736 int curLayer = 0;
7737 int i;
Romain Guy06882f82009-06-10 13:36:04 -07007738
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007739 if (DEBUG_LAYERS) {
7740 RuntimeException here = new RuntimeException("here");
7741 here.fillInStackTrace();
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07007742 Slog.v(TAG, "Assigning layers", here);
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007743 }
7744
Svetoslav Ganov55468c62012-10-15 15:09:02 -07007745 boolean anyLayerChanged = false;
7746
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007747 for (i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07007748 final WindowState w = windows.get(i);
Craig Mautneracafd192012-05-10 10:41:02 -07007749 final WindowStateAnimator winAnimator = w.mWinAnimator;
7750 boolean layerChanged = false;
7751 int oldLayer = w.mLayer;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007752 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
7753 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007754 curLayer += WINDOW_LAYER_MULTIPLIER;
7755 w.mLayer = curLayer;
7756 } else {
7757 curBaseLayer = curLayer = w.mBaseLayer;
7758 w.mLayer = curLayer;
7759 }
Craig Mautneracafd192012-05-10 10:41:02 -07007760 if (w.mLayer != oldLayer) {
7761 layerChanged = true;
Svetoslav Ganov55468c62012-10-15 15:09:02 -07007762 anyLayerChanged = true;
Craig Mautneracafd192012-05-10 10:41:02 -07007763 }
7764 oldLayer = winAnimator.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007765 if (w.mTargetAppToken != null) {
Craig Mautneracafd192012-05-10 10:41:02 -07007766 winAnimator.mAnimLayer =
Craig Mautner59431632012-04-04 11:56:44 -07007767 w.mLayer + w.mTargetAppToken.mAppAnimator.animLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007768 } else if (w.mAppToken != null) {
Craig Mautneracafd192012-05-10 10:41:02 -07007769 winAnimator.mAnimLayer =
Craig Mautner59431632012-04-04 11:56:44 -07007770 w.mLayer + w.mAppToken.mAppAnimator.animLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007771 } else {
Craig Mautneracafd192012-05-10 10:41:02 -07007772 winAnimator.mAnimLayer = w.mLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007773 }
7774 if (w.mIsImWindow) {
Craig Mautneracafd192012-05-10 10:41:02 -07007775 winAnimator.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007776 } else if (w.mIsWallpaper) {
Craig Mautneracafd192012-05-10 10:41:02 -07007777 winAnimator.mAnimLayer += mWallpaperAnimLayerAdjustment;
7778 }
7779 if (winAnimator.mAnimLayer != oldLayer) {
7780 layerChanged = true;
Svetoslav Ganov55468c62012-10-15 15:09:02 -07007781 anyLayerChanged = true;
Craig Mautneracafd192012-05-10 10:41:02 -07007782 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07007783 if (layerChanged && mAnimator.isDimmingLocked(winAnimator)) {
Craig Mautneracafd192012-05-10 10:41:02 -07007784 // Force an animation pass just to update the mDimAnimator layer.
Craig Mautner96868332012-12-04 14:29:11 -08007785 scheduleAnimationLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007786 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007787 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
Craig Mautner8863cca2012-09-18 15:04:34 -07007788 + "mBase=" + w.mBaseLayer
7789 + " mLayer=" + w.mLayer
7790 + (w.mAppToken == null ?
7791 "" : " mAppLayer=" + w.mAppToken.mAppAnimator.animLayerAdjustment)
7792 + " =mAnimLayer=" + winAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007793 //System.out.println(
7794 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
7795 }
Svetoslav Ganov55468c62012-10-15 15:09:02 -07007796
Svetoslav Ganov545252f2012-12-10 18:29:24 -08007797 //TODO (multidisplay): Magnification is supported only for the default display.
7798 if (mDisplayMagnifier != null && anyLayerChanged
7799 && windows.get(windows.size() - 1).getDisplayId() == Display.DEFAULT_DISPLAY) {
7800 mDisplayMagnifier.onWindowLayersChangedLocked();
Svetoslav Ganov55468c62012-10-15 15:09:02 -07007801 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007802 }
7803
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007804 private final void performLayoutAndPlaceSurfacesLocked() {
Dianne Hackborn7ad44382012-10-18 17:46:00 -07007805 int loopCount = 6;
Craig Mautnera13a41d2012-10-16 12:53:13 -07007806 do {
7807 mTraversalScheduled = false;
7808 performLayoutAndPlaceSurfacesLockedLoop();
7809 mH.removeMessages(H.DO_TRAVERSAL);
Dianne Hackborn7ad44382012-10-18 17:46:00 -07007810 loopCount--;
7811 } while (mTraversalScheduled && loopCount > 0);
Craig Mautner96868332012-12-04 14:29:11 -08007812 mInnerFields.mWallpaperActionPending = false;
Craig Mautnera13a41d2012-10-16 12:53:13 -07007813 }
7814
7815 private boolean mInLayout = false;
7816 private final void performLayoutAndPlaceSurfacesLockedLoop() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007817 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07007818 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007819 throw new RuntimeException("Recursive call!");
7820 }
Craig Mautneref25d7a2012-05-15 23:01:47 -07007821 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
7822 + Debug.getCallers(3));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007823 return;
7824 }
7825
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007826 if (mWaitingForConfig) {
7827 // Our configuration has changed (most likely rotation), but we
7828 // don't yet have the complete configuration to report to
7829 // applications. Don't do any window layout until we have it.
7830 return;
7831 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08007832
Jeff Browne215f262012-09-10 16:01:14 -07007833 if (!mDisplayReady) {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07007834 // Not yet initialized, nothing to do.
7835 return;
7836 }
7837
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07007838 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08007839 mInLayout = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007840 boolean recoveringMemory = false;
Craig Mautner6cfa7292013-01-15 09:05:42 -08007841
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08007842 try {
7843 if (mForceRemoves != null) {
7844 recoveringMemory = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007845 // Wait a little bit for things to settle down, and off we go.
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08007846 for (int i=0; i<mForceRemoves.size(); i++) {
7847 WindowState ws = mForceRemoves.get(i);
7848 Slog.i(TAG, "Force removing: " + ws);
7849 removeWindowInnerLocked(ws.mSession, ws);
7850 }
7851 mForceRemoves = null;
7852 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
7853 Object tmp = new Object();
7854 synchronized (tmp) {
7855 try {
7856 tmp.wait(250);
7857 } catch (InterruptedException e) {
7858 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007859 }
7860 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08007861 } catch (RuntimeException e) {
Dianne Hackborn89620282011-09-11 12:47:45 -07007862 Log.wtf(TAG, "Unhandled exception while force removing for memory", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007863 }
Craig Mautner59c00972012-07-30 12:10:24 -07007864
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007865 try {
Craig Mautner76a71652012-09-03 23:23:58 -07007866 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Craig Mautnerbb1449b2012-03-23 16:11:14 -07007867
Craig Mautner59c00972012-07-30 12:10:24 -07007868 mInLayout = false;
7869
Craig Mautner19d59bc2012-09-04 11:15:56 -07007870 if (needsLayout()) {
Craig Mautnerbb1449b2012-03-23 16:11:14 -07007871 if (++mLayoutRepeatCount < 6) {
7872 requestTraversalLocked();
7873 } else {
7874 Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
7875 mLayoutRepeatCount = 0;
7876 }
7877 } else {
7878 mLayoutRepeatCount = 0;
7879 }
Craig Mautnerbb1449b2012-03-23 16:11:14 -07007880
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007881 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07007882 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
You Kimcb6291c2012-12-04 23:22:28 +09007883 mH.sendEmptyMessage(H.REPORT_WINDOWS_CHANGE);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007884 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007885 } catch (RuntimeException e) {
7886 mInLayout = false;
Dianne Hackborn89620282011-09-11 12:47:45 -07007887 Log.wtf(TAG, "Unhandled exception while laying out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007888 }
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07007889
7890 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007891 }
7892
Craig Mautner59c00972012-07-30 12:10:24 -07007893 private final void performLayoutLockedInner(final DisplayContent displayContent,
7894 boolean initial, boolean updateInputWindows) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07007895 if (!displayContent.layoutNeeded) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08007896 return;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007897 }
Craig Mautner19d59bc2012-09-04 11:15:56 -07007898 displayContent.layoutNeeded = false;
Craig Mautner59c00972012-07-30 12:10:24 -07007899 WindowList windows = displayContent.getWindowList();
Craig Mautner69b08182012-09-05 13:07:13 -07007900 boolean isDefaultDisplay = displayContent.isDefaultDisplay;
Craig Mautner59c00972012-07-30 12:10:24 -07007901
7902 DisplayInfo displayInfo = displayContent.getDisplayInfo();
7903 final int dw = displayInfo.logicalWidth;
7904 final int dh = displayInfo.logicalHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007905
Dianne Hackborndf89e652011-10-06 22:35:11 -07007906 final int NFW = mFakeWindows.size();
7907 for (int i=0; i<NFW; i++) {
7908 mFakeWindows.get(i).layout(dw, dh);
7909 }
7910
Craig Mautner59c00972012-07-30 12:10:24 -07007911 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007912 int i;
7913
Dianne Hackborn01b02a72012-01-12 14:05:03 -08007914 if (DEBUG_LAYOUT) {
7915 Slog.v(TAG, "-------------------------------------");
7916 Slog.v(TAG, "performLayout: needed="
Craig Mautner19d59bc2012-09-04 11:15:56 -07007917 + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
Dianne Hackborn01b02a72012-01-12 14:05:03 -08007918 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007919
7920 WindowStateAnimator universeBackground = null;
7921
Craig Mautner69b08182012-09-05 13:07:13 -07007922 mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mRotation);
7923 if (isDefaultDisplay) {
7924 // Not needed on non-default displays.
7925 mSystemDecorLayer = mPolicy.getSystemDecorRectLw(mSystemDecorRect);
7926 mScreenRect.set(0, 0, dw, dh);
7927 }
Romain Guy06882f82009-06-10 13:36:04 -07007928
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007929 int seq = mLayoutSeq+1;
7930 if (seq < 0) seq = 0;
7931 mLayoutSeq = seq;
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07007932
7933 boolean behindDream = false;
7934
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007935 // First perform layout of any root windows (not attached
7936 // to another window).
7937 int topAttached = -1;
7938 for (i = N-1; i >= 0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07007939 final WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007940
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007941 // Don't do layout of a window if it is not visible, or
7942 // soon won't be visible, to avoid wasting time and funky
7943 // changes while a window is animating away.
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07007944 final boolean gone = (behindDream && mPolicy.canBeForceHidden(win, win.mAttrs))
Craig Mautnerae446592012-12-06 19:05:05 -08007945 || win.isGoneForLayoutLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007946
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007947 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
Dianne Hackborn01b02a72012-01-12 14:05:03 -08007948 Slog.v(TAG, "1ST PASS " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007949 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
Craig Mautner812d2ca2012-09-27 15:35:34 -07007950 + " mLayoutAttached=" + win.mLayoutAttached
Craig Mautnera3f4bf52012-10-10 20:37:48 -07007951 + " screen changed=" + win.isConfigChanged());
Dianne Hackborn01b02a72012-01-12 14:05:03 -08007952 final AppWindowToken atoken = win.mAppToken;
7953 if (gone) Slog.v(TAG, " GONE: mViewVisibility="
7954 + win.mViewVisibility + " mRelayoutCalled="
7955 + win.mRelayoutCalled + " hidden="
7956 + win.mRootToken.hidden + " hiddenRequested="
7957 + (atoken != null && atoken.hiddenRequested)
7958 + " mAttachedHidden=" + win.mAttachedHidden);
7959 else Slog.v(TAG, " VIS: mViewVisibility="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007960 + win.mViewVisibility + " mRelayoutCalled="
7961 + win.mRelayoutCalled + " hidden="
7962 + win.mRootToken.hidden + " hiddenRequested="
7963 + (atoken != null && atoken.hiddenRequested)
7964 + " mAttachedHidden=" + win.mAttachedHidden);
7965 }
Craig Mautner69b08182012-09-05 13:07:13 -07007966
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007967 // If this view is GONE, then skip it -- keep the current
7968 // frame, and let the caller know so they can ignore it
7969 // if they want. (We do the normal layout for INVISIBLE
7970 // windows, since that means "perform layout as normal,
7971 // just don't display").
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007972 if (!gone || !win.mHaveFrame || win.mLayoutNeeded
Craig Mautnerf02296f2012-11-06 14:33:46 -08007973 || (win.mAttrs.type == TYPE_KEYGUARD && win.isConfigChanged())
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007974 || win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007975 if (!win.mLayoutAttached) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08007976 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08007977 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08007978 win.mContentChanged = false;
7979 }
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07007980 if (win.mAttrs.type == TYPE_DREAM) {
7981 // Don't layout windows behind a dream, so that if it
7982 // does stuff like hide the status bar we won't get a
7983 // bad transition when it goes away.
7984 behindDream = true;
7985 }
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08007986 win.mLayoutNeeded = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007987 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007988 mPolicy.layoutWindowLw(win, win.mAttrs, null);
7989 win.mLayoutSeq = seq;
Dianne Hackborn01b02a72012-01-12 14:05:03 -08007990 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007991 + win.mFrame + " mContainingFrame="
7992 + win.mContainingFrame + " mDisplayFrame="
7993 + win.mDisplayFrame);
7994 } else {
7995 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007996 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07007997 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007998 if (win.mViewVisibility == View.VISIBLE
7999 && win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND
8000 && universeBackground == null) {
8001 universeBackground = win.mWinAnimator;
8002 }
8003 }
8004
8005 if (mAnimator.mUniverseBackground != universeBackground) {
8006 mFocusMayChange = true;
8007 mAnimator.mUniverseBackground = universeBackground;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008008 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008009
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008010 boolean attachedBehindDream = false;
8011
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008012 // Now perform layout of attached windows, which usually
8013 // depend on the position of the window they are attached to.
8014 // XXX does not deal with windows that are attached to windows
8015 // that are themselves attached.
8016 for (i = topAttached; i >= 0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07008017 final WindowState win = windows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008018
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008019 if (win.mLayoutAttached) {
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008020 if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008021 + " mHaveFrame=" + win.mHaveFrame
8022 + " mViewVisibility=" + win.mViewVisibility
8023 + " mRelayoutCalled=" + win.mRelayoutCalled);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008024 // If this view is GONE, then skip it -- keep the current
8025 // frame, and let the caller know so they can ignore it
8026 // if they want. (We do the normal layout for INVISIBLE
8027 // windows, since that means "perform layout as normal,
8028 // just don't display").
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008029 if (attachedBehindDream && mPolicy.canBeForceHidden(win, win.mAttrs)) {
8030 continue;
8031 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008032 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008033 || !win.mHaveFrame || win.mLayoutNeeded) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008034 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08008035 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008036 win.mContentChanged = false;
8037 }
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008038 win.mLayoutNeeded = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008039 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008040 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
8041 win.mLayoutSeq = seq;
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008042 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008043 + win.mFrame + " mContainingFrame="
8044 + win.mContainingFrame + " mDisplayFrame="
8045 + win.mDisplayFrame);
8046 }
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008047 } else if (win.mAttrs.type == TYPE_DREAM) {
8048 // Don't layout windows behind a dream, so that if it
8049 // does stuff like hide the status bar we won't get a
8050 // bad transition when it goes away.
8051 attachedBehindDream = behindDream;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008052 }
8053 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08008054
Jeff Brown349703e2010-06-22 01:27:15 -07008055 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown3a22cd92011-01-21 13:59:04 -08008056 mInputMonitor.setUpdateInputWindowsNeededLw();
8057 if (updateInputWindows) {
Jeff Brown2e44b072011-01-24 15:21:56 -08008058 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08008059 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008060
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008061 mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008062 }
Romain Guy06882f82009-06-10 13:36:04 -07008063
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008064 void makeWindowFreezingScreenIfNeededLocked(WindowState w) {
8065 // If the screen is currently frozen or off, then keep
8066 // it frozen/off until this window draws at its new
8067 // orientation.
Craig Mautner2fb98b12012-03-20 17:24:00 -07008068 if (!okToDisplay()) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008069 if (DEBUG_ORIENTATION) Slog.v(TAG,
8070 "Changing surface while display frozen: " + w);
8071 w.mOrientationChanging = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -07008072 w.mLastFreezeDuration = 0;
Craig Mautner3255a282012-04-16 15:42:47 -07008073 mInnerFields.mOrientationChangeComplete = false;
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008074 if (!mWindowsFreezingScreen) {
8075 mWindowsFreezingScreen = true;
8076 // XXX should probably keep timeout from
8077 // when we first froze the display.
8078 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
Craig Mautner6cfa7292013-01-15 09:05:42 -08008079 mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT,
You Kimcb6291c2012-12-04 23:22:28 +09008080 WINDOW_FREEZE_TIMEOUT_DURATION);
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008081 }
8082 }
8083 }
8084
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008085 /**
8086 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
Craig Mautner19d59bc2012-09-04 11:15:56 -07008087 * @param windows List of windows on default display.
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008088 * @return bitmap indicating if another pass through layout must be made.
8089 */
Craig Mautner59c00972012-07-30 12:10:24 -07008090 public int handleAppTransitionReadyLocked(WindowList windows) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008091 int changes = 0;
8092 int i;
8093 int NN = mOpeningApps.size();
8094 boolean goodToGo = true;
8095 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8096 "Checking " + NN + " opening apps (frozen="
8097 + mDisplayFrozen + " timeout="
Craig Mautner164d4bb2012-11-26 13:51:23 -08008098 + mAppTransition.isTimeout() + ")...");
8099 if (!mDisplayFrozen && !mAppTransition.isTimeout()) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008100 // If the display isn't frozen, wait to do anything until
8101 // all of the apps are ready. Otherwise just go because
8102 // we'll unfreeze the display when everyone is ready.
8103 for (i=0; i<NN && goodToGo; i++) {
8104 AppWindowToken wtoken = mOpeningApps.get(i);
8105 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Craig Mautner1d961d42012-05-27 12:02:11 -07008106 "Check opening app=" + wtoken + ": allDrawn="
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008107 + wtoken.allDrawn + " startingDisplayed="
Craig Mautner7358fbf2012-04-12 21:06:33 -07008108 + wtoken.startingDisplayed + " startingMoved="
8109 + wtoken.startingMoved);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008110 if (!wtoken.allDrawn && !wtoken.startingDisplayed
8111 && !wtoken.startingMoved) {
8112 goodToGo = false;
8113 }
8114 }
8115 }
8116 if (goodToGo) {
8117 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
Craig Mautner164d4bb2012-11-26 13:51:23 -08008118 int transit = mAppTransition.getAppTransition();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008119 if (mSkipAppTransitionAnimation) {
Craig Mautner4b71aa12012-12-27 17:20:01 -08008120 transit = AppTransition.TRANSIT_UNSET;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008121 }
Craig Mautner164d4bb2012-11-26 13:51:23 -08008122 mAppTransition.goodToGo();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008123 mStartingIconInTransition = false;
8124 mSkipAppTransitionAnimation = false;
8125
8126 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
8127
Craig Mautneref25d7a2012-05-15 23:01:47 -07008128 rebuildAppWindowListLocked();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008129
Craig Mautner0afddcb2012-05-08 15:38:00 -07008130 // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
Craig Mautner83339b42012-05-01 22:13:23 -07008131 WindowState oldWallpaper =
8132 mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
Craig Mautner0afddcb2012-05-08 15:38:00 -07008133 && !mWallpaperTarget.mWinAnimator.isDummyAnimation()
Craig Mautner83339b42012-05-01 22:13:23 -07008134 ? null : mWallpaperTarget;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008135
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008136 mInnerFields.mWallpaperMayChange = false;
8137
8138 // The top-most window will supply the layout params,
8139 // and we will determine it below.
8140 LayoutParams animLp = null;
8141 int bestAnimLayer = -1;
8142 boolean fullscreenAnim = false;
8143
8144 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8145 "New wallpaper target=" + mWallpaperTarget
Daniel Sandlerab886f52012-06-04 14:36:25 -04008146 + ", oldWallpaper=" + oldWallpaper
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008147 + ", lower target=" + mLowerWallpaperTarget
8148 + ", upper target=" + mUpperWallpaperTarget);
Craig Mautnerae446592012-12-06 19:05:05 -08008149
8150 boolean openingAppHasWallpaper = false;
8151 boolean closingAppHasWallpaper = false;
8152 final AppWindowToken lowerWallpaperAppToken;
8153 final AppWindowToken upperWallpaperAppToken;
8154 if (mLowerWallpaperTarget == null) {
8155 lowerWallpaperAppToken = upperWallpaperAppToken = null;
8156 } else {
8157 lowerWallpaperAppToken = mLowerWallpaperTarget.mAppToken;
8158 upperWallpaperAppToken = mUpperWallpaperTarget.mAppToken;
8159 }
8160
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008161 // Do a first pass through the tokens for two
8162 // things:
8163 // (1) Determine if both the closing and opening
8164 // app token sets are wallpaper targets, in which
8165 // case special animations are needed
8166 // (since the wallpaper needs to stay static
8167 // behind them).
8168 // (2) Find the layout params of the top-most
8169 // application window in the tokens, which is
8170 // what will control the animation theme.
8171 final int NC = mClosingApps.size();
8172 NN = NC + mOpeningApps.size();
8173 for (i=0; i<NN; i++) {
Craig Mautnerae446592012-12-06 19:05:05 -08008174 final AppWindowToken wtoken;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008175 if (i < NC) {
8176 wtoken = mClosingApps.get(i);
Craig Mautnerae446592012-12-06 19:05:05 -08008177 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
8178 closingAppHasWallpaper = true;
8179 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008180 } else {
Craig Mautnerae446592012-12-06 19:05:05 -08008181 wtoken = mOpeningApps.get(i - NC);
8182 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
8183 openingAppHasWallpaper = true;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008184 }
8185 }
Craig Mautnerae446592012-12-06 19:05:05 -08008186
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008187 if (wtoken.appFullscreen) {
8188 WindowState ws = wtoken.findMainWindow();
8189 if (ws != null) {
8190 animLp = ws.mAttrs;
8191 bestAnimLayer = ws.mLayer;
8192 fullscreenAnim = true;
8193 }
8194 } else if (!fullscreenAnim) {
8195 WindowState ws = wtoken.findMainWindow();
8196 if (ws != null) {
8197 if (ws.mLayer > bestAnimLayer) {
8198 animLp = ws.mAttrs;
8199 bestAnimLayer = ws.mLayer;
8200 }
8201 }
8202 }
8203 }
8204
Craig Mautnerae446592012-12-06 19:05:05 -08008205 if (closingAppHasWallpaper && openingAppHasWallpaper) {
8206 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Wallpaper animation!");
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008207 switch (transit) {
Craig Mautner4b71aa12012-12-27 17:20:01 -08008208 case AppTransition.TRANSIT_ACTIVITY_OPEN:
8209 case AppTransition.TRANSIT_TASK_OPEN:
8210 case AppTransition.TRANSIT_TASK_TO_FRONT:
8211 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008212 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08008213 case AppTransition.TRANSIT_ACTIVITY_CLOSE:
8214 case AppTransition.TRANSIT_TASK_CLOSE:
8215 case AppTransition.TRANSIT_TASK_TO_BACK:
8216 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008217 break;
8218 }
Craig Mautnerae446592012-12-06 19:05:05 -08008219 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "New transit: " + transit);
Daniel Sandlerab886f52012-06-04 14:36:25 -04008220 } else if ((oldWallpaper != null) && !mOpeningApps.contains(oldWallpaper.mAppToken)) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008221 // We are transitioning from an activity with
8222 // a wallpaper to one without.
Craig Mautner4b71aa12012-12-27 17:20:01 -08008223 transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008224 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8225 "New transit away from wallpaper: " + transit);
Craig Mautner8863cca2012-09-18 15:04:34 -07008226 } else if (mWallpaperTarget != null && mWallpaperTarget.isVisibleLw()) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008227 // We are transitioning from an activity without
8228 // a wallpaper to now showing the wallpaper
Craig Mautner4b71aa12012-12-27 17:20:01 -08008229 transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008230 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8231 "New transit into wallpaper: " + transit);
8232 }
8233
8234 // If all closing windows are obscured, then there is
8235 // no need to do an animation. This is the case, for
8236 // example, when this transition is being done behind
8237 // the lock screen.
8238 if (!mPolicy.allowAppAnimationsLw()) {
8239 animLp = null;
8240 }
8241
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008242 AppWindowToken topOpeningApp = null;
8243 int topOpeningLayer = 0;
8244
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008245 NN = mOpeningApps.size();
8246 for (i=0; i<NN; i++) {
8247 AppWindowToken wtoken = mOpeningApps.get(i);
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008248 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Craig Mautnerbec53f72012-04-05 11:49:05 -07008249 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008250 appAnimator.clearThumbnail();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008251 wtoken.inPendingTransaction = false;
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008252 appAnimator.animation = null;
Craig Mautnerbec53f72012-04-05 11:49:05 -07008253 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008254 wtoken.updateReportedVisibilityLocked();
8255 wtoken.waitingToShow = false;
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008256
8257 appAnimator.mAllAppWinAnimators.clear();
8258 final int N = wtoken.allAppWindows.size();
8259 for (int j = 0; j < N; j++) {
8260 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
8261 }
8262 mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
8263
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008264 if (animLp != null) {
8265 int layer = -1;
8266 for (int j=0; j<wtoken.windows.size(); j++) {
8267 WindowState win = wtoken.windows.get(j);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07008268 if (win.mWinAnimator.mAnimLayer > layer) {
8269 layer = win.mWinAnimator.mAnimLayer;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008270 }
8271 }
8272 if (topOpeningApp == null || layer > topOpeningLayer) {
8273 topOpeningApp = wtoken;
8274 topOpeningLayer = layer;
8275 }
8276 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008277 }
8278 NN = mClosingApps.size();
8279 for (i=0; i<NN; i++) {
8280 AppWindowToken wtoken = mClosingApps.get(i);
8281 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Craig Mautner8863cca2012-09-18 15:04:34 -07008282 "Now closing app " + wtoken);
Craig Mautner59431632012-04-04 11:56:44 -07008283 wtoken.mAppAnimator.clearThumbnail();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008284 wtoken.inPendingTransaction = false;
Craig Mautner59431632012-04-04 11:56:44 -07008285 wtoken.mAppAnimator.animation = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008286 setTokenVisibilityLocked(wtoken, animLp, false,
8287 transit, false);
8288 wtoken.updateReportedVisibilityLocked();
8289 wtoken.waitingToHide = false;
8290 // Force the allDrawn flag, because we want to start
8291 // this guy's animations regardless of whether it's
8292 // gotten drawn.
8293 wtoken.allDrawn = true;
Craig Mautner7636dfb2012-11-16 15:24:11 -08008294 wtoken.deferClearAllDrawn = false;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008295 }
8296
Craig Mautner164d4bb2012-11-26 13:51:23 -08008297 AppWindowAnimator appAnimator =
8298 topOpeningApp == null ? null : topOpeningApp.mAppAnimator;
8299 Bitmap nextAppTransitionThumbnail = mAppTransition.getNextAppTransitionThumbnail();
8300 if (nextAppTransitionThumbnail != null && appAnimator != null
8301 && appAnimator.animation != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008302 // This thumbnail animation is very special, we need to have
8303 // an extra surface with the thumbnail included with the animation.
Craig Mautner164d4bb2012-11-26 13:51:23 -08008304 Rect dirty = new Rect(0, 0, nextAppTransitionThumbnail.getWidth(),
8305 nextAppTransitionThumbnail.getHeight());
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008306 try {
Jeff Browne215f262012-09-10 16:01:14 -07008307 // TODO(multi-display): support other displays
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008308 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07008309 final Display display = displayContent.getDisplay();
Mathias Agopian29479eb2013-02-14 14:36:04 -08008310 SurfaceControl surfaceControl = new SurfaceControl(mFxSession,
Jeff Brown64a55af2012-08-26 02:47:39 -07008311 "thumbnail anim",
Craig Mautner6881a102012-07-27 13:04:51 -07008312 dirty.width(), dirty.height(),
Mathias Agopian3866f0d2013-02-11 22:08:48 -08008313 PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
Mathias Agopian29479eb2013-02-14 14:36:04 -08008314 surfaceControl.setLayerStack(display.getLayerStack());
8315 appAnimator.thumbnail = surfaceControl;
8316 if (SHOW_TRANSACTIONS) Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008317 Surface drawSurface = new Surface();
Mathias Agopian29479eb2013-02-14 14:36:04 -08008318 drawSurface.copyFrom(surfaceControl);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008319 Canvas c = drawSurface.lockCanvas(dirty);
Craig Mautner164d4bb2012-11-26 13:51:23 -08008320 c.drawBitmap(nextAppTransitionThumbnail, 0, 0, null);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008321 drawSurface.unlockCanvasAndPost(c);
8322 drawSurface.release();
Craig Mautner164d4bb2012-11-26 13:51:23 -08008323 appAnimator.thumbnailLayer = topOpeningLayer;
8324 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
8325 Animation anim = mAppTransition.createThumbnailAnimationLocked(
8326 transit, true, true, displayInfo.appWidth, displayInfo.appHeight);
8327 appAnimator.thumbnailAnimation = anim;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008328 anim.restrictDuration(MAX_ANIMATION_DURATION);
8329 anim.scaleCurrentDuration(mTransitionAnimationScale);
Craig Mautner164d4bb2012-11-26 13:51:23 -08008330 Point p = new Point();
8331 mAppTransition.getStartingPoint(p);
8332 appAnimator.thumbnailX = p.x;
8333 appAnimator.thumbnailY = p.y;
Mathias Agopian3866f0d2013-02-11 22:08:48 -08008334 } catch (SurfaceControl.OutOfResourcesException e) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008335 Slog.e(TAG, "Can't allocate thumbnail surface w=" + dirty.width()
8336 + " h=" + dirty.height(), e);
Craig Mautner164d4bb2012-11-26 13:51:23 -08008337 appAnimator.clearThumbnail();
Mathias Agopian3866f0d2013-02-11 22:08:48 -08008338 } catch (Surface.OutOfResourcesException e) {
8339 Slog.e(TAG, "Can't allocate Canvas surface w=" + dirty.width()
8340 + " h=" + dirty.height(), e);
8341 appAnimator.clearThumbnail();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008342 }
8343 }
8344
Craig Mautner164d4bb2012-11-26 13:51:23 -08008345 mAppTransition.postAnimationCallback();
8346 mAppTransition.clear();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008347
8348 mOpeningApps.clear();
8349 mClosingApps.clear();
8350
8351 // This has changed the visibility of windows, so perform
8352 // a new layout to get them all up-to-date.
Craig Mautner39834192012-09-02 07:47:24 -07008353 changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008354 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008355 getDefaultDisplayContentLocked().layoutNeeded = true;
Craig Mautner59c00972012-07-30 12:10:24 -07008356
8357 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008358 if (windows == getDefaultWindowListLocked()
8359 && !moveInputMethodWindowsIfNeededLocked(true)) {
Craig Mautner59c00972012-07-30 12:10:24 -07008360 assignLayersLocked(windows);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008361 }
Craig Mautner59c00972012-07-30 12:10:24 -07008362 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, false /*updateInputWindows*/);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008363 mFocusMayChange = false;
8364 }
8365
8366 return changes;
8367 }
8368
8369 /**
8370 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008371 * @return bitmap indicating if another pass through layout must be made.
8372 */
Craig Mautner2f995a72012-02-21 09:53:21 -08008373 private int handleAnimatingStoppedAndTransitionLocked() {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008374 int changes = 0;
8375
Craig Mautner9a29a5d2012-12-27 19:03:40 -08008376 mAppTransition.setIdle();
Craig Mautneref25d7a2012-05-15 23:01:47 -07008377 // Restore window app tokens to the ActivityManager views
Craig Mautner2ad92072013-02-25 16:19:24 -08008378 for (int i = mAnimatingAppTokens.size() - 1; i >= 0; i--) {
8379 mAnimatingAppTokens.get(i).sendingToBottom = false;
Craig Mautner3f99fde2012-06-19 14:10:01 -07008380 }
Craig Mautner2ad92072013-02-25 16:19:24 -08008381 mAnimatingAppTokens.clear();
8382 mAnimatingAppTokens.addAll(mAppTokens);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008383 rebuildAppWindowListLocked();
Craig Mautneref25d7a2012-05-15 23:01:47 -07008384
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008385 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Craig Mautnerae446592012-12-06 19:05:05 -08008386 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
8387 "Wallpaper layer changed: assigning layers + relayout");
Craig Mautneref25d7a2012-05-15 23:01:47 -07008388 moveInputMethodWindowsIfNeededLocked(true);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008389 mInnerFields.mWallpaperMayChange = true;
8390 // Since the window list has been rebuilt, focus might
8391 // have to be recomputed since the actual order of windows
8392 // might have changed again.
8393 mFocusMayChange = true;
8394
8395 return changes;
8396 }
8397
Craig Mautnere32c3072012-03-12 15:25:35 -07008398 private void updateResizingWindows(final WindowState w) {
Craig Mautnera608b882012-03-30 13:03:49 -07008399 final WindowStateAnimator winAnimator = w.mWinAnimator;
Craig Mautnerade0a9a2012-10-06 13:55:07 -07008400 if (w.mHasSurface && w.mLayoutSeq == mLayoutSeq) {
Dianne Hackbornc4aad012013-02-22 15:05:25 -08008401 w.mOverscanInsetsChanged |=
8402 !w.mLastOverscanInsets.equals(w.mOverscanInsets);
Craig Mautnere32c3072012-03-12 15:25:35 -07008403 w.mContentInsetsChanged |=
Dianne Hackborn5c58de32012-04-28 19:52:37 -07008404 !w.mLastContentInsets.equals(w.mContentInsets);
Craig Mautnere32c3072012-03-12 15:25:35 -07008405 w.mVisibleInsetsChanged |=
Dianne Hackborn5c58de32012-04-28 19:52:37 -07008406 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Craig Mautner812d2ca2012-09-27 15:35:34 -07008407 boolean configChanged = w.isConfigChanged();
Craig Mautnere32c3072012-03-12 15:25:35 -07008408 if (DEBUG_CONFIGURATION && configChanged) {
8409 Slog.v(TAG, "Win " + w + " config changed: "
8410 + mCurConfiguration);
8411 }
8412 if (localLOGV) Slog.v(TAG, "Resizing " + w
8413 + ": configChanged=" + configChanged
8414 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
8415 w.mLastFrame.set(w.mFrame);
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07008416 if (w.mContentInsetsChanged
Craig Mautnere32c3072012-03-12 15:25:35 -07008417 || w.mVisibleInsetsChanged
Craig Mautnera608b882012-03-30 13:03:49 -07008418 || winAnimator.mSurfaceResized
Craig Mautnere32c3072012-03-12 15:25:35 -07008419 || configChanged) {
8420 if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
8421 Slog.v(TAG, "Resize reasons: "
8422 + " contentInsetsChanged=" + w.mContentInsetsChanged
Craig Mautnerae446592012-12-06 19:05:05 -08008423 + " " + w.mContentInsets.toShortString()
Craig Mautnere32c3072012-03-12 15:25:35 -07008424 + " visibleInsetsChanged=" + w.mVisibleInsetsChanged
Craig Mautnerae446592012-12-06 19:05:05 -08008425 + " " + w.mVisibleInsets.toShortString()
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008426 + " surfaceResized=" + winAnimator.mSurfaceResized
Craig Mautnere32c3072012-03-12 15:25:35 -07008427 + " configChanged=" + configChanged);
8428 }
8429
Dianne Hackbornc4aad012013-02-22 15:05:25 -08008430 w.mLastOverscanInsets.set(w.mOverscanInsets);
Craig Mautnere32c3072012-03-12 15:25:35 -07008431 w.mLastContentInsets.set(w.mContentInsets);
8432 w.mLastVisibleInsets.set(w.mVisibleInsets);
8433 makeWindowFreezingScreenIfNeededLocked(w);
8434 // If the orientation is changing, then we need to
8435 // hold off on unfreezing the display until this
8436 // window has been redrawn; to do that, we need
8437 // to go through the process of getting informed
8438 // by the application when it has finished drawing.
8439 if (w.mOrientationChanging) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07008440 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautner83339b42012-05-01 22:13:23 -07008441 "Orientation start waiting for draw mDrawState=DRAW_PENDING in "
Mathias Agopian29479eb2013-02-14 14:36:04 -08008442 + w + ", surface " + winAnimator.mSurfaceControl);
Craig Mautner749a7bb2012-04-02 13:49:53 -07008443 winAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
Craig Mautnere32c3072012-03-12 15:25:35 -07008444 if (w.mAppToken != null) {
8445 w.mAppToken.allDrawn = false;
Craig Mautner7636dfb2012-11-16 15:24:11 -08008446 w.mAppToken.deferClearAllDrawn = false;
Craig Mautnere32c3072012-03-12 15:25:35 -07008447 }
8448 }
8449 if (!mResizingWindows.contains(w)) {
8450 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008451 "Resizing window " + w + " to " + winAnimator.mSurfaceW
8452 + "x" + winAnimator.mSurfaceH);
Craig Mautnere32c3072012-03-12 15:25:35 -07008453 mResizingWindows.add(w);
8454 }
8455 } else if (w.mOrientationChanging) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07008456 if (w.isDrawnLw()) {
Craig Mautnere32c3072012-03-12 15:25:35 -07008457 if (DEBUG_ORIENTATION) Slog.v(TAG,
8458 "Orientation not waiting for draw in "
Mathias Agopian29479eb2013-02-14 14:36:04 -08008459 + w + ", surface " + winAnimator.mSurfaceControl);
Craig Mautnere32c3072012-03-12 15:25:35 -07008460 w.mOrientationChanging = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07008461 w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
8462 - mDisplayFreezeTime);
Craig Mautnere32c3072012-03-12 15:25:35 -07008463 }
8464 }
8465 }
8466 }
8467
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008468 /**
8469 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
8470 *
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008471 * @param w WindowState this method is applied to.
8472 * @param currentTime The time which animations use for calculating transitions.
8473 * @param innerDw Width of app window.
8474 * @param innerDh Height of app window.
8475 */
8476 private void handleNotObscuredLocked(final WindowState w, final long currentTime,
8477 final int innerDw, final int innerDh) {
8478 final WindowManager.LayoutParams attrs = w.mAttrs;
8479 final int attrFlags = attrs.flags;
8480 final boolean canBeSeen = w.isDisplayedLw();
8481
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07008482 if (w.mHasSurface) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008483 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
8484 mInnerFields.mHoldScreen = w.mSession;
8485 }
8486 if (!mInnerFields.mSyswin && w.mAttrs.screenBrightness >= 0
8487 && mInnerFields.mScreenBrightness < 0) {
8488 mInnerFields.mScreenBrightness = w.mAttrs.screenBrightness;
8489 }
8490 if (!mInnerFields.mSyswin && w.mAttrs.buttonBrightness >= 0
8491 && mInnerFields.mButtonBrightness < 0) {
8492 mInnerFields.mButtonBrightness = w.mAttrs.buttonBrightness;
8493 }
Jeff Brown1e3b98d2012-09-30 18:58:59 -07008494 if (!mInnerFields.mSyswin && w.mAttrs.userActivityTimeout >= 0
8495 && mInnerFields.mUserActivityTimeout < 0) {
8496 mInnerFields.mUserActivityTimeout = w.mAttrs.userActivityTimeout;
8497 }
8498
Craig Mautner65d11b32012-10-01 13:59:52 -07008499 final int type = attrs.type;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008500 if (canBeSeen
Craig Mautner65d11b32012-10-01 13:59:52 -07008501 && (type == TYPE_SYSTEM_DIALOG
Craig Mautner88400d32012-09-30 12:35:45 -07008502 || type == TYPE_RECENTS_OVERLAY
Craig Mautner65d11b32012-10-01 13:59:52 -07008503 || type == TYPE_KEYGUARD
8504 || type == TYPE_SYSTEM_ERROR)) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008505 mInnerFields.mSyswin = true;
8506 }
Craig Mautner65d11b32012-10-01 13:59:52 -07008507
8508 if (canBeSeen) {
8509 if (type == TYPE_DREAM || type == TYPE_KEYGUARD) {
8510 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_MIRROR;
8511 } else if (mInnerFields.mDisplayHasContent
8512 == LayoutFields.DISPLAY_CONTENT_UNKNOWN) {
8513 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNIQUE;
8514 }
8515 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008516 }
8517
8518 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
8519 if (opaqueDrawn && w.isFullscreen(innerDw, innerDh)) {
8520 // This window completely covers everything behind it,
Craig Mautner2fb98b12012-03-20 17:24:00 -07008521 // so we want to leave all of them as undimmed (for
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008522 // performance reasons).
8523 mInnerFields.mObscured = true;
Craig Mautner312eac42012-11-13 10:56:22 -08008524 }
8525 }
8526
8527 private void handleFlagDimBehind(WindowState w, int innerDw, int innerDh) {
8528 final WindowManager.LayoutParams attrs = w.mAttrs;
8529 if ((attrs.flags & FLAG_DIM_BEHIND) != 0
8530 && w.isDisplayedLw()
Craig Mautner236a35b2012-06-08 09:54:59 -07008531 && !w.mExiting) {
Craig Mautner312eac42012-11-13 10:56:22 -08008532 mInnerFields.mDimming = true;
8533 final WindowStateAnimator winAnimator = w.mWinAnimator;
8534 if (!mAnimator.isDimmingLocked(winAnimator)) {
Craig Mautner312eac42012-11-13 10:56:22 -08008535 if (localLOGV) Slog.v(TAG, "Win " + w + " start dimming.");
Craig Mautner1420b932012-12-28 17:14:38 -08008536 startDimmingLocked(winAnimator, w.mExiting ? 0 : w.mAttrs.dimAmount);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008537 }
8538 }
8539 }
8540
Craig Mautner2ad92072013-02-25 16:19:24 -08008541 private void updateAllDrawnLocked() {
Craig Mautner6fbda632012-07-03 09:26:39 -07008542 // See if any windows have been drawn, so they (and others
8543 // associated with them) can now be shown.
Craig Mautner2ad92072013-02-25 16:19:24 -08008544 final ArrayList<AppWindowToken> appTokens = mAnimatingAppTokens;
8545 final int NT = appTokens.size();
8546 for (int i=0; i<NT; i++) {
8547 AppWindowToken wtoken = appTokens.get(i);
Craig Mautner6fbda632012-07-03 09:26:39 -07008548 if (!wtoken.allDrawn) {
8549 int numInteresting = wtoken.numInterestingWindows;
8550 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
8551 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
8552 "allDrawn: " + wtoken
8553 + " interesting=" + numInteresting
8554 + " drawn=" + wtoken.numDrawnWindows);
8555 wtoken.allDrawn = true;
8556 }
8557 }
8558 }
8559 }
8560
Brad Fitzpatrick68044332010-11-22 18:19:48 -08008561 // "Something has changed! Let's make it correct now."
Craig Mautner76a71652012-09-03 23:23:58 -07008562 private final void performLayoutAndPlaceSurfacesLockedInner(boolean recoveringMemory) {
Craig Mautner7d8df392012-04-06 15:26:23 -07008563 if (DEBUG_WINDOW_TRACE) {
Craig Mautner3255a282012-04-16 15:42:47 -07008564 Slog.v(TAG, "performLayoutAndPlaceSurfacesLockedInner: entry. Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -07008565 + Debug.getCallers(3));
Craig Mautner7d8df392012-04-06 15:26:23 -07008566 }
Joe Onorato34bcebc2010-07-07 18:05:01 -04008567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008568 final long currentTime = SystemClock.uptimeMillis();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008569
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008570 int i;
8571
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008572 if (mFocusMayChange) {
8573 mFocusMayChange = false;
Jeff Brown3a22cd92011-01-21 13:59:04 -08008574 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
8575 false /*updateInputWindows*/);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008576 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008577
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008578 // Initialize state of exiting tokens.
Craig Mautner2ad92072013-02-25 16:19:24 -08008579 for (i=mExitingTokens.size()-1; i>=0; i--) {
8580 mExitingTokens.get(i).hasVisible = false;
8581 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008582
Craig Mautner2ad92072013-02-25 16:19:24 -08008583 // Initialize state of exiting applications.
8584 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
8585 mExitingAppTokens.get(i).hasVisible = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008586 }
8587
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008588 mInnerFields.mHoldScreen = null;
8589 mInnerFields.mScreenBrightness = -1;
8590 mInnerFields.mButtonBrightness = -1;
Jeff Brown1e3b98d2012-09-30 18:58:59 -07008591 mInnerFields.mUserActivityTimeout = -1;
Craig Mautner65d11b32012-10-01 13:59:52 -07008592 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNKNOWN;
Jeff Brown1e3b98d2012-09-30 18:58:59 -07008593
Craig Mautner6fbda632012-07-03 09:26:39 -07008594 mTransactionSequence++;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07008595
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008596 final DisplayContent defaultDisplay = getDefaultDisplayContentLocked();
Craig Mautner76a71652012-09-03 23:23:58 -07008597 final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
8598 final int defaultDw = defaultInfo.logicalWidth;
8599 final int defaultDh = defaultInfo.logicalHeight;
Craig Mautner76a71652012-09-03 23:23:58 -07008600
Dianne Hackborn36991742011-10-11 21:35:26 -07008601 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
8602 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
Mathias Agopian3866f0d2013-02-11 22:08:48 -08008603 SurfaceControl.openTransaction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008604 try {
Craig Mautner76a71652012-09-03 23:23:58 -07008605
Jeff Brown4ed8fe72012-08-30 18:18:29 -07008606 if (mWatermark != null) {
Craig Mautner76a71652012-09-03 23:23:58 -07008607 mWatermark.positionSurface(defaultDw, defaultDh);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07008608 }
8609 if (mStrictModeFlash != null) {
Craig Mautner76a71652012-09-03 23:23:58 -07008610 mStrictModeFlash.positionSurface(defaultDw, defaultDh);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07008611 }
8612
Craig Mautner7358fbf2012-04-12 21:06:33 -07008613 boolean focusDisplayed = false;
Craig Mautner2ad92072013-02-25 16:19:24 -08008614 boolean updateAllDrawn = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008615
Craig Mautner7c6be102013-07-16 12:30:28 -07008616 final int numDisplays = mDisplayContents.size();
8617 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
8618 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautner76a71652012-09-03 23:23:58 -07008619 WindowList windows = displayContent.getWindowList();
8620 DisplayInfo displayInfo = displayContent.getDisplayInfo();
Craig Mautner19d59bc2012-09-04 11:15:56 -07008621 final int displayId = displayContent.getDisplayId();
Craig Mautner76a71652012-09-03 23:23:58 -07008622 final int dw = displayInfo.logicalWidth;
8623 final int dh = displayInfo.logicalHeight;
8624 final int innerDw = displayInfo.appWidth;
8625 final int innerDh = displayInfo.appHeight;
Craig Mautner19d59bc2012-09-04 11:15:56 -07008626 final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008627
Craig Mautner65d11b32012-10-01 13:59:52 -07008628 // Reset for each display unless we are forcing mirroring.
8629 if (mInnerFields.mDisplayHasContent != LayoutFields.DISPLAY_CONTENT_MIRROR) {
8630 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNKNOWN;
8631 }
8632
Craig Mautner76a71652012-09-03 23:23:58 -07008633 int repeats = 0;
8634 do {
8635 repeats++;
8636 if (repeats > 6) {
8637 Slog.w(TAG, "Animation repeat aborted after too many iterations");
Craig Mautner76a71652012-09-03 23:23:58 -07008638 displayContent.layoutNeeded = false;
8639 break;
Craig Mautner5702d4d2012-06-30 14:10:16 -07008640 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008641
Craig Mautner76a71652012-09-03 23:23:58 -07008642 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("On entry to LockedInner",
8643 displayContent.pendingLayoutChanges);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008644
Craig Mautner0bf6ec92012-12-18 08:33:27 -08008645 if ((displayContent.pendingLayoutChanges &
8646 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
8647 (adjustWallpaperWindowsLocked() &
8648 ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Craig Mautner76a71652012-09-03 23:23:58 -07008649 assignLayersLocked(windows);
Craig Mautner76a71652012-09-03 23:23:58 -07008650 displayContent.layoutNeeded = true;
8651 }
8652
8653 if (isDefaultDisplay && (displayContent.pendingLayoutChanges
8654 & WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
8655 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
8656 if (updateOrientationFromAppTokensLocked(true)) {
Craig Mautner76a71652012-09-03 23:23:58 -07008657 displayContent.layoutNeeded = true;
8658 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008659 }
8660 }
8661
Craig Mautner76a71652012-09-03 23:23:58 -07008662 if ((displayContent.pendingLayoutChanges
8663 & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
Craig Mautner76a71652012-09-03 23:23:58 -07008664 displayContent.layoutNeeded = true;
Craig Mautner6fbda632012-07-03 09:26:39 -07008665 }
Craig Mautner76a71652012-09-03 23:23:58 -07008666
8667 // FIRST LOOP: Perform a layout, if needed.
8668 if (repeats < 4) {
8669 performLayoutLockedInner(displayContent, repeats == 1,
8670 false /*updateInputWindows*/);
8671 } else {
8672 Slog.w(TAG, "Layout repeat skipped after too many iterations");
8673 }
8674
8675 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
8676 // it is animating.
8677 displayContent.pendingLayoutChanges = 0;
8678
8679 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("loop number "
8680 + mLayoutRepeatCount, displayContent.pendingLayoutChanges);
8681
Craig Mautner69b08182012-09-05 13:07:13 -07008682 if (isDefaultDisplay) {
8683 mPolicy.beginPostLayoutPolicyLw(dw, dh);
8684 for (i = windows.size() - 1; i >= 0; i--) {
8685 WindowState w = windows.get(i);
8686 if (w.mHasSurface) {
8687 mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs);
8688 }
Craig Mautner6fbda632012-07-03 09:26:39 -07008689 }
Craig Mautner69b08182012-09-05 13:07:13 -07008690 displayContent.pendingLayoutChanges |= mPolicy.finishPostLayoutPolicyLw();
8691 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
8692 "after finishPostLayoutPolicyLw", displayContent.pendingLayoutChanges);
Craig Mautner76a71652012-09-03 23:23:58 -07008693 }
Craig Mautner76a71652012-09-03 23:23:58 -07008694 } while (displayContent.pendingLayoutChanges != 0);
8695
8696 mInnerFields.mObscured = false;
8697 mInnerFields.mDimming = false;
8698 mInnerFields.mSyswin = false;
8699
8700 // Only used if default window
8701 final boolean someoneLosingFocus = !mLosingFocus.isEmpty();
8702
8703 final int N = windows.size();
8704 for (i=N-1; i>=0; i--) {
8705 WindowState w = windows.get(i);
8706
8707 final boolean obscuredChanged = w.mObscured != mInnerFields.mObscured;
8708
8709 // Update effect.
8710 w.mObscured = mInnerFields.mObscured;
8711 if (!mInnerFields.mObscured) {
8712 handleNotObscuredLocked(w, currentTime, innerDw, innerDh);
8713 }
8714
Craig Mautner312eac42012-11-13 10:56:22 -08008715 if (!mInnerFields.mDimming) {
8716 handleFlagDimBehind(w, innerDw, innerDh);
8717 }
8718
Craig Mautner76a71652012-09-03 23:23:58 -07008719 if (isDefaultDisplay && obscuredChanged && (mWallpaperTarget == w)
8720 && w.isVisibleLw()) {
8721 // This is the wallpaper target and its obscured state
8722 // changed... make sure the current wallaper's visibility
8723 // has been updated accordingly.
8724 updateWallpaperVisibilityLocked();
8725 }
8726
8727 final WindowStateAnimator winAnimator = w.mWinAnimator;
8728
8729 // If the window has moved due to its containing
8730 // content frame changing, then we'd like to animate
8731 // it.
8732 if (w.mHasSurface && w.shouldAnimateMove()) {
8733 // Frame has moved, containing content frame
8734 // has also moved, and we're not currently animating...
8735 // let's do something.
8736 Animation a = AnimationUtils.loadAnimation(mContext,
8737 com.android.internal.R.anim.window_move_from_decor);
8738 winAnimator.setAnimation(a);
8739 winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
8740 winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
8741 try {
8742 w.mClient.moved(w.mFrame.left, w.mFrame.top);
8743 } catch (RemoteException e) {
8744 }
8745 }
8746
8747 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
8748 w.mContentChanged = false;
8749
8750 // Moved from updateWindowsAndWallpaperLocked().
8751 if (w.mHasSurface) {
8752 // Take care of the window being ready to display.
Craig Mautner69b08182012-09-05 13:07:13 -07008753 final boolean committed =
8754 winAnimator.commitFinishDrawingLocked(currentTime);
8755 if (isDefaultDisplay && committed) {
Dianne Hackborn7ad44382012-10-18 17:46:00 -07008756 if (w.mAttrs.type == TYPE_DREAM) {
8757 // HACK: When a dream is shown, it may at that
8758 // point hide the lock screen. So we need to
8759 // redo the layout to let the phone window manager
8760 // make this happen.
8761 displayContent.pendingLayoutChanges |=
8762 WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
8763 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
8764 debugLayoutRepeats(
8765 "dream and commitFinishDrawingLocked true",
8766 displayContent.pendingLayoutChanges);
8767 }
8768 }
Craig Mautner65d11b32012-10-01 13:59:52 -07008769 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07008770 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Craig Mautner76a71652012-09-03 23:23:58 -07008771 "First draw done in potential wallpaper target " + w);
8772 mInnerFields.mWallpaperMayChange = true;
8773 displayContent.pendingLayoutChanges |=
8774 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
8775 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
8776 debugLayoutRepeats(
8777 "wallpaper and commitFinishDrawingLocked true",
8778 displayContent.pendingLayoutChanges);
Craig Mautner6fbda632012-07-03 09:26:39 -07008779 }
8780 }
Craig Mautner76a71652012-09-03 23:23:58 -07008781 }
8782
Craig Mautnera91f9e22012-09-14 16:22:08 -07008783 winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
Craig Mautner76a71652012-09-03 23:23:58 -07008784
8785 final AppWindowToken atoken = w.mAppToken;
Craig Mautner65d11b32012-10-01 13:59:52 -07008786 if (DEBUG_STARTING_WINDOW && atoken != null
8787 && w == atoken.startingWindow) {
Craig Mautner76a71652012-09-03 23:23:58 -07008788 Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen="
8789 + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
8790 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
8791 }
8792 if (atoken != null
8793 && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
8794 if (atoken.lastTransactionSequence != mTransactionSequence) {
8795 atoken.lastTransactionSequence = mTransactionSequence;
8796 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
8797 atoken.startingDisplayed = false;
8798 }
Craig Mautner65d11b32012-10-01 13:59:52 -07008799 if ((w.isOnScreen() || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
Craig Mautner76a71652012-09-03 23:23:58 -07008800 && !w.mExiting && !w.mDestroying) {
8801 if (WindowManagerService.DEBUG_VISIBILITY ||
8802 WindowManagerService.DEBUG_ORIENTATION) {
8803 Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
8804 + ", isAnimating=" + winAnimator.isAnimating());
8805 if (!w.isDrawnLw()) {
Mathias Agopian29479eb2013-02-14 14:36:04 -08008806 Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceControl
Craig Mautner76a71652012-09-03 23:23:58 -07008807 + " pv=" + w.mPolicyVisibility
8808 + " mDrawState=" + winAnimator.mDrawState
8809 + " ah=" + w.mAttachedHidden
8810 + " th=" + atoken.hiddenRequested
8811 + " a=" + winAnimator.mAnimating);
Craig Mautner6fbda632012-07-03 09:26:39 -07008812 }
8813 }
Craig Mautner76a71652012-09-03 23:23:58 -07008814 if (w != atoken.startingWindow) {
8815 if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
8816 atoken.numInterestingWindows++;
8817 if (w.isDrawnLw()) {
8818 atoken.numDrawnWindows++;
8819 if (WindowManagerService.DEBUG_VISIBILITY ||
8820 WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
8821 "tokenMayBeDrawn: " + atoken
8822 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen
8823 + " mAppFreezing=" + w.mAppFreezing);
8824 updateAllDrawn = true;
8825 }
8826 }
8827 } else if (w.isDrawnLw()) {
8828 atoken.startingDisplayed = true;
8829 }
Craig Mautner6fbda632012-07-03 09:26:39 -07008830 }
8831 }
8832 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008833
Craig Mautner76a71652012-09-03 23:23:58 -07008834 if (isDefaultDisplay && someoneLosingFocus && (w == mCurrentFocus)
8835 && w.isDisplayedLw()) {
8836 focusDisplayed = true;
8837 }
Craig Mautner51bb12b2012-04-27 14:39:53 -07008838
Craig Mautner76a71652012-09-03 23:23:58 -07008839 updateResizingWindows(w);
8840 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07008841
Craig Mautner65d11b32012-10-01 13:59:52 -07008842 final boolean hasUniqueContent;
8843 switch (mInnerFields.mDisplayHasContent) {
8844 case LayoutFields.DISPLAY_CONTENT_MIRROR:
8845 hasUniqueContent = isDefaultDisplay;
8846 break;
8847 case LayoutFields.DISPLAY_CONTENT_UNIQUE:
8848 hasUniqueContent = true;
8849 break;
8850 case LayoutFields.DISPLAY_CONTENT_UNKNOWN:
8851 default:
8852 hasUniqueContent = false;
8853 break;
8854 }
8855 mDisplayManagerService.setDisplayHasContent(displayId, hasUniqueContent,
8856 true /* inTraversal, must call performTraversalInTrans... below */);
8857
Craig Mautnera91f9e22012-09-14 16:22:08 -07008858 if (!mInnerFields.mDimming && mAnimator.isDimmingLocked(displayId)) {
8859 stopDimmingLocked(displayId);
8860 }
Craig Mautner2ad92072013-02-25 16:19:24 -08008861 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008862
Craig Mautner2ad92072013-02-25 16:19:24 -08008863 if (updateAllDrawn) {
8864 updateAllDrawnLocked();
Craig Mautner6fbda632012-07-03 09:26:39 -07008865 }
8866
Craig Mautner7358fbf2012-04-12 21:06:33 -07008867 if (focusDisplayed) {
8868 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
8869 }
Craig Mautner65d11b32012-10-01 13:59:52 -07008870
8871 // Give the display manager a chance to adjust properties
8872 // like display rotation if it needs to.
8873 mDisplayManagerService.performTraversalInTransactionFromWindowManager();
8874
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008875 } catch (RuntimeException e) {
Dianne Hackborn89620282011-09-11 12:47:45 -07008876 Log.wtf(TAG, "Unhandled exception in Window Manager", e);
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07008877 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -08008878 SurfaceControl.closeTransaction();
Chet Haased5d11af2012-10-31 08:57:17 -07008879 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
8880 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008881 }
8882
Craig Mautner76a71652012-09-03 23:23:58 -07008883 final WindowList defaultWindows = defaultDisplay.getWindowList();
8884
Craig Mautner764983d2012-03-22 11:37:36 -07008885 // If we are ready to perform an app transition, check through
8886 // all of the app tokens to be shown and see if they are ready
8887 // to go.
Craig Mautner164d4bb2012-11-26 13:51:23 -08008888 if (mAppTransition.isReady()) {
Craig Mautner76a71652012-09-03 23:23:58 -07008889 defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07008890 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAppTransitionReadyLocked",
Craig Mautnerae446592012-12-06 19:05:05 -08008891 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07008892 }
8893
Craig Mautner164d4bb2012-11-26 13:51:23 -08008894 if (!mAnimator.mAnimating && mAppTransition.isRunning()) {
Craig Mautner764983d2012-03-22 11:37:36 -07008895 // We have finished the animation of an app transition. To do
8896 // this, we have delayed a lot of operations like showing and
8897 // hiding apps, moving apps in Z-order, etc. The app token list
8898 // reflects the correct Z-order, but the window list may now
8899 // be out of sync with it. So here we will just rebuild the
8900 // entire app window list. Fun!
Craig Mautner76a71652012-09-03 23:23:58 -07008901 defaultDisplay.pendingLayoutChanges |= handleAnimatingStoppedAndTransitionLocked();
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07008902 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAnimStopAndXitionLock",
Craig Mautner76a71652012-09-03 23:23:58 -07008903 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07008904 }
8905
Craig Mautner76a71652012-09-03 23:23:58 -07008906 if (mInnerFields.mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
Craig Mautner164d4bb2012-11-26 13:51:23 -08008907 && !mAppTransition.isReady()) {
Craig Mautner764983d2012-03-22 11:37:36 -07008908 // At this point, there was a window with a wallpaper that
8909 // was force hiding other windows behind it, but now it
8910 // is going away. This may be simple -- just animate
8911 // away the wallpaper and its window -- or it may be
8912 // hard -- the wallpaper now needs to be shown behind
8913 // something that was hidden.
Craig Mautnerae446592012-12-06 19:05:05 -08008914 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07008915 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animateAwayWallpaperLocked",
Craig Mautner76a71652012-09-03 23:23:58 -07008916 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07008917 }
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07008918 mInnerFields.mWallpaperForceHidingChanged = false;
Craig Mautner764983d2012-03-22 11:37:36 -07008919
Craig Mautnere7ae2502012-03-26 17:11:19 -07008920 if (mInnerFields.mWallpaperMayChange) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07008921 if (WindowManagerService.DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Craig Mautnere7ae2502012-03-26 17:11:19 -07008922 "Wallpaper may change! Adjusting");
Craig Mautnerae446592012-12-06 19:05:05 -08008923 defaultDisplay.pendingLayoutChanges |=
8924 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
8925 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
8926 defaultDisplay.pendingLayoutChanges);
Craig Mautnere7ae2502012-03-26 17:11:19 -07008927 }
8928
8929 if (mFocusMayChange) {
8930 mFocusMayChange = false;
8931 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
8932 false /*updateInputWindows*/)) {
Craig Mautner76a71652012-09-03 23:23:58 -07008933 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
Craig Mautnere7ae2502012-03-26 17:11:19 -07008934 }
8935 }
Craig Mautner764983d2012-03-22 11:37:36 -07008936
Craig Mautner19d59bc2012-09-04 11:15:56 -07008937 if (needsLayout()) {
Craig Mautner76a71652012-09-03 23:23:58 -07008938 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
8939 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
8940 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07008941 }
8942
Craig Mautnerade0a9a2012-10-06 13:55:07 -07008943 for (i = mResizingWindows.size() - 1; i >= 0; i--) {
8944 WindowState win = mResizingWindows.get(i);
8945 if (win.mAppFreezing) {
8946 // Don't remove this window until rotation has completed.
8947 continue;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07008948 }
Craig Mautnerade0a9a2012-10-06 13:55:07 -07008949 final WindowStateAnimator winAnimator = win.mWinAnimator;
8950 try {
8951 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
8952 "Reporting new frame to " + win + ": " + win.mCompatFrame);
8953 int diff = 0;
8954 boolean configChanged = win.isConfigChanged();
Dianne Hackborn7ff30112012-11-08 11:12:09 -08008955 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
Craig Mautnerade0a9a2012-10-06 13:55:07 -07008956 && configChanged) {
8957 Slog.i(TAG, "Sending new config to window " + win + ": "
8958 + winAnimator.mSurfaceW + "x" + winAnimator.mSurfaceH
8959 + " / " + mCurConfiguration + " / 0x"
8960 + Integer.toHexString(diff));
8961 }
Craig Mautnere8552142012-11-07 13:55:47 -08008962 win.setConfiguration(mCurConfiguration);
Craig Mautnerade0a9a2012-10-06 13:55:07 -07008963 if (DEBUG_ORIENTATION &&
8964 winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) Slog.i(
8965 TAG, "Resizing " + win + " WITH DRAW PENDING");
Sangkyu Lee0438bd62013-01-16 14:53:17 +09008966 final IWindow client = win.mClient;
8967 final Rect frame = win.mFrame;
8968 final Rect overscanInsets = win.mLastOverscanInsets;
8969 final Rect contentInsets = win.mLastContentInsets;
8970 final Rect visibleInsets = win.mLastVisibleInsets;
8971 final boolean reportDraw
8972 = winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING;
8973 final Configuration newConfig = configChanged ? win.mConfiguration : null;
8974 if (win.mClient instanceof IWindow.Stub) {
8975 // To prevent deadlock simulate one-way call if win.mClient is a local object.
8976 mH.post(new Runnable() {
8977 @Override
8978 public void run() {
8979 try {
8980 client.resized(frame, overscanInsets, contentInsets,
8981 visibleInsets, reportDraw, newConfig);
8982 } catch (RemoteException e) {
8983 // Not a remote call, RemoteException won't be raised.
8984 }
8985 }
8986 });
8987 } else {
8988 client.resized(frame, overscanInsets, contentInsets, visibleInsets, reportDraw,
8989 newConfig);
8990 }
Dianne Hackbornc4aad012013-02-22 15:05:25 -08008991 win.mOverscanInsetsChanged = false;
Craig Mautnerade0a9a2012-10-06 13:55:07 -07008992 win.mContentInsetsChanged = false;
8993 win.mVisibleInsetsChanged = false;
8994 winAnimator.mSurfaceResized = false;
8995 } catch (RemoteException e) {
8996 win.mOrientationChanging = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07008997 win.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
8998 - mDisplayFreezeTime);
Craig Mautnerade0a9a2012-10-06 13:55:07 -07008999 }
9000 mResizingWindows.remove(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009001 }
Romain Guy06882f82009-06-10 13:36:04 -07009002
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009003 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
9004 "With display frozen, orientationChangeComplete="
9005 + mInnerFields.mOrientationChangeComplete);
9006 if (mInnerFields.mOrientationChangeComplete) {
9007 if (mWindowsFreezingScreen) {
9008 mWindowsFreezingScreen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009009 mLastFinishedFreezeSource = mInnerFields.mLastWindowFreezeSource;
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009010 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
9011 }
9012 stopFreezingDisplayLocked();
9013 }
9014
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009015 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009016 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009017 i = mDestroySurface.size();
9018 if (i > 0) {
9019 do {
9020 i--;
9021 WindowState win = mDestroySurface.get(i);
9022 win.mDestroying = false;
9023 if (mInputMethodWindow == win) {
9024 mInputMethodWindow = null;
9025 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009026 if (win == mWallpaperTarget) {
9027 wallpaperDestroyed = true;
9028 }
Craig Mautner96868332012-12-04 14:29:11 -08009029 win.mWinAnimator.destroySurfaceLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009030 } while (i > 0);
9031 mDestroySurface.clear();
9032 }
9033
9034 // Time to remove any exiting tokens?
Craig Mautner2ad92072013-02-25 16:19:24 -08009035 for (i=mExitingTokens.size()-1; i>=0; i--) {
9036 WindowToken token = mExitingTokens.get(i);
9037 if (!token.hasVisible) {
9038 mExitingTokens.remove(i);
9039 if (token.windowType == TYPE_WALLPAPER) {
9040 mWallpaperTokens.remove(token);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07009041 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009042 }
Craig Mautner2ad92072013-02-25 16:19:24 -08009043 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009044
Craig Mautner2ad92072013-02-25 16:19:24 -08009045 // Time to remove any exiting applications?
9046 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
9047 AppWindowToken token = mExitingAppTokens.get(i);
9048 if (!token.hasVisible && !mClosingApps.contains(token)) {
9049 // Make sure there is no animation running on this token,
9050 // so any windows associated with it will be removed as
9051 // soon as their animations are complete
9052 token.mAppAnimator.clearAnimation();
9053 token.mAppAnimator.animating = false;
9054 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
9055 "performLayout: App token exiting now removed" + token);
9056 mAppTokens.remove(token);
9057 mAnimatingAppTokens.remove(token);
9058 mExitingAppTokens.remove(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009059 }
9060 }
9061
Dianne Hackborn12d3a942012-04-27 14:16:30 -07009062 if (!mAnimator.mAnimating && mRelayoutWhileAnimating.size() > 0) {
9063 for (int j=mRelayoutWhileAnimating.size()-1; j>=0; j--) {
9064 try {
9065 mRelayoutWhileAnimating.get(j).mClient.doneAnimating();
9066 } catch (RemoteException e) {
9067 }
9068 }
9069 mRelayoutWhileAnimating.clear();
9070 }
9071
Craig Mautnerae446592012-12-06 19:05:05 -08009072 if (wallpaperDestroyed) {
9073 defaultDisplay.pendingLayoutChanges |=
9074 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
9075 defaultDisplay.layoutNeeded = true;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009076 }
Craig Mautner76a71652012-09-03 23:23:58 -07009077
Craig Mautner7c6be102013-07-16 12:30:28 -07009078 final int numDisplays = mDisplayContents.size();
9079 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9080 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautner76a71652012-09-03 23:23:58 -07009081 if (displayContent.pendingLayoutChanges != 0) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009082 displayContent.layoutNeeded = true;
Craig Mautner76a71652012-09-03 23:23:58 -07009083 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009084 }
Jeff Browneb857f12010-07-16 10:06:33 -07009085
Jeff Brown3a22cd92011-01-21 13:59:04 -08009086 // Finally update all input windows now that the window changes have stabilized.
Jeff Brown2e44b072011-01-24 15:21:56 -08009087 mInputMonitor.updateInputWindowsLw(true /*force*/);
Jeff Browneb857f12010-07-16 10:06:33 -07009088
Craig Mautner259328c2012-08-21 19:30:58 -07009089 setHoldScreenLocked(mInnerFields.mHoldScreen);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009090 if (!mDisplayFrozen) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009091 if (mInnerFields.mScreenBrightness < 0 || mInnerFields.mScreenBrightness > 1.0f) {
Jeff Brown96307042012-07-27 15:51:34 -07009092 mPowerManager.setScreenBrightnessOverrideFromWindowManager(-1);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009093 } else {
Jeff Brown96307042012-07-27 15:51:34 -07009094 mPowerManager.setScreenBrightnessOverrideFromWindowManager(
9095 toBrightnessOverride(mInnerFields.mScreenBrightness));
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009096 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009097 if (mInnerFields.mButtonBrightness < 0 || mInnerFields.mButtonBrightness > 1.0f) {
Jeff Brown96307042012-07-27 15:51:34 -07009098 mPowerManager.setButtonBrightnessOverrideFromWindowManager(-1);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009099 } else {
Jeff Brown96307042012-07-27 15:51:34 -07009100 mPowerManager.setButtonBrightnessOverrideFromWindowManager(
9101 toBrightnessOverride(mInnerFields.mButtonBrightness));
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009102 }
Jeff Brown1e3b98d2012-09-30 18:58:59 -07009103 mPowerManager.setUserActivityTimeoutOverrideFromWindowManager(
9104 mInnerFields.mUserActivityTimeout);
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009105 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009106
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009107 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009108 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Jeff Brown96307042012-07-27 15:51:34 -07009109 mPowerManager.wakeUp(SystemClock.uptimeMillis());
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009110 mTurnOnScreen = false;
9111 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009112
Craig Mautnera608b882012-03-30 13:03:49 -07009113 if (mInnerFields.mUpdateRotation) {
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009114 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009115 if (updateRotationUncheckedLocked(false)) {
Dianne Hackborn3e4f9d02011-02-04 14:05:55 -08009116 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07009117 } else {
Craig Mautnera608b882012-03-30 13:03:49 -07009118 mInnerFields.mUpdateRotation = false;
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009119 }
9120 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009121
Craig Mautner19d59bc2012-09-04 11:15:56 -07009122 if (mInnerFields.mOrientationChangeComplete && !defaultDisplay.layoutNeeded
9123 && !mInnerFields.mUpdateRotation) {
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07009124 checkDrawnWindowsLocked();
9125 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009126
Craig Mautner76a71652012-09-03 23:23:58 -07009127 final int N = mPendingRemove.size();
9128 if (N > 0) {
9129 if (mPendingRemoveTmp.length < N) {
9130 mPendingRemoveTmp = new WindowState[N+10];
9131 }
9132 mPendingRemove.toArray(mPendingRemoveTmp);
9133 mPendingRemove.clear();
9134 DisplayContentList displayList = new DisplayContentList();
9135 for (i = 0; i < N; i++) {
9136 WindowState w = mPendingRemoveTmp[i];
9137 removeWindowInnerLocked(w.mSession, w);
9138 if (!displayList.contains(w.mDisplayContent)) {
9139 displayList.add(w.mDisplayContent);
9140 }
9141 }
9142
9143 for (DisplayContent displayContent : displayList) {
9144 assignLayersLocked(displayContent.getWindowList());
Craig Mautner19d59bc2012-09-04 11:15:56 -07009145 displayContent.layoutNeeded = true;
Craig Mautner76a71652012-09-03 23:23:58 -07009146 }
Craig Mautner76a71652012-09-03 23:23:58 -07009147 }
9148
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08009149 // Check to see if we are now in a state where the screen should
9150 // be enabled, because the window obscured flags have changed.
9151 enableScreenIfNeededLocked();
Craig Mautner7d8df392012-04-06 15:26:23 -07009152
Craig Mautner96868332012-12-04 14:29:11 -08009153 scheduleAnimationLocked();
Craig Mautner7d8df392012-04-06 15:26:23 -07009154
9155 if (DEBUG_WINDOW_TRACE) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009156 Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: animating="
9157 + mAnimator.mAnimating);
Craig Mautner7d8df392012-04-06 15:26:23 -07009158 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009159 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009160
Jeff Brown96307042012-07-27 15:51:34 -07009161 private int toBrightnessOverride(float value) {
9162 return (int)(value * PowerManager.BRIGHTNESS_ON);
9163 }
9164
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009165 void checkDrawnWindowsLocked() {
9166 if (mWaitingForDrawn.size() > 0) {
9167 for (int j=mWaitingForDrawn.size()-1; j>=0; j--) {
9168 Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(j);
9169 WindowState win = pair.first;
9170 //Slog.i(TAG, "Waiting for drawn " + win + ": removed="
9171 // + win.mRemoved + " visible=" + win.isVisibleLw()
9172 // + " shown=" + win.mSurfaceShown);
9173 if (win.mRemoved || !win.isVisibleLw()) {
9174 // Window has been removed or made invisible; no draw
9175 // will now happen, so stop waiting.
9176 Slog.w(TAG, "Aborted waiting for drawn: " + pair.first);
9177 try {
9178 pair.second.sendResult(null);
9179 } catch (RemoteException e) {
9180 }
9181 mWaitingForDrawn.remove(pair);
9182 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009183 } else if (win.mWinAnimator.mSurfaceShown) {
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009184 // Window is now drawn (and shown).
9185 try {
9186 pair.second.sendResult(null);
9187 } catch (RemoteException e) {
9188 }
9189 mWaitingForDrawn.remove(pair);
9190 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9191 }
9192 }
9193 }
9194 }
9195
Craig Mautner2268e7e2012-12-13 15:40:00 -08009196 @Override
Jeff Brownc38c9be2012-10-04 13:16:19 -07009197 public boolean waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
9198 if (token != null && callback != null) {
9199 synchronized (mWindowMap) {
9200 WindowState win = windowForClientLocked(null, token, true);
9201 if (win != null) {
9202 Pair<WindowState, IRemoteCallback> pair =
9203 new Pair<WindowState, IRemoteCallback>(win, callback);
9204 Message m = mH.obtainMessage(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9205 mH.sendMessageDelayed(m, 2000);
9206 mWaitingForDrawn.add(pair);
9207 checkDrawnWindowsLocked();
9208 return true;
9209 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009210 }
9211 }
Jeff Brownc38c9be2012-10-04 13:16:19 -07009212 return false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009213 }
9214
Craig Mautner259328c2012-08-21 19:30:58 -07009215 void setHoldScreenLocked(final Session newHoldScreen) {
9216 final boolean hold = newHoldScreen != null;
9217
9218 if (hold && mHoldingScreenOn != newHoldScreen) {
9219 mHoldingScreenWakeLock.setWorkSource(new WorkSource(newHoldScreen.mUid));
9220 }
9221 mHoldingScreenOn = newHoldScreen;
9222
9223 final boolean state = mHoldingScreenWakeLock.isHeld();
9224 if (hold != state) {
9225 if (hold) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07009226 mHoldingScreenWakeLock.acquire();
Jeff Brownc38c9be2012-10-04 13:16:19 -07009227 mPolicy.keepScreenOnStartedLw();
Jeff Brown46b9ac02010-04-22 18:58:52 -07009228 } else {
Jeff Brownc38c9be2012-10-04 13:16:19 -07009229 mPolicy.keepScreenOnStoppedLw();
Jeff Brown46b9ac02010-04-22 18:58:52 -07009230 mHoldingScreenWakeLock.release();
9231 }
9232 }
9233 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009234
Craig Mautner722285e2012-09-07 13:55:58 -07009235 @Override
Jeff Brown4ed8fe72012-08-30 18:18:29 -07009236 public void requestTraversal() {
9237 synchronized (mWindowMap) {
9238 requestTraversalLocked();
9239 }
9240 }
9241
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08009242 void requestTraversalLocked() {
9243 if (!mTraversalScheduled) {
9244 mTraversalScheduled = true;
9245 mH.sendEmptyMessage(H.DO_TRAVERSAL);
9246 }
9247 }
9248
Craig Mautner711f90a2012-07-03 18:43:52 -07009249 /** Note that Locked in this case is on mLayoutToAnim */
Jeff Brown4a06c802012-02-15 15:06:01 -08009250 void scheduleAnimationLocked() {
Craig Mautner96868332012-12-04 14:29:11 -08009251 if (!mAnimationScheduled) {
9252 mAnimationScheduled = true;
Craig Mautner711f90a2012-07-03 18:43:52 -07009253 mChoreographer.postCallback(
9254 Choreographer.CALLBACK_ANIMATION, mAnimator.mAnimationRunnable, null);
9255 }
9256 }
9257
Craig Mautner1420b932012-12-28 17:14:38 -08009258 void startDimmingLocked(final WindowStateAnimator winAnimator, final float target) {
9259 mAnimator.setDimWinAnimatorLocked(winAnimator.mWin.getDisplayId(), winAnimator);
Craig Mautnera76fdb72012-07-03 19:03:02 -07009260 }
9261
Craig Mautnera91f9e22012-09-14 16:22:08 -07009262 void stopDimmingLocked(int displayId) {
Craig Mautner1420b932012-12-28 17:14:38 -08009263 mAnimator.setDimWinAnimatorLocked(displayId, null);
Craig Mautnera76fdb72012-07-03 19:03:02 -07009264 }
9265
Craig Mautner19d59bc2012-09-04 11:15:56 -07009266 private boolean needsLayout() {
Craig Mautner7c6be102013-07-16 12:30:28 -07009267 final int numDisplays = mDisplayContents.size();
9268 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9269 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
9270 if (displayContent.layoutNeeded) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009271 return true;
9272 }
9273 }
9274 return false;
9275 }
9276
Craig Mautner96868332012-12-04 14:29:11 -08009277 boolean copyAnimToLayoutParamsLocked() {
Craig Mautner322e4032012-07-13 13:35:20 -07009278 boolean doRequest = false;
Craig Mautner322e4032012-07-13 13:35:20 -07009279
Craig Mautner96868332012-12-04 14:29:11 -08009280 final int bulkUpdateParams = mAnimator.mBulkUpdateParams;
Craig Mautner96868332012-12-04 14:29:11 -08009281 if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) {
9282 mInnerFields.mUpdateRotation = true;
9283 doRequest = true;
Craig Mautner322e4032012-07-13 13:35:20 -07009284 }
Craig Mautner96868332012-12-04 14:29:11 -08009285 if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
9286 mInnerFields.mWallpaperMayChange = true;
9287 doRequest = true;
9288 }
9289 if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
9290 mInnerFields.mWallpaperForceHidingChanged = true;
9291 doRequest = true;
9292 }
9293 if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
9294 mInnerFields.mOrientationChangeComplete = false;
9295 } else {
9296 mInnerFields.mOrientationChangeComplete = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009297 mInnerFields.mLastWindowFreezeSource = mAnimator.mLastWindowFreezeSource;
Craig Mautner96868332012-12-04 14:29:11 -08009298 if (mWindowsFreezingScreen) {
9299 doRequest = true;
9300 }
9301 }
9302 if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
9303 mTurnOnScreen = true;
9304 }
9305 if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_ACTION_PENDING) != 0) {
9306 mInnerFields.mWallpaperActionPending = true;
9307 }
9308
Craig Mautner322e4032012-07-13 13:35:20 -07009309 return doRequest;
9310 }
9311
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009312 boolean reclaimSomeSurfaceMemoryLocked(WindowStateAnimator winAnimator, String operation,
9313 boolean secure) {
Mathias Agopian29479eb2013-02-14 14:36:04 -08009314 final SurfaceControl surface = winAnimator.mSurfaceControl;
Dianne Hackborn64825172011-03-02 21:32:58 -08009315 boolean leakedSurface = false;
9316 boolean killedApps = false;
Romain Guy06882f82009-06-10 13:36:04 -07009317
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009318 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
9319 winAnimator.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -07009320
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009321 if (mForceRemoves == null) {
9322 mForceRemoves = new ArrayList<WindowState>();
9323 }
Romain Guy06882f82009-06-10 13:36:04 -07009324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009325 long callingIdentity = Binder.clearCallingIdentity();
9326 try {
9327 // There was some problem... first, do a sanity check of the
9328 // window list to make sure we haven't left any dangling surfaces
9329 // around.
Craig Mautner59c00972012-07-30 12:10:24 -07009330
Craig Mautner7c6be102013-07-16 12:30:28 -07009331 final int numDisplays = mDisplayContents.size();
9332 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9333 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
9334 final int numWindows = windows.size();
9335 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
9336 final WindowState ws = windows.get(winNdx);
9337 WindowStateAnimator wsa = ws.mWinAnimator;
9338 if (wsa.mSurfaceControl != null) {
9339 if (!mSessions.contains(wsa.mSession)) {
9340 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
9341 + ws + " surface=" + wsa.mSurfaceControl
9342 + " token=" + ws.mToken
9343 + " pid=" + ws.mSession.mPid
9344 + " uid=" + ws.mSession.mUid);
9345 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
9346 wsa.mSurfaceControl.destroy();
9347 wsa.mSurfaceShown = false;
9348 wsa.mSurfaceControl = null;
9349 ws.mHasSurface = false;
9350 mForceRemoves.add(ws);
9351 leakedSurface = true;
9352 } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
9353 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
9354 + ws + " surface=" + wsa.mSurfaceControl
9355 + " token=" + ws.mAppToken);
9356 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
9357 wsa.mSurfaceControl.destroy();
9358 wsa.mSurfaceShown = false;
9359 wsa.mSurfaceControl = null;
9360 ws.mHasSurface = false;
9361 leakedSurface = true;
9362 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009363 }
9364 }
9365 }
Romain Guy06882f82009-06-10 13:36:04 -07009366
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009367 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009368 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009369 SparseIntArray pidCandidates = new SparseIntArray();
Craig Mautner7c6be102013-07-16 12:30:28 -07009370 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9371 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
9372 final int numWindows = windows.size();
9373 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
9374 final WindowState ws = windows.get(winNdx);
9375 if (mForceRemoves.contains(ws)) {
9376 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009377 }
Craig Mautner7c6be102013-07-16 12:30:28 -07009378 WindowStateAnimator wsa = ws.mWinAnimator;
9379 if (wsa.mSurfaceControl != null) {
9380 pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
9381 }
9382 }
9383 if (pidCandidates.size() > 0) {
9384 int[] pids = new int[pidCandidates.size()];
9385 for (int i=0; i<pids.length; i++) {
9386 pids[i] = pidCandidates.keyAt(i);
9387 }
9388 try {
9389 if (mActivityManager.killPids(pids, "Free memory", secure)) {
9390 killedApps = true;
9391 }
9392 } catch (RemoteException e) {
9393 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009394 }
9395 }
9396 }
Romain Guy06882f82009-06-10 13:36:04 -07009397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009398 if (leakedSurface || killedApps) {
9399 // We managed to reclaim some memory, so get rid of the trouble
9400 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -08009401 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009402 if (surface != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009403 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
Dianne Hackborn5fd21692011-06-07 14:09:47 -07009404 "RECOVER DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009405 surface.destroy();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009406 winAnimator.mSurfaceShown = false;
Mathias Agopian29479eb2013-02-14 14:36:04 -08009407 winAnimator.mSurfaceControl = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009408 winAnimator.mWin.mHasSurface = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009409 }
Romain Guy06882f82009-06-10 13:36:04 -07009410
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009411 try {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009412 winAnimator.mWin.mClient.dispatchGetNewSurface();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009413 } catch (RemoteException e) {
9414 }
9415 }
9416 } finally {
9417 Binder.restoreCallingIdentity(callingIdentity);
9418 }
Dianne Hackborn64825172011-03-02 21:32:58 -08009419
9420 return leakedSurface || killedApps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009421 }
Romain Guy06882f82009-06-10 13:36:04 -07009422
Jeff Brown3a22cd92011-01-21 13:59:04 -08009423 private boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009424 WindowState newFocus = computeFocusedWindowLocked();
9425 if (mCurrentFocus != newFocus) {
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07009426 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009427 // This check makes sure that we don't already have the focus
9428 // change message pending.
9429 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
9430 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009431 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009432 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
9433 final WindowState oldFocus = mCurrentFocus;
9434 mCurrentFocus = newFocus;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009435 mAnimator.setCurrentFocus(newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009436 mLosingFocus.remove(newFocus);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009437 int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus);
Romain Guy06882f82009-06-10 13:36:04 -07009438
Craig Mautner59c00972012-07-30 12:10:24 -07009439 // TODO(multidisplay): Focused windows on default display only.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07009440 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07009441
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009442 final WindowState imWindow = mInputMethodWindow;
9443 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009444 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009445 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009446 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
Jeff Brown20337632012-09-24 14:25:54 -07009447 displayContent.layoutNeeded = true;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009448 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009449 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Craig Mautner59c00972012-07-30 12:10:24 -07009450 performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009451 focusChanged &= ~WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009452 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
9453 // Client will do the layout, but we need to assign layers
9454 // for handleNewWindowLocked() below.
Craig Mautner59c00972012-07-30 12:10:24 -07009455 assignLayersLocked(displayContent.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009456 }
9457 }
Dianne Hackborndf89e652011-10-06 22:35:11 -07009458
Craig Mautner39834192012-09-02 07:47:24 -07009459 if ((focusChanged & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07009460 // The change in focus caused us to need to do a layout. Okay.
Jeff Brown20337632012-09-24 14:25:54 -07009461 displayContent.layoutNeeded = true;
Dianne Hackborndf89e652011-10-06 22:35:11 -07009462 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Craig Mautner59c00972012-07-30 12:10:24 -07009463 performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009464 }
9465 }
9466
Jeff Brown349703e2010-06-22 01:27:15 -07009467 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
9468 // If we defer assigning layers, then the caller is responsible for
9469 // doing this part.
Jeff Brown3a22cd92011-01-21 13:59:04 -08009470 finishUpdateFocusedWindowAfterAssignLayersLocked(updateInputWindows);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009471 }
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07009472
9473 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009474 return true;
9475 }
9476 return false;
9477 }
Craig Mautner66f78d72012-12-04 16:46:50 -08009478
Jeff Brown3a22cd92011-01-21 13:59:04 -08009479 private void finishUpdateFocusedWindowAfterAssignLayersLocked(boolean updateInputWindows) {
9480 mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows);
Jeff Brown349703e2010-06-22 01:27:15 -07009481 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009482
9483 private WindowState computeFocusedWindowLocked() {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07009484 if (mAnimator.mUniverseBackground != null
9485 && mAnimator.mUniverseBackground.mWin.canReceiveKeys()) {
9486 return mAnimator.mUniverseBackground.mWin;
9487 }
9488
Jeff Brown20337632012-09-24 14:25:54 -07009489 final int displayCount = mDisplayContents.size();
9490 for (int i = 0; i < displayCount; i++) {
9491 final DisplayContent displayContent = mDisplayContents.valueAt(i);
9492 WindowState win = findFocusedWindowLocked(displayContent);
9493 if (win != null) {
9494 return win;
9495 }
9496 }
9497 return null;
9498 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009499
Jeff Brown20337632012-09-24 14:25:54 -07009500 private WindowState findFocusedWindowLocked(DisplayContent displayContent) {
Craig Mautner2ad92072013-02-25 16:19:24 -08009501 int nextAppIndex = mAppTokens.size()-1;
9502 WindowToken nextApp = nextAppIndex >= 0 ? mAppTokens.get(nextAppIndex) : null;
Jeff Brown20337632012-09-24 14:25:54 -07009503
9504 final WindowList windows = displayContent.getWindowList();
Craig Mautner59c00972012-07-30 12:10:24 -07009505 for (int i = windows.size() - 1; i >= 0; i--) {
Jeff Brown20337632012-09-24 14:25:54 -07009506 final WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009507
Joe Onorato8a9b2202010-02-26 18:56:32 -08009508 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009509 TAG, "Looking for focus: " + i
9510 + " = " + win
9511 + ", flags=" + win.mAttrs.flags
9512 + ", canReceive=" + win.canReceiveKeys());
9513
9514 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -07009515
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009516 // If this window's application has been removed, just skip it.
Craig Mautneref25d7a2012-05-15 23:01:47 -07009517 if (thisApp != null && (thisApp.removed || thisApp.sendingToBottom)) {
Craig Mautner3f99fde2012-06-19 14:10:01 -07009518 if (DEBUG_FOCUS) Slog.v(TAG, "Skipping app because " + (thisApp.removed
9519 ? "removed" : "sendingToBottom"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009520 continue;
9521 }
Romain Guy06882f82009-06-10 13:36:04 -07009522
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009523 // If there is a focused app, don't allow focus to go to any
9524 // windows below it. If this is an application window, step
9525 // through the app tokens until we find its app.
9526 if (thisApp != null && nextApp != null && thisApp != nextApp
9527 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
Craig Mautner2ad92072013-02-25 16:19:24 -08009528 int origAppIndex = nextAppIndex;
9529 while (nextAppIndex > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009530 if (nextApp == mFocusedApp) {
9531 // Whoops, we are below the focused app... no focus
9532 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -08009533 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009534 TAG, "Reached focused app: " + mFocusedApp);
9535 return null;
9536 }
Craig Mautner2ad92072013-02-25 16:19:24 -08009537 nextAppIndex--;
9538 nextApp = mAppTokens.get(nextAppIndex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009539 if (nextApp == thisApp) {
9540 break;
9541 }
9542 }
9543 if (thisApp != nextApp) {
9544 // Uh oh, the app token doesn't exist! This shouldn't
9545 // happen, but if it does we can get totally hosed...
9546 // so restart at the original app.
Craig Mautner2ad92072013-02-25 16:19:24 -08009547 nextAppIndex = origAppIndex;
9548 nextApp = mAppTokens.get(nextAppIndex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009549 }
9550 }
9551
9552 // Dispatch to this window if it is wants key events.
9553 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009554 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009555 TAG, "Found focus @ " + i + " = " + win);
Jeff Brown20337632012-09-24 14:25:54 -07009556 return win;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009557 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009558 }
Jeff Brown20337632012-09-24 14:25:54 -07009559 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009560 }
9561
Craig Mautner3c174372013-02-21 17:54:37 -08009562 private void startFreezingDisplayLocked(boolean inTransaction, int exitAnim, int enterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009563 if (mDisplayFrozen) {
9564 return;
9565 }
Romain Guy06882f82009-06-10 13:36:04 -07009566
Jeff Browne215f262012-09-10 16:01:14 -07009567 if (!mDisplayReady || !mPolicy.isScreenOnFully()) {
Dianne Hackborn8e8d65f2011-08-11 19:36:18 -07009568 // No need to freeze the screen before the system is ready or if
9569 // the screen is off.
9570 return;
9571 }
9572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009573 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -07009574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009575 mDisplayFrozen = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009576 mDisplayFreezeTime = SystemClock.elapsedRealtime();
9577 mLastFinishedFreezeSource = null;
Craig Mautner7d8df392012-04-06 15:26:23 -07009578
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009579 mInputMonitor.freezeInputDispatchingLw();
Craig Mautner7d8df392012-04-06 15:26:23 -07009580
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07009581 // Clear the last input window -- that is just used for
9582 // clean transitions between IMEs, and if we are freezing
9583 // the screen then the whole world is changing behind the scenes.
9584 mPolicy.setLastInputMethodWindowLw(null, null);
9585
Craig Mautner164d4bb2012-11-26 13:51:23 -08009586 if (mAppTransition.isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08009587 mAppTransition.freeze();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009588 }
Romain Guy06882f82009-06-10 13:36:04 -07009589
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009590 if (PROFILE_ORIENTATION) {
9591 File file = new File("/data/system/frozen");
9592 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
9593 }
Dianne Hackborna1111872010-11-23 20:55:11 -08009594
9595 if (CUSTOM_SCREEN_ROTATION) {
Craig Mautner3c174372013-02-21 17:54:37 -08009596 mExitAnimId = exitAnim;
9597 mEnterAnimId = enterAnim;
Craig Mautnera91f9e22012-09-14 16:22:08 -07009598 final DisplayContent displayContent = getDefaultDisplayContentLocked();
9599 final int displayId = displayContent.getDisplayId();
9600 ScreenRotationAnimation screenRotationAnimation =
9601 mAnimator.getScreenRotationAnimationLocked(displayId);
9602 if (screenRotationAnimation != null) {
9603 screenRotationAnimation.kill();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08009604 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07009605
Craig Mautner59c00972012-07-30 12:10:24 -07009606 // TODO(multidisplay): rotation on main screen only.
Jeff Browne215f262012-09-10 16:01:14 -07009607 final Display display = displayContent.getDisplay();
9608 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
Craig Mautnera91f9e22012-09-14 16:22:08 -07009609 screenRotationAnimation = new ScreenRotationAnimation(mContext,
Jeff Browne215f262012-09-10 16:01:14 -07009610 display, mFxSession, inTransaction, displayInfo.logicalWidth,
Craig Mautner3c174372013-02-21 17:54:37 -08009611 displayInfo.logicalHeight, display.getRotation());
Craig Mautnera91f9e22012-09-14 16:22:08 -07009612 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackborna1111872010-11-23 20:55:11 -08009613 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009614 }
Romain Guy06882f82009-06-10 13:36:04 -07009615
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009616 private void stopFreezingDisplayLocked() {
9617 if (!mDisplayFrozen) {
9618 return;
9619 }
Romain Guy06882f82009-06-10 13:36:04 -07009620
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009621 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen
9622 || mClientFreezingScreen) {
Craig Mautnerd87946b2012-03-29 18:00:19 -07009623 if (DEBUG_ORIENTATION) Slog.d(TAG,
9624 "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + mWaitingForConfig
9625 + ", mAppsFreezingScreen=" + mAppsFreezingScreen
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009626 + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen
9627 + ", mClientFreezingScreen=" + mClientFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009628 return;
9629 }
Craig Mautner66f78d72012-12-04 16:46:50 -08009630
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009631 mDisplayFrozen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009632 mLastDisplayFreezeDuration = (int)(SystemClock.elapsedRealtime() - mDisplayFreezeTime);
9633 StringBuilder sb = new StringBuilder(128);
9634 sb.append("Screen frozen for ");
9635 TimeUtils.formatDuration(mLastDisplayFreezeDuration, sb);
9636 if (mLastFinishedFreezeSource != null) {
9637 sb.append(" due to ");
9638 sb.append(mLastFinishedFreezeSource);
9639 }
9640 Slog.i(TAG, sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009641 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009642 mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009643 if (PROFILE_ORIENTATION) {
9644 Debug.stopMethodTracing();
9645 }
Dianne Hackborna1111872010-11-23 20:55:11 -08009646
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009647 boolean updateRotation = false;
Craig Mautner59c00972012-07-30 12:10:24 -07009648
Craig Mautnera91f9e22012-09-14 16:22:08 -07009649 final DisplayContent displayContent = getDefaultDisplayContentLocked();
9650 final int displayId = displayContent.getDisplayId();
9651 ScreenRotationAnimation screenRotationAnimation =
9652 mAnimator.getScreenRotationAnimationLocked(displayId);
9653 if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
9654 && screenRotationAnimation.hasScreenshot()) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07009655 if (DEBUG_ORIENTATION) Slog.i(TAG, "**** Dismissing screen rotation animation");
Craig Mautner59c00972012-07-30 12:10:24 -07009656 // TODO(multidisplay): rotation on main screen only.
Craig Mautnera91f9e22012-09-14 16:22:08 -07009657 DisplayInfo displayInfo = displayContent.getDisplayInfo();
Craig Mautner3c174372013-02-21 17:54:37 -08009658 // Get rotation animation again, with new top window
9659 boolean isDimming = mAnimator.isDimmingLocked(Display.DEFAULT_DISPLAY);
9660 if (!mPolicy.validateRotationAnimationLw(mExitAnimId, mEnterAnimId, isDimming)) {
9661 mExitAnimId = mEnterAnimId = 0;
9662 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07009663 if (screenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
Craig Mautner59c00972012-07-30 12:10:24 -07009664 mTransitionAnimationScale, displayInfo.logicalWidth,
Craig Mautner3c174372013-02-21 17:54:37 -08009665 displayInfo.logicalHeight, mExitAnimId, mEnterAnimId)) {
Craig Mautner96868332012-12-04 14:29:11 -08009666 scheduleAnimationLocked();
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009667 } else {
Craig Mautnera91f9e22012-09-14 16:22:08 -07009668 screenRotationAnimation.kill();
9669 screenRotationAnimation = null;
9670 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009671 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -08009672 }
9673 } else {
Craig Mautnera91f9e22012-09-14 16:22:08 -07009674 if (screenRotationAnimation != null) {
9675 screenRotationAnimation.kill();
9676 screenRotationAnimation = null;
9677 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009678 }
9679 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -08009680 }
Romain Guy06882f82009-06-10 13:36:04 -07009681
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009682 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009683
Dianne Hackborn420829e2011-01-28 11:30:35 -08009684 boolean configChanged;
Craig Mautner0bf6ec92012-12-18 08:33:27 -08009685
Christopher Tateb696aee2010-04-02 19:08:30 -07009686 // While the display is frozen we don't re-compute the orientation
9687 // to avoid inconsistent states. However, something interesting
9688 // could have actually changed during that time so re-evaluate it
9689 // now to catch that.
Dianne Hackborn420829e2011-01-28 11:30:35 -08009690 configChanged = updateOrientationFromAppTokensLocked(false);
Christopher Tateb696aee2010-04-02 19:08:30 -07009691
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009692 // A little kludge: a lot could have happened while the
9693 // display was frozen, so now that we are coming back we
9694 // do a gc so that any remote references the system
9695 // processes holds on others can be released if they are
9696 // no longer needed.
9697 mH.removeMessages(H.FORCE_GC);
You Kimcb6291c2012-12-04 23:22:28 +09009698 mH.sendEmptyMessageDelayed(H.FORCE_GC, 2000);
Romain Guy06882f82009-06-10 13:36:04 -07009699
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009700 mScreenFrozenLock.release();
Craig Mautner6cfa7292013-01-15 09:05:42 -08009701
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009702 if (updateRotation) {
9703 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Jeff Brown01a98dd2011-09-20 15:08:29 -07009704 configChanged |= updateRotationUncheckedLocked(false);
Dianne Hackborn420829e2011-01-28 11:30:35 -08009705 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08009706
Dianne Hackborn420829e2011-01-28 11:30:35 -08009707 if (configChanged) {
9708 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009709 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009710 }
Romain Guy06882f82009-06-10 13:36:04 -07009711
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07009712 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
9713 DisplayMetrics dm) {
9714 if (index < tokens.length) {
9715 String str = tokens[index];
9716 if (str != null && str.length() > 0) {
9717 try {
9718 int val = Integer.parseInt(str);
9719 return val;
9720 } catch (Exception e) {
9721 }
9722 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009723 }
9724 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
9725 return defDps;
9726 }
9727 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
9728 return val;
9729 }
9730
Jeff Brown4ed8fe72012-08-30 18:18:29 -07009731 void createWatermarkInTransaction() {
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009732 if (mWatermark != null) {
9733 return;
9734 }
9735
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07009736 File file = new File("/system/etc/setup.conf");
9737 FileInputStream in = null;
Craig Mautner2268e7e2012-12-13 15:40:00 -08009738 DataInputStream ind = null;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07009739 try {
9740 in = new FileInputStream(file);
Craig Mautner2268e7e2012-12-13 15:40:00 -08009741 ind = new DataInputStream(in);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07009742 String line = ind.readLine();
9743 if (line != null) {
9744 String[] toks = line.split("%");
9745 if (toks != null && toks.length > 0) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07009746 mWatermark = new Watermark(getDefaultDisplayContentLocked().getDisplay(),
Jeff Browne215f262012-09-10 16:01:14 -07009747 mRealDisplayMetrics, mFxSession, toks);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07009748 }
9749 }
9750 } catch (FileNotFoundException e) {
9751 } catch (IOException e) {
9752 } finally {
Craig Mautner2268e7e2012-12-13 15:40:00 -08009753 if (ind != null) {
9754 try {
9755 ind.close();
9756 } catch (IOException e) {
9757 }
Craig Mautner0bf6ec92012-12-18 08:33:27 -08009758 } else if (in != null) {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07009759 try {
9760 in.close();
9761 } catch (IOException e) {
9762 }
9763 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009764 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009765 }
9766
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009767 @Override
Joe Onorato664644d2011-01-23 17:53:23 -08009768 public void statusBarVisibilityChanged(int visibility) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07009769 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
9770 != PackageManager.PERMISSION_GRANTED) {
9771 throw new SecurityException("Caller does not hold permission "
9772 + android.Manifest.permission.STATUS_BAR);
9773 }
Dianne Hackborn9a230e02011-10-06 11:51:27 -07009774
Joe Onorato664644d2011-01-23 17:53:23 -08009775 synchronized (mWindowMap) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07009776 mLastStatusBarVisibility = visibility;
9777 visibility = mPolicy.adjustSystemUiVisibilityLw(visibility);
9778 updateStatusBarVisibilityLocked(visibility);
9779 }
9780 }
9781
Craig Mautner59c00972012-07-30 12:10:24 -07009782 // TOOD(multidisplay): StatusBar on multiple screens?
Dianne Hackborndf89e652011-10-06 22:35:11 -07009783 void updateStatusBarVisibilityLocked(int visibility) {
9784 mInputManager.setSystemUiVisibility(visibility);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07009785 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07009786 final int N = windows.size();
Dianne Hackborndf89e652011-10-06 22:35:11 -07009787 for (int i = 0; i < N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07009788 WindowState ws = windows.get(i);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009789 try {
9790 int curValue = ws.mSystemUiVisibility;
9791 int diff = curValue ^ visibility;
9792 // We are only interested in differences of one of the
9793 // clearable flags...
9794 diff &= View.SYSTEM_UI_CLEARABLE_FLAGS;
9795 // ...if it has actually been cleared.
9796 diff &= ~visibility;
9797 int newValue = (curValue&~diff) | (visibility&diff);
9798 if (newValue != curValue) {
9799 ws.mSeq++;
9800 ws.mSystemUiVisibility = newValue;
9801 }
9802 if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) {
9803 ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq,
9804 visibility, newValue, diff);
9805 }
9806 } catch (RemoteException e) {
9807 // so sorry
9808 }
9809 }
9810 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08009811
Dianne Hackborndf89e652011-10-06 22:35:11 -07009812 @Override
9813 public void reevaluateStatusBarVisibility() {
9814 synchronized (mWindowMap) {
9815 int visibility = mPolicy.adjustSystemUiVisibilityLw(mLastStatusBarVisibility);
9816 updateStatusBarVisibilityLocked(visibility);
9817 performLayoutAndPlaceSurfacesLocked();
9818 }
9819 }
9820
9821 @Override
Jeff Brown32cbc38552011-12-01 14:01:49 -08009822 public FakeWindow addFakeWindow(Looper looper,
9823 InputEventReceiver.Factory inputEventReceiverFactory,
Dianne Hackborndf89e652011-10-06 22:35:11 -07009824 String name, int windowType, int layoutParamsFlags, boolean canReceiveKeys,
9825 boolean hasFocus, boolean touchFullscreen) {
9826 synchronized (mWindowMap) {
Jeff Brown32cbc38552011-12-01 14:01:49 -08009827 FakeWindowImpl fw = new FakeWindowImpl(this, looper, inputEventReceiverFactory,
9828 name, windowType,
Dianne Hackborndf89e652011-10-06 22:35:11 -07009829 layoutParamsFlags, canReceiveKeys, hasFocus, touchFullscreen);
9830 int i=0;
9831 while (i<mFakeWindows.size()) {
9832 if (mFakeWindows.get(i).mWindowLayer <= fw.mWindowLayer) {
9833 break;
Joe Onorato664644d2011-01-23 17:53:23 -08009834 }
9835 }
Dianne Hackborndf89e652011-10-06 22:35:11 -07009836 mFakeWindows.add(i, fw);
9837 mInputMonitor.updateInputWindowsLw(true);
9838 return fw;
9839 }
9840 }
9841
9842 boolean removeFakeWindowLocked(FakeWindow window) {
9843 synchronized (mWindowMap) {
9844 if (mFakeWindows.remove(window)) {
9845 mInputMonitor.updateInputWindowsLw(true);
9846 return true;
9847 }
9848 return false;
Joe Onorato664644d2011-01-23 17:53:23 -08009849 }
9850 }
9851
satoke0a99412012-05-10 02:22:58 +09009852 // It is assumed that this method is called only by InputMethodManagerService.
9853 public void saveLastInputMethodWindowForTransition() {
9854 synchronized (mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -07009855 // TODO(multidisplay): Pass in the displayID.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07009856 DisplayContent displayContent = getDefaultDisplayContentLocked();
satoke0a99412012-05-10 02:22:58 +09009857 if (mInputMethodWindow != null) {
9858 mPolicy.setLastInputMethodWindowLw(mInputMethodWindow, mInputMethodTarget);
9859 }
9860 }
9861 }
9862
Daniel Sandler0c4ccff2011-10-19 16:39:14 -04009863 @Override
9864 public boolean hasNavigationBar() {
9865 return mPolicy.hasNavigationBar();
9866 }
9867
Craig Mautner96868332012-12-04 14:29:11 -08009868 @Override
Adam Cohenf7522022012-10-03 20:03:18 -07009869 public void lockNow(Bundle options) {
9870 mPolicy.lockNow(options);
Jim Miller93c518e2012-01-17 15:55:31 -08009871 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08009872
Craig Mautner96868332012-12-04 14:29:11 -08009873 @Override
Jim Millerbfec0a82012-11-05 20:05:22 -08009874 public boolean isSafeModeEnabled() {
9875 return mSafeMode;
9876 }
Jim Miller93c518e2012-01-17 15:55:31 -08009877
Craig Mautner96868332012-12-04 14:29:11 -08009878 @Override
Jim Miller4eeb4f62012-11-08 00:04:29 -08009879 public void showAssistant() {
9880 // TODO: What permission?
9881 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
9882 != PackageManager.PERMISSION_GRANTED) {
9883 return;
9884 }
9885 mPolicy.showAssistant();
9886 }
9887
Jeff Brownd7a04de2012-06-17 14:17:52 -07009888 void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009889 pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
Jeff Brownd7a04de2012-06-17 14:17:52 -07009890 mPolicy.dump(" ", pw, args);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009891 }
9892
Dianne Hackborn529e7442012-11-01 14:22:28 -07009893 void dumpAnimatorLocked(PrintWriter pw, String[] args, boolean dumpAll) {
9894 pw.println("WINDOW MANAGER ANIMATOR STATE (dumpsys window animator)");
9895 mAnimator.dumpLocked(pw, " ", dumpAll);
9896 }
9897
Jeff Brownd7a04de2012-06-17 14:17:52 -07009898 void dumpTokensLocked(PrintWriter pw, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009899 pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
9900 if (mTokenMap.size() > 0) {
9901 pw.println(" All tokens:");
9902 Iterator<WindowToken> it = mTokenMap.values().iterator();
9903 while (it.hasNext()) {
9904 WindowToken token = it.next();
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07009905 pw.print(" "); pw.print(token);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009906 if (dumpAll) {
9907 pw.println(':');
9908 token.dump(pw, " ");
9909 } else {
9910 pw.println();
9911 }
9912 }
9913 }
9914 if (mWallpaperTokens.size() > 0) {
9915 pw.println();
9916 pw.println(" Wallpaper tokens:");
9917 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
9918 WindowToken token = mWallpaperTokens.get(i);
9919 pw.print(" Wallpaper #"); pw.print(i);
9920 pw.print(' '); pw.print(token);
9921 if (dumpAll) {
9922 pw.println(':');
9923 token.dump(pw, " ");
9924 } else {
9925 pw.println();
9926 }
9927 }
9928 }
Craig Mautner2ad92072013-02-25 16:19:24 -08009929 if (mAppTokens.size() > 0) {
9930 pw.println();
9931 pw.println(" Application tokens in Z order:");
9932 for (int i=mAppTokens.size()-1; i>=0; i--) {
9933 pw.print(" App #"); pw.print(i);
9934 pw.print(' '); pw.print(mAppTokens.get(i)); pw.println(":");
9935 mAppTokens.get(i).dump(pw, " ");
9936 }
9937 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009938 if (mFinishedStarting.size() > 0) {
9939 pw.println();
9940 pw.println(" Finishing start of application tokens:");
9941 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
9942 WindowToken token = mFinishedStarting.get(i);
9943 pw.print(" Finished Starting #"); pw.print(i);
9944 pw.print(' '); pw.print(token);
9945 if (dumpAll) {
9946 pw.println(':');
9947 token.dump(pw, " ");
9948 } else {
9949 pw.println();
9950 }
9951 }
9952 }
Craig Mautner2ad92072013-02-25 16:19:24 -08009953 if (mExitingTokens.size() > 0) {
9954 pw.println();
9955 pw.println(" Exiting tokens:");
9956 for (int i=mExitingTokens.size()-1; i>=0; i--) {
9957 WindowToken token = mExitingTokens.get(i);
9958 pw.print(" Exiting #"); pw.print(i);
9959 pw.print(' '); pw.print(token);
9960 if (dumpAll) {
9961 pw.println(':');
9962 token.dump(pw, " ");
9963 } else {
9964 pw.println();
9965 }
9966 }
9967 }
9968 if (mExitingAppTokens.size() > 0) {
9969 pw.println();
9970 pw.println(" Exiting application tokens:");
9971 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
9972 WindowToken token = mExitingAppTokens.get(i);
9973 pw.print(" Exiting App #"); pw.print(i);
9974 pw.print(' '); pw.print(token);
9975 if (dumpAll) {
9976 pw.println(':');
9977 token.dump(pw, " ");
9978 } else {
9979 pw.println();
9980 }
9981 }
9982 }
9983 if (mAppTransition.isRunning() && mAnimatingAppTokens.size() > 0) {
9984 pw.println();
9985 pw.println(" Application tokens during animation:");
9986 for (int i=mAnimatingAppTokens.size()-1; i>=0; i--) {
9987 WindowToken token = mAnimatingAppTokens.get(i);
9988 pw.print(" App moving to bottom #"); pw.print(i);
9989 pw.print(' '); pw.print(token);
9990 if (dumpAll) {
9991 pw.println(':');
9992 token.dump(pw, " ");
9993 } else {
9994 pw.println();
9995 }
9996 }
9997 }
Dianne Hackborn6e2281d2012-06-19 17:48:32 -07009998 if (mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
9999 pw.println();
10000 if (mOpeningApps.size() > 0) {
10001 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
10002 }
10003 if (mClosingApps.size() > 0) {
10004 pw.print(" mClosingApps="); pw.println(mClosingApps);
10005 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010006 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010007 }
10008
Jeff Brownd7a04de2012-06-17 14:17:52 -070010009 void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010010 pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
10011 if (mSessions.size() > 0) {
10012 Iterator<Session> it = mSessions.iterator();
10013 while (it.hasNext()) {
10014 Session s = it.next();
10015 pw.print(" Session "); pw.print(s); pw.println(':');
10016 s.dump(pw, " ");
10017 }
10018 }
10019 }
10020
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010021 void dumpDisplayContentsLocked(PrintWriter pw, boolean dumpAll) {
10022 pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)");
10023 if (mDisplayReady) {
Craig Mautner7c6be102013-07-16 12:30:28 -070010024 final int numDisplays = mDisplayContents.size();
10025 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10026 mDisplayContents.valueAt(displayNdx).dump(" ", pw);
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010027 }
10028 } else {
10029 pw.println(" NO DISPLAY");
10030 }
10031 }
10032
Jeff Brownd7a04de2012-06-17 14:17:52 -070010033 void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010034 ArrayList<WindowState> windows) {
10035 pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010036 dumpWindowsNoHeaderLocked(pw, dumpAll, windows);
10037 }
10038
10039 void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll,
10040 ArrayList<WindowState> windows) {
Craig Mautner59c00972012-07-30 12:10:24 -070010041 int j = 0;
Craig Mautner7c6be102013-07-16 12:30:28 -070010042 final int numDisplays = mDisplayContents.size();
10043 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10044 final WindowList windowList = mDisplayContents.valueAt(displayNdx).getWindowList();
10045 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
10046 final WindowState w = windowList.get(winNdx);
10047 if (windows == null || windows.contains(w)) {
10048 pw.print(" Window #"); pw.print(j++); pw.print(' ');
10049 pw.print(w); pw.println(":");
10050 w.dump(pw, " ", dumpAll || windows != null);
10051 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010052 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010053 }
10054 if (mInputMethodDialogs.size() > 0) {
10055 pw.println();
10056 pw.println(" Input method dialogs:");
10057 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
10058 WindowState w = mInputMethodDialogs.get(i);
10059 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010060 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010061 }
10062 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010063 }
10064 if (mPendingRemove.size() > 0) {
10065 pw.println();
10066 pw.println(" Remove pending for:");
10067 for (int i=mPendingRemove.size()-1; i>=0; i--) {
10068 WindowState w = mPendingRemove.get(i);
10069 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010070 pw.print(" Remove #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010071 pw.print(w);
10072 if (dumpAll) {
10073 pw.println(":");
10074 w.dump(pw, " ", true);
10075 } else {
10076 pw.println();
10077 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010078 }
10079 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010080 }
10081 if (mForceRemoves != null && mForceRemoves.size() > 0) {
10082 pw.println();
10083 pw.println(" Windows force removing:");
10084 for (int i=mForceRemoves.size()-1; i>=0; i--) {
10085 WindowState w = mForceRemoves.get(i);
10086 pw.print(" Removing #"); pw.print(i); pw.print(' ');
10087 pw.print(w);
10088 if (dumpAll) {
10089 pw.println(":");
10090 w.dump(pw, " ", true);
10091 } else {
10092 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010093 }
10094 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010095 }
10096 if (mDestroySurface.size() > 0) {
10097 pw.println();
10098 pw.println(" Windows waiting to destroy their surface:");
10099 for (int i=mDestroySurface.size()-1; i>=0; i--) {
10100 WindowState w = mDestroySurface.get(i);
10101 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010102 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010103 pw.print(w);
10104 if (dumpAll) {
10105 pw.println(":");
10106 w.dump(pw, " ", true);
10107 } else {
10108 pw.println();
10109 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010110 }
10111 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010112 }
10113 if (mLosingFocus.size() > 0) {
10114 pw.println();
10115 pw.println(" Windows losing focus:");
10116 for (int i=mLosingFocus.size()-1; i>=0; i--) {
10117 WindowState w = mLosingFocus.get(i);
10118 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010119 pw.print(" Losing #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010120 pw.print(w);
10121 if (dumpAll) {
10122 pw.println(":");
10123 w.dump(pw, " ", true);
10124 } else {
10125 pw.println();
10126 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010127 }
10128 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010129 }
10130 if (mResizingWindows.size() > 0) {
10131 pw.println();
10132 pw.println(" Windows waiting to resize:");
10133 for (int i=mResizingWindows.size()-1; i>=0; i--) {
10134 WindowState w = mResizingWindows.get(i);
10135 if (windows == null || windows.contains(w)) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010136 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010137 pw.print(w);
10138 if (dumpAll) {
10139 pw.println(":");
10140 w.dump(pw, " ", true);
10141 } else {
10142 pw.println();
10143 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010144 }
10145 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010146 }
Dianne Hackborn38e29a62011-09-18 14:43:08 -070010147 if (mWaitingForDrawn.size() > 0) {
10148 pw.println();
10149 pw.println(" Clients waiting for these windows to be drawn:");
10150 for (int i=mWaitingForDrawn.size()-1; i>=0; i--) {
10151 Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(i);
10152 pw.print(" Waiting #"); pw.print(i); pw.print(' '); pw.print(pair.first);
10153 pw.print(": "); pw.println(pair.second);
10154 }
10155 }
Dianne Hackborn77119bc2012-10-23 14:32:48 -070010156 pw.println();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010157 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
10158 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
10159 if (mLastFocus != mCurrentFocus) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010160 pw.print(" mLastFocus="); pw.println(mLastFocus);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010161 }
10162 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
10163 if (mInputMethodTarget != null) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010164 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010165 }
10166 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
10167 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborna57c6952013-03-29 14:46:40 -070010168 pw.print(" mLastDisplayFreezeDuration=");
10169 TimeUtils.formatDuration(mLastDisplayFreezeDuration, pw);
10170 if ( mLastFinishedFreezeSource != null) {
10171 pw.print(" due to ");
10172 pw.print(mLastFinishedFreezeSource);
10173 }
10174 pw.println();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010175 if (dumpAll) {
Dianne Hackborn85afd1b2012-05-13 13:31:06 -070010176 pw.print(" mSystemDecorRect="); pw.print(mSystemDecorRect.toShortString());
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070010177 pw.print(" mSystemDecorLayer="); pw.print(mSystemDecorLayer);
Dianne Hackbornc652de82013-02-15 16:32:56 -080010178 pw.print(" mScreenRect="); pw.println(mScreenRect.toShortString());
Dianne Hackborndf89e652011-10-06 22:35:11 -070010179 if (mLastStatusBarVisibility != 0) {
10180 pw.print(" mLastStatusBarVisibility=0x");
10181 pw.println(Integer.toHexString(mLastStatusBarVisibility));
10182 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010183 if (mInputMethodWindow != null) {
10184 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
10185 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -070010186 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn529e7442012-11-01 14:22:28 -070010187 if (mLowerWallpaperTarget != null || mUpperWallpaperTarget != null) {
Dianne Hackborn284ac932009-08-28 10:34:25 -070010188 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
10189 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
10190 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010191 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
10192 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
10193 if (mInputMethodAnimLayerAdjustment != 0 ||
10194 mWallpaperAnimLayerAdjustment != 0) {
10195 pw.print(" mInputMethodAnimLayerAdjustment=");
10196 pw.print(mInputMethodAnimLayerAdjustment);
10197 pw.print(" mWallpaperAnimLayerAdjustment=");
10198 pw.println(mWallpaperAnimLayerAdjustment);
10199 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010200 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
10201 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
Craig Mautner19d59bc2012-09-04 11:15:56 -070010202 if (needsLayout()) {
10203 pw.print(" layoutNeeded on displays=");
Craig Mautner7c6be102013-07-16 12:30:28 -070010204 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10205 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautner19d59bc2012-09-04 11:15:56 -070010206 if (displayContent.layoutNeeded) {
10207 pw.print(displayContent.getDisplayId());
10208 }
10209 }
10210 pw.println();
10211 }
Craig Mautner69b08182012-09-05 13:07:13 -070010212 pw.print(" mTransactionSequence="); pw.println(mTransactionSequence);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010213 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -070010214 pw.print(" windows="); pw.print(mWindowsFreezingScreen);
10215 pw.print(" client="); pw.print(mClientFreezingScreen);
10216 pw.print(" apps="); pw.print(mAppsFreezingScreen);
10217 pw.print(" waitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010218 pw.print(" mRotation="); pw.print(mRotation);
Dianne Hackborndacea8c2011-04-21 17:26:39 -070010219 pw.print(" mAltOrientation="); pw.println(mAltOrientation);
Craig Mautnerf20588f2012-04-11 17:06:21 -070010220 pw.print(" mLastWindowForcedOrientation="); pw.print(mLastWindowForcedOrientation);
Dianne Hackbornbc7386c2011-06-06 17:27:54 -070010221 pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation);
Jeff Brown01a98dd2011-09-20 15:08:29 -070010222 pw.print(" mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
Dianne Hackborn4dcece82012-02-10 14:50:32 -080010223 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
10224 pw.print(" mTransitionWindowAnimationScale="); pw.print(mTransitionAnimationScale);
Chet Haasec38fa1f2012-02-01 16:37:46 -080010225 pw.print(" mAnimatorDurationScale="); pw.println(mAnimatorDurationScale);
Craig Mautner164d4bb2012-11-26 13:51:23 -080010226 pw.print(" mTraversalScheduled="); pw.println(mTraversalScheduled);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010227 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010228 pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Dianne Hackborn529e7442012-11-01 14:22:28 -070010229 pw.println(" mLayoutToAnim:");
Craig Mautner164d4bb2012-11-26 13:51:23 -080010230 mAppTransition.dump(pw);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010231 }
10232 }
10233
Jeff Brownd7a04de2012-06-17 14:17:52 -070010234 boolean dumpWindows(PrintWriter pw, String name, String[] args,
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010235 int opti, boolean dumpAll) {
Craig Mautner722285e2012-09-07 13:55:58 -070010236 WindowList windows = new WindowList();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010237 if ("visible".equals(name)) {
10238 synchronized(mWindowMap) {
Craig Mautner7c6be102013-07-16 12:30:28 -070010239 final int numDisplays = mDisplayContents.size();
10240 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10241 final WindowList windowList =
10242 mDisplayContents.valueAt(displayNdx).getWindowList();
10243 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
10244 final WindowState w = windowList.get(winNdx);
10245 if (w.mWinAnimator.mSurfaceShown) {
10246 windows.add(w);
10247 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010248 }
10249 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010250 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010251 } else {
10252 int objectId = 0;
10253 // See if this is an object ID.
10254 try {
10255 objectId = Integer.parseInt(name, 16);
10256 name = null;
10257 } catch (RuntimeException e) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010258 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010259 synchronized(mWindowMap) {
Craig Mautner7c6be102013-07-16 12:30:28 -070010260 final int numDisplays = mDisplayContents.size();
10261 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10262 final WindowList windowList = mDisplayContents.valueAt(displayNdx).getWindowList();
10263 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
10264 final WindowState w = windowList.get(winNdx);
10265 if (name != null) {
10266 if (w.mAttrs.getTitle().toString().contains(name)) {
10267 windows.add(w);
10268 }
10269 } else if (System.identityHashCode(w) == objectId) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010270 windows.add(w);
10271 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010272 }
10273 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010274 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010275 }
10276
10277 if (windows.size() <= 0) {
10278 return false;
10279 }
10280
10281 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010282 dumpWindowsLocked(pw, dumpAll, windows);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010283 }
10284 return true;
10285 }
10286
Jeff Brownd7a04de2012-06-17 14:17:52 -070010287 void dumpLastANRLocked(PrintWriter pw) {
10288 pw.println("WINDOW MANAGER LAST ANR (dumpsys window lastanr)");
10289 if (mLastANRState == null) {
10290 pw.println(" <no ANR has occurred since boot>");
10291 } else {
10292 pw.println(mLastANRState);
10293 }
10294 }
10295
10296 /**
10297 * Saves information about the state of the window manager at
10298 * the time an ANR occurred before anything else in the system changes
10299 * in response.
10300 *
Jeff Brownee172412012-06-18 12:58:03 -070010301 * @param appWindowToken The application that ANR'd, may be null.
Jeff Brownd7a04de2012-06-17 14:17:52 -070010302 * @param windowState The window that ANR'd, may be null.
10303 */
10304 public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState) {
10305 StringWriter sw = new StringWriter();
10306 PrintWriter pw = new PrintWriter(sw);
10307 pw.println(" ANR time: " + DateFormat.getInstance().format(new Date()));
Jeff Brownee172412012-06-18 12:58:03 -070010308 if (appWindowToken != null) {
10309 pw.println(" Application at fault: " + appWindowToken.stringName);
10310 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010311 if (windowState != null) {
10312 pw.println(" Window at fault: " + windowState.mAttrs.getTitle());
10313 }
10314 pw.println();
10315 dumpWindowsNoHeaderLocked(pw, true, null);
10316 pw.close();
10317 mLastANRState = sw.toString();
10318 }
10319
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010320 @Override
10321 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10322 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
10323 != PackageManager.PERMISSION_GRANTED) {
10324 pw.println("Permission Denial: can't dump WindowManager from from pid="
10325 + Binder.getCallingPid()
10326 + ", uid=" + Binder.getCallingUid());
10327 return;
10328 }
10329
10330 boolean dumpAll = false;
10331
10332 int opti = 0;
10333 while (opti < args.length) {
10334 String opt = args[opti];
10335 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10336 break;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010337 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010338 opti++;
10339 if ("-a".equals(opt)) {
10340 dumpAll = true;
10341 } else if ("-h".equals(opt)) {
10342 pw.println("Window manager dump options:");
10343 pw.println(" [-a] [-h] [cmd] ...");
10344 pw.println(" cmd may be one of:");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010345 pw.println(" l[astanr]: last ANR information");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010346 pw.println(" p[policy]: policy state");
Dianne Hackborn529e7442012-11-01 14:22:28 -070010347 pw.println(" a[animator]: animator state");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010348 pw.println(" s[essions]: active sessions");
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010349 pw.println(" d[isplays]: active display contents");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010350 pw.println(" t[okens]: token list");
10351 pw.println(" w[indows]: window list");
10352 pw.println(" cmd may also be a NAME to dump windows. NAME may");
10353 pw.println(" be a partial substring in a window name, a");
10354 pw.println(" Window hex object identifier, or");
10355 pw.println(" \"all\" for all windows, or");
10356 pw.println(" \"visible\" for the visible windows.");
10357 pw.println(" -a: include all available server state.");
10358 return;
Dianne Hackborn87fc3082010-12-03 13:09:12 -080010359 } else {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010360 pw.println("Unknown argument: " + opt + "; use -h for help");
Dianne Hackborn87fc3082010-12-03 13:09:12 -080010361 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010362 }
10363
10364 // Is the caller requesting to dump a particular piece of data?
10365 if (opti < args.length) {
10366 String cmd = args[opti];
10367 opti++;
Jeff Brownd7a04de2012-06-17 14:17:52 -070010368 if ("lastanr".equals(cmd) || "l".equals(cmd)) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010369 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010370 dumpLastANRLocked(pw);
10371 }
10372 return;
10373 } else if ("policy".equals(cmd) || "p".equals(cmd)) {
10374 synchronized(mWindowMap) {
10375 dumpPolicyLocked(pw, args, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010376 }
10377 return;
Dianne Hackborn529e7442012-11-01 14:22:28 -070010378 } else if ("animator".equals(cmd) || "a".equals(cmd)) {
10379 synchronized(mWindowMap) {
10380 dumpAnimatorLocked(pw, args, true);
10381 }
10382 return;
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010383 } else if ("sessions".equals(cmd) || "s".equals(cmd)) {
10384 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010385 dumpSessionsLocked(pw, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010386 }
10387 return;
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010388 } else if ("displays".equals(cmd) || "d".equals(cmd)) {
10389 synchronized(mWindowMap) {
10390 dumpDisplayContentsLocked(pw, true);
10391 }
10392 return;
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010393 } else if ("tokens".equals(cmd) || "t".equals(cmd)) {
10394 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010395 dumpTokensLocked(pw, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010396 }
10397 return;
10398 } else if ("windows".equals(cmd) || "w".equals(cmd)) {
10399 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010400 dumpWindowsLocked(pw, true, null);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010401 }
10402 return;
10403 } else if ("all".equals(cmd) || "a".equals(cmd)) {
10404 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010405 dumpWindowsLocked(pw, true, null);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010406 }
10407 return;
10408 } else {
10409 // Dumping a single name?
Jeff Brownd7a04de2012-06-17 14:17:52 -070010410 if (!dumpWindows(pw, cmd, args, opti, dumpAll)) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010411 pw.println("Bad window command, or no windows match: " + cmd);
10412 pw.println("Use -h for help.");
10413 }
10414 return;
10415 }
10416 }
10417
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010418 synchronized(mWindowMap) {
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010419 pw.println();
10420 if (dumpAll) {
10421 pw.println("-------------------------------------------------------------------------------");
10422 }
10423 dumpLastANRLocked(pw);
10424 pw.println();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010425 if (dumpAll) {
10426 pw.println("-------------------------------------------------------------------------------");
10427 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010428 dumpPolicyLocked(pw, args, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010429 pw.println();
10430 if (dumpAll) {
10431 pw.println("-------------------------------------------------------------------------------");
10432 }
Dianne Hackborn529e7442012-11-01 14:22:28 -070010433 dumpAnimatorLocked(pw, args, dumpAll);
10434 pw.println();
10435 if (dumpAll) {
10436 pw.println("-------------------------------------------------------------------------------");
10437 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010438 dumpSessionsLocked(pw, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010439 pw.println();
10440 if (dumpAll) {
10441 pw.println("-------------------------------------------------------------------------------");
10442 }
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010443 dumpDisplayContentsLocked(pw, dumpAll);
10444 pw.println();
10445 if (dumpAll) {
10446 pw.println("-------------------------------------------------------------------------------");
10447 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010448 dumpTokensLocked(pw, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010449 pw.println();
10450 if (dumpAll) {
10451 pw.println("-------------------------------------------------------------------------------");
10452 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010453 dumpWindowsLocked(pw, dumpAll, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010454 }
10455 }
10456
Jeff Brown349703e2010-06-22 01:27:15 -070010457 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
Craig Mautner96868332012-12-04 14:29:11 -080010458 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010459 public void monitor() {
10460 synchronized (mWindowMap) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070010461 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010462
Jeff Brown2992ea72011-01-28 22:04:14 -080010463 public interface OnHardKeyboardStatusChangeListener {
10464 public void onHardKeyboardStatusChange(boolean available, boolean enabled);
10465 }
Craig Mautnera2c77052012-03-26 12:14:43 -070010466
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070010467 void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
Craig Mautnercf8cbbe2012-03-25 21:54:36 -070010468 if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070010469 Slog.v(TAG, "Layouts looping: " + msg + ", mPendingLayoutChanges = 0x" +
10470 Integer.toHexString(pendingLayoutChanges));
Craig Mautnercf8cbbe2012-03-25 21:54:36 -070010471 }
10472 }
Craig Mautner59c00972012-07-30 12:10:24 -070010473
Dianne Hackbornc652de82013-02-15 16:32:56 -080010474 private DisplayContent newDisplayContentLocked(final Display display) {
10475 DisplayContent displayContent = new DisplayContent(display);
10476 mDisplayContents.put(display.getDisplayId(), displayContent);
10477 final Rect rect = new Rect();
10478 DisplayInfo info = displayContent.getDisplayInfo();
10479 mDisplaySettings.getOverscanLocked(info.name, rect);
10480 info.overscanLeft = rect.left;
10481 info.overscanTop = rect.top;
10482 info.overscanRight = rect.right;
10483 info.overscanBottom = rect.bottom;
10484 mDisplayManagerService.setOverscan(display.getDisplayId(), rect.left, rect.top,
10485 rect.right, rect.bottom);
10486 mPolicy.setDisplayOverscan(displayContent.getDisplay(), rect.left, rect.top,
10487 rect.right, rect.bottom);
10488 return displayContent;
10489 }
10490
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010491 public void createDisplayContentLocked(final Display display) {
Craig Mautner722285e2012-09-07 13:55:58 -070010492 if (display == null) {
10493 throw new IllegalArgumentException("getDisplayContent: display must not be null");
10494 }
Dianne Hackbornc652de82013-02-15 16:32:56 -080010495 newDisplayContentLocked(display);
Craig Mautner722285e2012-09-07 13:55:58 -070010496 }
10497
Craig Mautner2d5618c2012-10-18 13:55:47 -070010498 /**
10499 * Retrieve the DisplayContent for the specified displayId. Will create a new DisplayContent if
10500 * there is a Display for the displayId.
10501 * @param displayId The display the caller is interested in.
10502 * @return The DisplayContent associated with displayId or null if there is no Display for it.
10503 */
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010504 public DisplayContent getDisplayContentLocked(final int displayId) {
Craig Mautner59c00972012-07-30 12:10:24 -070010505 DisplayContent displayContent = mDisplayContents.get(displayId);
10506 if (displayContent == null) {
Craig Mautner2d5618c2012-10-18 13:55:47 -070010507 final Display display = mDisplayManager.getDisplay(displayId);
10508 if (display != null) {
Dianne Hackbornc652de82013-02-15 16:32:56 -080010509 displayContent = newDisplayContentLocked(display);
Craig Mautner2d5618c2012-10-18 13:55:47 -070010510 }
Craig Mautner59c00972012-07-30 12:10:24 -070010511 }
10512 return displayContent;
10513 }
10514
Craig Mautner2d5618c2012-10-18 13:55:47 -070010515 // There is an inherent assumption that this will never return null.
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010516 public DisplayContent getDefaultDisplayContentLocked() {
10517 return getDisplayContentLocked(Display.DEFAULT_DISPLAY);
Craig Mautner59c00972012-07-30 12:10:24 -070010518 }
10519
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010520 public WindowList getDefaultWindowListLocked() {
10521 return getDefaultDisplayContentLocked().getWindowList();
Craig Mautner59c00972012-07-30 12:10:24 -070010522 }
10523
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010524 public DisplayInfo getDefaultDisplayInfoLocked() {
10525 return getDefaultDisplayContentLocked().getDisplayInfo();
Craig Mautner59c00972012-07-30 12:10:24 -070010526 }
10527
Craig Mautner2d5618c2012-10-18 13:55:47 -070010528 /**
10529 * Return the list of WindowStates associated on the passed display.
10530 * @param display The screen to return windows from.
10531 * @return The list of WindowStates on the screen, or null if the there is no screen.
10532 */
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010533 public WindowList getWindowListLocked(final Display display) {
Craig Mautner96868332012-12-04 14:29:11 -080010534 return getWindowListLocked(display.getDisplayId());
10535 }
10536
10537 /**
10538 * Return the list of WindowStates associated on the passed display.
10539 * @param displayId The screen to return windows from.
10540 * @return The list of WindowStates on the screen, or null if the there is no screen.
10541 */
10542 public WindowList getWindowListLocked(final int displayId) {
10543 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -070010544 return displayContent != null ? displayContent.getWindowList() : null;
Craig Mautner39834192012-09-02 07:47:24 -070010545 }
Craig Mautner722285e2012-09-07 13:55:58 -070010546
10547 @Override
10548 public void onDisplayAdded(int displayId) {
10549 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_ADDED, displayId, 0));
10550 }
10551
10552 private void handleDisplayAddedLocked(int displayId) {
Craig Mautner2d5618c2012-10-18 13:55:47 -070010553 final Display display = mDisplayManager.getDisplay(displayId);
10554 if (display != null) {
10555 createDisplayContentLocked(display);
10556 displayReady(displayId);
10557 }
Craig Mautner722285e2012-09-07 13:55:58 -070010558 }
10559
10560 @Override
10561 public void onDisplayRemoved(int displayId) {
10562 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_REMOVED, displayId, 0));
10563 }
10564
10565 private void handleDisplayRemovedLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010566 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -070010567 if (displayContent != null) {
10568 mDisplayContents.delete(displayId);
10569 WindowList windows = displayContent.getWindowList();
10570 while (!windows.isEmpty()) {
10571 final WindowState win = windows.get(windows.size() - 1);
10572 removeWindowLocked(win.mSession, win);
10573 }
Craig Mautner722285e2012-09-07 13:55:58 -070010574 }
Craig Mautnera91f9e22012-09-14 16:22:08 -070010575 mAnimator.removeDisplayLocked(displayId);
Craig Mautner722285e2012-09-07 13:55:58 -070010576 }
10577
10578 @Override
10579 public void onDisplayChanged(int displayId) {
10580 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_CHANGED, displayId, 0));
10581 }
10582
10583 private void handleDisplayChangedLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010584 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner722285e2012-09-07 13:55:58 -070010585 if (displayContent != null) {
10586 displayContent.updateDisplayInfo();
10587 }
10588 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010589}