blob: cf249ddc97f43ba61b2e1026898b27cba103dca1 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080017package com.android.server.wm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
Craig Mautner9e4f28c2013-04-03 10:53:23 -070019import static android.view.WindowManager.LayoutParams.*;
20
Craig Mautnerae446592012-12-06 19:05:05 -080021import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
22
Dianne Hackbornc2293022013-02-06 23:14:49 -080023import android.app.AppOpsManager;
Craig Mautner9ef471f2014-02-07 13:11:47 -080024import android.util.ArraySet;
Dianne Hackborna57c6952013-03-29 14:46:40 -070025import android.util.TimeUtils;
Dianne Hackborne3f23a32013-03-01 13:25:35 -080026import android.view.IWindowId;
Craig Mautner5eda9b32013-07-02 11:58:16 -070027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import com.android.internal.app.IBatteryStats;
29import com.android.internal.policy.PolicyManager;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080030import com.android.internal.policy.impl.PhoneWindowManager;
Dianne Hackborn8c841092013-06-24 13:46:13 -070031import com.android.internal.util.FastPrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import com.android.internal.view.IInputContext;
33import com.android.internal.view.IInputMethodClient;
34import com.android.internal.view.IInputMethodManager;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080035import com.android.internal.view.WindowManagerPolicyThread;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080036import com.android.server.AttributeCache;
Jeff Brown4ccb8232014-01-16 22:16:42 -080037import com.android.server.DisplayThread;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080038import com.android.server.EventLogTags;
Jeff Brown6f357d32014-01-15 20:40:55 -080039import com.android.server.LocalServices;
Dianne Hackborn8d044e82013-04-30 17:24:15 -070040import com.android.server.UiThread;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080041import com.android.server.Watchdog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import com.android.server.am.BatteryStatsService;
Jeff Brown4532e612012-04-05 14:27:12 -070043import com.android.server.input.InputManagerService;
Jeff Brown4f8ecd82012-06-18 18:29:13 -070044import com.android.server.power.ShutdownThread;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045
46import android.Manifest;
47import android.app.ActivityManagerNative;
48import android.app.IActivityManager;
Joe Onoratoac0ee892011-01-30 15:38:30 -080049import android.app.StatusBarManager;
Jim Millerd6b57052010-06-07 17:52:42 -070050import android.app.admin.DevicePolicyManager;
Jeff Brownff7e6ef2012-08-15 02:05:18 -070051import android.animation.ValueAnimator;
Jim Miller284b62e2010-06-08 14:27:42 -070052import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053import android.content.Context;
Jim Miller284b62e2010-06-08 14:27:42 -070054import android.content.Intent;
55import android.content.IntentFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056import android.content.pm.ActivityInfo;
57import android.content.pm.PackageManager;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070058import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059import android.content.res.Configuration;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080060import android.graphics.Bitmap;
John Reck172e87c2013-10-02 16:55:16 -070061import android.graphics.Bitmap.Config;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070062import android.graphics.Canvas;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063import android.graphics.Matrix;
64import android.graphics.PixelFormat;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -070065import android.graphics.Point;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.graphics.Rect;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070067import android.graphics.RectF;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068import android.graphics.Region;
Craig Mautnerb47bbc32012-08-22 17:41:48 -070069import android.hardware.display.DisplayManager;
Jeff Brown4ccb8232014-01-16 22:16:42 -080070import android.hardware.display.DisplayManagerInternal;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071import android.os.Binder;
Dianne Hackborn75804932009-10-20 20:15:20 -070072import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.os.Debug;
74import android.os.Handler;
75import android.os.IBinder;
Dianne Hackborn38e29a62011-09-18 14:43:08 -070076import android.os.IRemoteCallback;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077import android.os.Looper;
78import android.os.Message;
79import android.os.Parcel;
80import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.os.PowerManager;
Jeff Brown6f357d32014-01-15 20:40:55 -080082import android.os.PowerManagerInternal;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083import android.os.Process;
84import android.os.RemoteException;
85import android.os.ServiceManager;
Brad Fitzpatrickec062f62010-11-03 09:56:54 -070086import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087import android.os.SystemClock;
88import android.os.SystemProperties;
Dianne Hackborn1ded0b12012-04-26 14:14:50 -070089import android.os.Trace;
Craig Mautner259328c2012-08-21 19:30:58 -070090import android.os.WorkSource;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091import android.provider.Settings;
Dianne Hackborn723738c2009-06-25 19:48:04 -070092import android.util.DisplayMetrics;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093import android.util.EventLog;
Michael Jurka4accb6a2012-03-26 09:18:46 -070094import android.util.FloatMath;
Jim Millerd6b57052010-06-07 17:52:42 -070095import android.util.Log;
Craig Mautner59c00972012-07-30 12:10:24 -070096import android.util.SparseArray;
Dianne Hackborn38e29a62011-09-18 14:43:08 -070097import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -080098import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099import android.util.SparseIntArray;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700100import android.util.TypedValue;
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800101import android.view.Choreographer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import android.view.Display;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700103import android.view.DisplayInfo;
Adam Powelldfee59a2011-08-05 20:48:30 -0700104import android.view.Gravity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import android.view.IApplicationToken;
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -0700106import android.view.IInputFilter;
Svetoslav Ganov545252f2012-12-10 18:29:24 -0800107import android.view.IMagnificationCallbacks;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.view.IOnKeyguardExitResult;
109import android.view.IRotationWatcher;
110import android.view.IWindow;
111import android.view.IWindowManager;
112import android.view.IWindowSession;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700113import android.view.InputChannel;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700114import android.view.InputDevice;
Jeff Brownbbda99d2010-07-28 15:48:59 -0700115import android.view.InputEvent;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800116import android.view.InputEventReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117import android.view.KeyEvent;
Svetoslav Ganov545252f2012-12-10 18:29:24 -0800118import android.view.MagnificationSpec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119import android.view.MotionEvent;
Jeff Brown4ccb8232014-01-16 22:16:42 -0800120import android.view.WindowManagerInternal;
Igor Murashkina86ab6402013-08-30 12:58:36 -0700121import android.view.Surface.OutOfResourcesException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122import android.view.Surface;
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800123import android.view.SurfaceControl;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124import android.view.SurfaceSession;
125import android.view.View;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700126import android.view.ViewTreeObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127import android.view.WindowManager;
Jeff Brown98365d72012-08-19 20:30:52 -0700128import android.view.WindowManagerGlobal;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129import android.view.WindowManagerPolicy;
130import android.view.WindowManager.LayoutParams;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700131import android.view.WindowManagerPolicy.FakeWindow;
Craig Mautner037aa8d2013-06-07 10:35:44 -0700132import android.view.WindowManagerPolicy.PointerEventListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133import android.view.animation.Animation;
134import android.view.animation.AnimationUtils;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700135import android.view.animation.Transformation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136
137import java.io.BufferedWriter;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700138import java.io.DataInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139import java.io.File;
140import java.io.FileDescriptor;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700141import java.io.FileInputStream;
142import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143import java.io.IOException;
144import java.io.OutputStream;
145import java.io.OutputStreamWriter;
146import java.io.PrintWriter;
147import java.io.StringWriter;
148import java.net.Socket;
Jeff Brownd7a04de2012-06-17 14:17:52 -0700149import java.text.DateFormat;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150import java.util.ArrayList;
Jeff Brownd7a04de2012-06-17 14:17:52 -0700151import java.util.Date;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152import java.util.HashMap;
153import java.util.HashSet;
154import java.util.Iterator;
155import java.util.List;
156
157/** {@hide} */
Dianne Hackbornddca3ee2009-07-23 19:01:31 -0700158public class WindowManagerService extends IWindowManager.Stub
Craig Mautnerdf88d732014-01-27 09:21:32 -0800159 implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 static final String TAG = "WindowManager";
161 static final boolean DEBUG = false;
Craig Mautnerac565142013-09-23 17:37:09 -0700162 static final boolean DEBUG_ADD_REMOVE = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800163 static final boolean DEBUG_FOCUS = false;
Craig Mautnerb3370ce2013-09-19 12:02:09 -0700164 static final boolean DEBUG_FOCUS_LIGHT = DEBUG_FOCUS || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 static final boolean DEBUG_ANIM = false;
Dianne Hackborn9b52a212009-12-11 14:51:35 -0800166 static final boolean DEBUG_LAYOUT = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800167 static final boolean DEBUG_RESIZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 static final boolean DEBUG_LAYERS = false;
169 static final boolean DEBUG_INPUT = false;
170 static final boolean DEBUG_INPUT_METHOD = false;
171 static final boolean DEBUG_VISIBILITY = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700172 static final boolean DEBUG_WINDOW_MOVEMENT = false;
Craig Mautnerd9a22882013-03-16 15:00:36 -0700173 static final boolean DEBUG_TOKEN_MOVEMENT = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 static final boolean DEBUG_ORIENTATION = false;
Dianne Hackbornbc7386c2011-06-06 17:27:54 -0700175 static final boolean DEBUG_APP_ORIENTATION = false;
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700176 static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800177 static final boolean DEBUG_APP_TRANSITIONS = false;
178 static final boolean DEBUG_STARTING_WINDOW = false;
179 static final boolean DEBUG_REORDER = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800180 static final boolean DEBUG_WALLPAPER = false;
Dianne Hackborn98129732012-11-01 16:28:16 -0700181 static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER;
Christopher Tate994ef922011-01-12 20:06:07 -0800182 static final boolean DEBUG_DRAG = false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700183 static final boolean DEBUG_SCREEN_ON = false;
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -0700184 static final boolean DEBUG_SCREENSHOT = false;
Dianne Hackborn38cc8962011-10-13 11:33:55 -0700185 static final boolean DEBUG_BOOT = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700186 static final boolean DEBUG_LAYOUT_REPEATS = true;
Craig Mautner7358fbf2012-04-12 21:06:33 -0700187 static final boolean DEBUG_SURFACE_TRACE = false;
Craig Mautner7d8df392012-04-06 15:26:23 -0700188 static final boolean DEBUG_WINDOW_TRACE = false;
Craig Mautner926f3832013-02-13 11:56:07 -0800189 static final boolean DEBUG_TASK_MOVEMENT = false;
Craig Mautner58004432013-10-14 12:58:42 -0700190 static final boolean DEBUG_STACK = false;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700191 static final boolean SHOW_SURFACE_ALLOC = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800192 static final boolean SHOW_TRANSACTIONS = false;
Dianne Hackborn36991742011-10-11 21:35:26 -0700193 static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700194 static final boolean HIDE_STACK_CRAWLS = true;
Craig Mautnercf8cbbe2012-03-25 21:54:36 -0700195 static final int LAYOUT_REPEAT_THRESHOLD = 4;
Michael Chan53071d62009-05-13 17:29:48 -0700196
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 static final boolean PROFILE_ORIENTATION = false;
Dave Bortcfe65242009-04-09 14:51:04 -0700198 static final boolean localLOGV = DEBUG;
Romain Guy06882f82009-06-10 13:36:04 -0700199
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200 /** How much to multiply the policy's type layer, to reserve room
201 * for multiple windows of the same type and Z-ordering adjustment
202 * with TYPE_LAYER_OFFSET. */
203 static final int TYPE_LAYER_MULTIPLIER = 10000;
Romain Guy06882f82009-06-10 13:36:04 -0700204
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
206 * or below others in the same layer. */
207 static final int TYPE_LAYER_OFFSET = 1000;
Romain Guy06882f82009-06-10 13:36:04 -0700208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 /** How much to increment the layer for each window, to reserve room
210 * for effect surfaces between them.
211 */
212 static final int WINDOW_LAYER_MULTIPLIER = 5;
Romain Guy06882f82009-06-10 13:36:04 -0700213
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800214 /**
215 * Dim surface layer is immediately below target window.
216 */
217 static final int LAYER_OFFSET_DIM = 1;
218
219 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700220 * Blur surface layer is immediately below dim layer.
221 */
222 static final int LAYER_OFFSET_BLUR = 2;
223
224 /**
Craig Mautnerf7666462013-04-28 08:58:21 -0700225 * FocusedStackFrame layer is immediately above focused window.
226 */
227 static final int LAYER_OFFSET_FOCUSED_STACK = 1;
228
229 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700230 * Animation thumbnail is as far as possible below the window above
231 * the thumbnail (or in other words as far as possible above the window
232 * below it).
233 */
234 static final int LAYER_OFFSET_THUMBNAIL = WINDOW_LAYER_MULTIPLIER-1;
235
236 /**
Dianne Hackborn7916ac62011-05-16 20:45:48 -0700237 * Layer at which to put the rotation freeze snapshot.
238 */
239 static final int FREEZE_LAYER = (TYPE_LAYER_MULTIPLIER * 200) + 1;
240
241 /**
242 * Layer at which to put the mask for emulated screen sizes.
243 */
244 static final int MASK_LAYER = TYPE_LAYER_MULTIPLIER * 200;
245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246 /** The maximum length we will accept for a loaded animation duration:
247 * this is 10 seconds.
248 */
249 static final int MAX_ANIMATION_DURATION = 10*1000;
250
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700251 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
252 * compatible windows.
253 */
254 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
255
Craig Mautner7dfcb012012-10-10 10:24:47 -0700256 /** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */
Craig Mautnera4942c92012-10-16 09:06:53 -0700257 static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000;
Craig Mautner7dfcb012012-10-10 10:24:47 -0700258
Craig Mautner68cc2412013-10-01 10:39:43 -0700259 /** Amount of time (in milliseconds) to delay before declaring a starting window leaked. */
260 static final int STARTING_WINDOW_TIMEOUT_DURATION = 10000;
261
Dianne Hackborna1111872010-11-23 20:55:11 -0800262 /**
263 * If true, the window manager will do its own custom freezing and general
264 * management of the screen during rotation.
265 */
266 static final boolean CUSTOM_SCREEN_ROTATION = true;
267
Jeff Brownb09abc12011-01-13 21:08:27 -0800268 // Maximum number of milliseconds to wait for input devices to be enumerated before
269 // proceding with safe mode detection.
270 private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
Jim Miller28637ba2011-07-06 19:57:05 -0700271
Jeff Brown349703e2010-06-22 01:27:15 -0700272 // Default input dispatching timeout in nanoseconds.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800273 static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
Romain Guy06882f82009-06-10 13:36:04 -0700274
Craig Mautnerdf88d732014-01-27 09:21:32 -0800275 /** Minimum value for attachStack and resizeStack weight value */
Craig Mautner967212c2013-04-13 21:10:58 -0700276 public static final float STACK_WEIGHT_MIN = 0.2f;
277
Craig Mautnerdf88d732014-01-27 09:21:32 -0800278 /** Maximum value for attachStack and resizeStack weight value */
Craig Mautner967212c2013-04-13 21:10:58 -0700279 public static final float STACK_WEIGHT_MAX = 0.8f;
280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281 static final int UPDATE_FOCUS_NORMAL = 0;
282 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
283 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
284 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700287 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288
Colin Crossef96fd92013-07-18 17:09:56 -0700289 private static final String DENSITY_OVERRIDE = "ro.config.density_override";
290 private static final String SIZE_OVERRIDE = "ro.config.size_override";
291
Craig Mautner24d887472013-03-20 15:40:36 -0700292 private static final int MAX_SCREENSHOT_RETRIES = 3;
293
Craig Mautner5642a482012-08-23 12:16:53 -0700294 final private KeyguardDisableHandler mKeyguardDisableHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800295
Jim Miller284b62e2010-06-08 14:27:42 -0700296 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
297 @Override
298 public void onReceive(Context context, Intent intent) {
Craig Mautner9dc52bc2012-08-06 14:15:42 -0700299 final String action = intent.getAction();
300 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
Craig Mautner5642a482012-08-23 12:16:53 -0700301 mKeyguardDisableHandler.sendEmptyMessage(
302 KeyguardDisableHandler.KEYGUARD_POLICY_CHANGED);
Jim Miller284b62e2010-06-08 14:27:42 -0700303 }
304 }
305 };
306
Craig Mautner9dc52bc2012-08-06 14:15:42 -0700307 // Current user when multi-user is enabled. Don't show windows of non-current user.
308 int mCurrentUserId;
309
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 final Context mContext;
311
312 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700313
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700314 final boolean mAllowBootMessages;
315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700317
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
319
320 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700323
Dianne Hackbornc2293022013-02-06 23:14:49 -0800324 final AppOpsManager mAppOps;
325
Dianne Hackbornc652de82013-02-15 16:32:56 -0800326 final DisplaySettings mDisplaySettings;
327
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 /**
329 * All currently active sessions with clients.
330 */
331 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700332
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 /**
334 * Mapping from an IWindow IBinder to the server's Window object.
335 * This is also used as the lock for all of our state.
Craig Mautner58106812012-12-28 12:27:40 -0800336 * NOTE: Never call into methods that lock ActivityManagerService while holding this object.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 */
338 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
339
340 /**
341 * Mapping from a token IBinder to a WindowToken object.
342 */
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800343 final HashMap<IBinder, WindowToken> mTokenMap = new HashMap<IBinder, WindowToken>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344
345 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 * List of window tokens that have finished starting their application,
347 * and now need to have the policy remove their windows.
348 */
349 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
350
351 /**
Dianne Hackborndf89e652011-10-06 22:35:11 -0700352 * Fake windows added to the window manager. Note: ordered from top to
353 * bottom, opposite of mWindows.
354 */
355 final ArrayList<FakeWindowImpl> mFakeWindows = new ArrayList<FakeWindowImpl>();
356
357 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 * Windows that are being resized. Used so we can tell the client about
359 * the resize after closing the transaction in which we resized the
360 * underlying surface.
361 */
362 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
363
364 /**
365 * Windows whose animations have ended and now must be removed.
366 */
367 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
368
369 /**
Craig Mautner9ef471f2014-02-07 13:11:47 -0800370 * Stacks whose animations have ended and whose tasks, apps, selves may now be removed.
371 */
372 final ArraySet<TaskStack> mPendingStacksRemove = new ArraySet<TaskStack>();
373
374 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800375 * Used when processing mPendingRemove to avoid working on the original array.
376 */
377 WindowState[] mPendingRemoveTmp = new WindowState[20];
378
379 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800380 * Windows whose surface should be destroyed.
381 */
382 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
383
384 /**
385 * Windows that have lost input focus and are waiting for the new
386 * focus window to be displayed before they are told about this.
387 */
388 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
389
390 /**
391 * This is set when we have run out of memory, and will either be an empty
392 * list or contain windows that need to be force removed.
393 */
394 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700395
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800396 /**
Dianne Hackborn38e29a62011-09-18 14:43:08 -0700397 * Windows that clients are waiting to have drawn.
398 */
399 ArrayList<Pair<WindowState, IRemoteCallback>> mWaitingForDrawn
400 = new ArrayList<Pair<WindowState, IRemoteCallback>>();
401
402 /**
Dianne Hackborn12d3a942012-04-27 14:16:30 -0700403 * Windows that have called relayout() while we were running animations,
404 * so we need to tell when the animation is done.
405 */
406 final ArrayList<WindowState> mRelayoutWhileAnimating = new ArrayList<WindowState>();
407
408 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800409 * Used when rebuilding window list to keep track of windows that have
410 * been removed.
411 */
412 WindowState[] mRebuildTmp = new WindowState[20];
413
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700415
Svetoslav Ganov545252f2012-12-10 18:29:24 -0800416 DisplayMagnifier mDisplayMagnifier;
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -0700417
Craig Mautner7358fbf2012-04-12 21:06:33 -0700418 final SurfaceSession mFxSession;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700419 Watermark mWatermark;
Brad Fitzpatrick68044332010-11-22 18:19:48 -0800420 StrictModeFlash mStrictModeFlash;
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700421 FocusedStackFrame mFocusedStackFrame;
Romain Guy06882f82009-06-10 13:36:04 -0700422
Craig Mautnerf7666462013-04-28 08:58:21 -0700423 int mFocusedStackLayer;
424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425 final float[] mTmpFloats = new float[9];
John Spurlock4e92a7c2013-09-24 17:09:05 -0400426 final Rect mTmpContentRect = new Rect();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427
Jeff Browne215f262012-09-10 16:01:14 -0700428 boolean mDisplayReady;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800429 boolean mSafeMode;
430 boolean mDisplayEnabled = false;
431 boolean mSystemBooted = false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700432 boolean mForceDisplayEnabled = false;
Dianne Hackborn661cd522011-08-22 00:26:20 -0700433 boolean mShowingBootMessages = false;
Dianne Hackborn1fbee792011-11-30 11:29:58 -0800434
Jeff Brownd7a04de2012-06-17 14:17:52 -0700435 String mLastANRState;
436
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800437 /** All DisplayContents in the world, kept here */
Craig Mautnerf8924152013-07-16 09:10:55 -0700438 SparseArray<DisplayContent> mDisplayContents = new SparseArray<DisplayContent>(2);
Craig Mautner343ad712013-02-13 22:37:26 -0800439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800440 int mRotation = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborndacea8c2011-04-21 17:26:39 -0700442 boolean mAltOrientation = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800443 ArrayList<IRotationWatcher> mRotationWatchers
444 = new ArrayList<IRotationWatcher>();
Jeff Brown01a98dd2011-09-20 15:08:29 -0700445 int mDeferredRotationPauseCount;
Romain Guy06882f82009-06-10 13:36:04 -0700446
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700447 int mSystemDecorLayer = 0;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700448 final Rect mScreenRect = new Rect();
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700449
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800450 boolean mTraversalScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 boolean mDisplayFrozen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -0700452 long mDisplayFreezeTime = 0;
453 int mLastDisplayFreezeDuration = 0;
454 Object mLastFinishedFreezeSource = null;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800455 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800456 boolean mWindowsFreezingScreen = false;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700457 boolean mClientFreezingScreen = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458 int mAppsFreezingScreen = 0;
Dianne Hackbornbc7386c2011-06-06 17:27:54 -0700459 int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800460
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800461 int mLayoutSeq = 0;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700462
463 int mLastStatusBarVisibility = 0;
464
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800465 // State while inside of layoutAndPlaceSurfacesLocked().
466 boolean mFocusMayChange;
Craig Mautner01cd0e72012-06-18 10:19:11 -0700467
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800468 Configuration mCurConfiguration = new Configuration();
Craig Mautner01cd0e72012-06-18 10:19:11 -0700469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 // This is held as long as we have the screen frozen, to give us time to
471 // perform a rotation animation when turning off shows the lock screen which
472 // changes the orientation.
Igor Murashkina86ab6402013-08-30 12:58:36 -0700473 private final PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700474
Craig Mautner164d4bb2012-11-26 13:51:23 -0800475 final AppTransition mAppTransition;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800476 boolean mStartingIconInTransition = false;
477 boolean mSkipAppTransitionAnimation = false;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800478
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800479 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
480 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700481
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700482 boolean mIsTouchDevice;
483
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700484 final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Jeff Brownbc68a592011-07-25 12:58:12 -0700485 final DisplayMetrics mRealDisplayMetrics = new DisplayMetrics();
Dianne Hackborn48a76512011-06-08 21:51:44 -0700486 final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics();
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700487 final DisplayMetrics mCompatDisplayMetrics = new DisplayMetrics();
488
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800489 final H mH = new H();
490
491 final Choreographer mChoreographer = Choreographer.getInstance();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800492
493 WindowState mCurrentFocus = null;
494 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700495
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800496 /** This just indicates the window the input method is on top of, not
497 * necessarily the window its input is going to. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498 WindowState mInputMethodTarget = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800499
500 /** If true hold off on modifying the animation layer of mInputMethodTarget */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501 boolean mInputMethodTargetWaitingAnim;
502 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700503
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504 WindowState mInputMethodWindow = null;
505 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
506
Jeff Brown2992ea72011-01-28 22:04:14 -0800507 boolean mHardKeyboardAvailable;
508 boolean mHardKeyboardEnabled;
509 OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
510
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700511 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800512
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700513 // If non-null, this is the currently visible window that is associated
514 // with the wallpaper.
515 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700516 // If non-null, we are in the middle of animating from one wallpaper target
517 // to another, and this is the lower one in Z-order.
Dianne Hackborn98129732012-11-01 16:28:16 -0700518 WindowState mLowerWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700519 // If non-null, we are in the middle of animating from one wallpaper target
520 // to another, and this is the higher one in Z-order.
Craig Mautner96868332012-12-04 14:29:11 -0800521 WindowState mUpperWallpaperTarget = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700522 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700523 float mLastWallpaperX = -1;
524 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800525 float mLastWallpaperXStep = -1;
526 float mLastWallpaperYStep = -1;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700527 // This is set when we are waiting for a wallpaper to tell us it is done
528 // changing its scroll position.
529 WindowState mWaitingOnWallpaper;
530 // The last time we had a timeout when waiting for a wallpaper.
531 long mLastWallpaperTimeoutTime;
532 // We give a wallpaper up to 150ms to finish scrolling.
533 static final long WALLPAPER_TIMEOUT = 150;
534 // Time we wait after a timeout before trying to wait again.
535 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Craig Mautner798adef2013-10-22 14:29:01 -0700536 boolean mAnimateWallpaperWithTarget;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800538 AppWindowToken mFocusedApp = null;
539
Jeff Brown6f357d32014-01-15 20:40:55 -0800540 PowerManager mPowerManager;
541 PowerManagerInternal mPowerManagerInternal;
Romain Guy06882f82009-06-10 13:36:04 -0700542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800543 float mWindowAnimationScale = 1.0f;
544 float mTransitionAnimationScale = 1.0f;
Chet Haasec38fa1f2012-02-01 16:37:46 -0800545 float mAnimatorDurationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700546
Jeff Brown4532e612012-04-05 14:27:12 -0700547 final InputManagerService mInputManager;
Jeff Brown4ccb8232014-01-16 22:16:42 -0800548 final DisplayManagerInternal mDisplayManagerInternal;
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700549 final DisplayManager mDisplayManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550
551 // Who is holding the screen on.
552 Session mHoldingScreenOn;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700553 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700554
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700555 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800556
Christopher Tatea53146c2010-09-07 11:57:52 -0700557 DragState mDragState = null;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800558
Craig Mautner3c174372013-02-21 17:54:37 -0800559 // For frozen screen animations.
560 int mExitAnimId, mEnterAnimId;
561
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800562 /** Pulled out of performLayoutAndPlaceSurfacesLockedInner in order to refactor into multiple
563 * methods. */
Craig Mautnera608b882012-03-30 13:03:49 -0700564 class LayoutFields {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700565 static final int SET_UPDATE_ROTATION = 1 << 0;
566 static final int SET_WALLPAPER_MAY_CHANGE = 1 << 1;
567 static final int SET_FORCE_HIDING_CHANGED = 1 << 2;
Craig Mautner2639da52012-07-09 09:39:06 -0700568 static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3;
Craig Mautner7d8df392012-04-06 15:26:23 -0700569 static final int SET_TURN_ON_SCREEN = 1 << 4;
Craig Mautner96868332012-12-04 14:29:11 -0800570 static final int SET_WALLPAPER_ACTION_PENDING = 1 << 5;
Craig Mautnera608b882012-03-30 13:03:49 -0700571
Craig Mautner764983d2012-03-22 11:37:36 -0700572 boolean mWallpaperForceHidingChanged = false;
573 boolean mWallpaperMayChange = false;
Craig Mautner764983d2012-03-22 11:37:36 -0700574 boolean mOrientationChangeComplete = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -0700575 Object mLastWindowFreezeSource = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800576 private Session mHoldScreen = null;
577 private boolean mObscured = false;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800578 private boolean mSyswin = false;
579 private float mScreenBrightness = -1;
580 private float mButtonBrightness = -1;
Jeff Brown1e3b98d2012-09-30 18:58:59 -0700581 private long mUserActivityTimeout = -1;
Craig Mautnera608b882012-03-30 13:03:49 -0700582 private boolean mUpdateRotation = false;
Craig Mautner96868332012-12-04 14:29:11 -0800583 boolean mWallpaperActionPending = false;
Craig Mautner65d11b32012-10-01 13:59:52 -0700584
Jeff Brown4fd79172013-11-07 17:58:15 -0800585 // Set to true when the display contains content to show the user.
586 // When false, the display manager may choose to mirror or blank the display.
587 boolean mDisplayHasContent = false;
588
589 // Only set while traversing the default display based on its content.
590 // Affects the behavior of mirroring on secondary displays.
591 boolean mObscureApplicationContentOnSecondaryDisplays = false;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800592 }
Craig Mautner01cd0e72012-06-18 10:19:11 -0700593 final LayoutFields mInnerFields = new LayoutFields();
594
Craig Mautner96868332012-12-04 14:29:11 -0800595 boolean mAnimationScheduled;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800596
Craig Mautner6fbda632012-07-03 09:26:39 -0700597 /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
598 * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
599 private int mTransactionSequence;
600
Craig Mautnerbb1449b2012-03-23 16:11:14 -0700601 /** Only do a maximum of 6 repeated layouts. After that quit */
602 private int mLayoutRepeatCount;
603
Craig Mautner764983d2012-03-22 11:37:36 -0700604 final WindowAnimator mAnimator;
Jeff Brown4a06c802012-02-15 15:06:01 -0800605
Craig Mautnerc00204b2013-03-05 15:02:14 -0800606 SparseArray<Task> mTaskIdToTask = new SparseArray<Task>();
Craig Mautnerdc548482014-02-05 13:35:24 -0800607
608 /** All of the TaskStacks in the window manager, unordered. For an ordered list call
609 * DisplayContent.getStacks(). */
Craig Mautnerc00204b2013-03-05 15:02:14 -0800610 SparseArray<TaskStack> mStackIdToStack = new SparseArray<TaskStack>();
611
Craig Mautner037aa8d2013-06-07 10:35:44 -0700612 private final PointerEventDispatcher mPointerEventDispatcher;
613
Jeff Brown32cbc38552011-12-01 14:01:49 -0800614 final class DragInputEventReceiver extends InputEventReceiver {
615 public DragInputEventReceiver(InputChannel inputChannel, Looper looper) {
616 super(inputChannel, looper);
617 }
618
Christopher Tatea53146c2010-09-07 11:57:52 -0700619 @Override
Jeff Brown32cbc38552011-12-01 14:01:49 -0800620 public void onInputEvent(InputEvent event) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700621 boolean handled = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700622 try {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800623 if (event instanceof MotionEvent
624 && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
Jeff Brown3915bb82010-11-05 15:02:16 -0700625 && mDragState != null) {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800626 final MotionEvent motionEvent = (MotionEvent)event;
Jeff Brown3915bb82010-11-05 15:02:16 -0700627 boolean endDrag = false;
Jeff Brown4952dfd2011-11-30 19:23:22 -0800628 final float newX = motionEvent.getRawX();
629 final float newY = motionEvent.getRawY();
Jeff Brown3915bb82010-11-05 15:02:16 -0700630
Jeff Brown4952dfd2011-11-30 19:23:22 -0800631 switch (motionEvent.getAction()) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700632 case MotionEvent.ACTION_DOWN: {
633 if (DEBUG_DRAG) {
634 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
635 }
636 } break;
637
638 case MotionEvent.ACTION_MOVE: {
639 synchronized (mWindowMap) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700640 // move the surface and tell the involved window(s) where we are
Christopher Tatea53146c2010-09-07 11:57:52 -0700641 mDragState.notifyMoveLw(newX, newY);
642 }
643 } break;
644
645 case MotionEvent.ACTION_UP: {
646 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
647 + newX + "," + newY);
648 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700649 endDrag = mDragState.notifyDropLw(newX, newY);
Christopher Tatea53146c2010-09-07 11:57:52 -0700650 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700651 } break;
652
653 case MotionEvent.ACTION_CANCEL: {
654 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
655 endDrag = true;
656 } break;
657 }
658
659 if (endDrag) {
660 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
661 // tell all the windows that the drag has ended
Chris Tate59943592010-10-11 20:33:44 -0700662 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700663 mDragState.endDragLw();
Chris Tate59943592010-10-11 20:33:44 -0700664 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700665 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700666
667 handled = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700668 }
669 } catch (Exception e) {
670 Slog.e(TAG, "Exception caught by drag handleMotion", e);
671 } finally {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800672 finishInputEvent(event, handled);
Christopher Tatea53146c2010-09-07 11:57:52 -0700673 }
674 }
Jeff Brown32cbc38552011-12-01 14:01:49 -0800675 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700676
677 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800678 * Whether the UI is currently running in touch mode (not showing
679 * navigational focus because the user is directly pressing the screen).
680 */
Michael Jurkae99adc72011-08-11 18:28:01 -0700681 boolean mInTouchMode = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800682
683 private ViewServer mViewServer;
Igor Murashkina86ab6402013-08-30 12:58:36 -0700684 private final ArrayList<WindowChangeListener> mWindowChangeListeners =
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700685 new ArrayList<WindowChangeListener>();
686 private boolean mWindowsChanged = false;
687
688 public interface WindowChangeListener {
689 public void windowsChanged();
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -0700690 public void focusChanged();
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700691 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800692
Dianne Hackbornc485a602009-03-24 22:39:49 -0700693 final Configuration mTempConfiguration = new Configuration();
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700694
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700695 // The desired scaling factor for compatible apps.
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400696 float mCompatibleScreenScale;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700697
Jeff Brown780c46f2012-06-24 12:15:38 -0700698 // If true, only the core apps and services are being launched because the device
699 // is in a special boot mode, such as being encrypted or waiting for a decryption password.
700 // For example, when this flag is true, there will be no wallpaper service.
701 final boolean mOnlyCore;
702
Jeff Brownbd6e1502012-08-28 03:27:37 -0700703 public static WindowManagerService main(final Context context,
Jeff Brown4ccb8232014-01-16 22:16:42 -0800704 final InputManagerService im,
Jeff Brownbd6e1502012-08-28 03:27:37 -0700705 final boolean haveInputMethods, final boolean showBootMsgs,
706 final boolean onlyCore) {
707 final WindowManagerService[] holder = new WindowManagerService[1];
Jeff Brown4ccb8232014-01-16 22:16:42 -0800708 DisplayThread.getHandler().runWithScissors(new Runnable() {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700709 @Override
710 public void run() {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800711 holder[0] = new WindowManagerService(context, im,
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700712 haveInputMethods, showBootMsgs, onlyCore);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800713 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700714 }, 0);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700715 return holder[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800716 }
Romain Guy06882f82009-06-10 13:36:04 -0700717
Jeff Brown4ccb8232014-01-16 22:16:42 -0800718 private void initPolicy() {
719 UiThread.getHandler().runWithScissors(new Runnable() {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700720 @Override
721 public void run() {
722 WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
Romain Guy06882f82009-06-10 13:36:04 -0700723
Jeff Brownbd6e1502012-08-28 03:27:37 -0700724 mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
725 mAnimator.mAboveUniverseLayer = mPolicy.getAboveUniverseLayer()
726 * TYPE_LAYER_MULTIPLIER
727 + TYPE_LAYER_OFFSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800728 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700729 }, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800730 }
731
Jeff Brown4ccb8232014-01-16 22:16:42 -0800732 private WindowManagerService(Context context, InputManagerService inputManager,
Jeff Brown780c46f2012-06-24 12:15:38 -0700733 boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800734 mContext = context;
735 mHaveInputMethods = haveInputMethods;
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700736 mAllowBootMessages = showBootMsgs;
Jeff Brown780c46f2012-06-24 12:15:38 -0700737 mOnlyCore = onlyCore;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800738 mLimitedAlphaCompositing = context.getResources().getBoolean(
739 com.android.internal.R.bool.config_sf_limitedAlpha);
Craig Mautnercf910b02013-04-23 11:23:27 -0700740 mInputManager = inputManager; // Must be before createDisplayContentLocked.
Jeff Brown4ccb8232014-01-16 22:16:42 -0800741 mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800742 mDisplaySettings = new DisplaySettings(context);
743 mDisplaySettings.readSettingsLocked();
Romain Guy06882f82009-06-10 13:36:04 -0700744
Craig Mautner037aa8d2013-06-07 10:35:44 -0700745 mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG));
746
Craig Mautnerdee8bf02013-08-07 09:24:11 -0700747 mFxSession = new SurfaceSession();
Craig Mautner722285e2012-09-07 13:55:58 -0700748 mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
Craig Mautner722285e2012-09-07 13:55:58 -0700749 Display[] displays = mDisplayManager.getDisplays();
750 for (Display display : displays) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -0700751 createDisplayContentLocked(display);
Craig Mautner722285e2012-09-07 13:55:58 -0700752 }
753
Craig Mautner5642a482012-08-23 12:16:53 -0700754 mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);
755
Jeff Brown6f357d32014-01-15 20:40:55 -0800756 mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
757 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
758 mPowerManagerInternal.setPolicy(mPolicy); // TODO: register as local service instead
759 mScreenFrozenLock = mPowerManager.newWakeLock(
760 PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800761 mScreenFrozenLock.setReferenceCounted(false);
762
Craig Mautner164d4bb2012-11-26 13:51:23 -0800763 mAppTransition = new AppTransition(context, mH);
764
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800765 mActivityManager = ActivityManagerNative.getDefault();
766 mBatteryStats = BatteryStatsService.getService();
Dianne Hackbornc2293022013-02-06 23:14:49 -0800767 mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -0800768 mAppOps.startWatchingMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, null,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700769 new AppOpsManager.OnOpChangedInternalListener() {
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -0800770 @Override
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700771 public void onOpChanged(int op, String packageName) {
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -0800772 updateAppOpsState();
773 }
774 }
775 );
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776
777 // Get persisted window scale setting
Jeff Sharkey6e2bee72012-10-01 13:39:08 -0700778 mWindowAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
779 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
780 mTransitionAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
781 Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
782 setAnimatorDurationScale(Settings.Global.getFloat(context.getContentResolver(),
Craig Mautnera7233fe32012-11-15 14:25:14 -0800783 Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale));
Romain Guy06882f82009-06-10 13:36:04 -0700784
Jim Miller284b62e2010-06-08 14:27:42 -0700785 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
786 IntentFilter filter = new IntentFilter();
787 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
788 mContext.registerReceiver(mBroadcastReceiver, filter);
789
Jeff Brown6f357d32014-01-15 20:40:55 -0800790 mHoldingScreenWakeLock = mPowerManager.newWakeLock(
791 PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700792 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800793
Craig Mautner918b53b2012-07-09 14:15:54 -0700794 mAnimator = new WindowAnimator(this);
Romain Guy06882f82009-06-10 13:36:04 -0700795
Jeff Brown4ccb8232014-01-16 22:16:42 -0800796 initPolicy();
Romain Guy06882f82009-06-10 13:36:04 -0700797
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800798 // Add ourself to the Watchdog monitors.
799 Watchdog.getInstance().addMonitor(this);
Craig Mautner7358fbf2012-04-12 21:06:33 -0700800
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800801 SurfaceControl.openTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700802 try {
803 createWatermarkInTransaction();
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700804 mFocusedStackFrame = new FocusedStackFrame(
805 getDefaultDisplayContentLocked().getDisplay(), mFxSession);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700806 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800807 SurfaceControl.closeTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700808 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800809
810 LocalServices.addService(WindowManagerInternal.class, new LocalService());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800811 }
812
Jeff Browna9d131c2012-09-20 16:48:17 -0700813 public InputMonitor getInputMonitor() {
814 return mInputMonitor;
Jeff Brown4532e612012-04-05 14:27:12 -0700815 }
816
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800817 @Override
818 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
819 throws RemoteException {
820 try {
821 return super.onTransact(code, data, reply, flags);
822 } catch (RuntimeException e) {
823 // The window manager only throws security exceptions, so let's
824 // log all others.
825 if (!(e instanceof SecurityException)) {
Dianne Hackborn164371f2013-10-01 19:10:13 -0700826 Slog.wtf(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800827 }
828 throw e;
829 }
830 }
831
Jeff Browne33348b2010-07-15 23:54:05 -0700832 private void placeWindowAfter(WindowState pos, WindowState window) {
Craig Mautner59c00972012-07-30 12:10:24 -0700833 final WindowList windows = pos.getWindowList();
834 final int i = windows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800835 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800836 TAG, "Adding window " + window + " at "
Craig Mautner59c00972012-07-30 12:10:24 -0700837 + (i+1) + " of " + windows.size() + " (after " + pos + ")");
838 windows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700839 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800840 }
841
Jeff Browne33348b2010-07-15 23:54:05 -0700842 private void placeWindowBefore(WindowState pos, WindowState window) {
Craig Mautner59c00972012-07-30 12:10:24 -0700843 final WindowList windows = pos.getWindowList();
Craig Mautnerf81b90872013-02-26 13:02:43 -0800844 int i = windows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800845 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800846 TAG, "Adding window " + window + " at "
Craig Mautner59c00972012-07-30 12:10:24 -0700847 + i + " of " + windows.size() + " (before " + pos + ")");
Craig Mautnerf81b90872013-02-26 13:02:43 -0800848 if (i < 0) {
849 Slog.w(TAG, "placeWindowBefore: Unable to find " + pos + " in " + windows);
850 i = 0;
851 }
Craig Mautner59c00972012-07-30 12:10:24 -0700852 windows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700853 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800854 }
855
856 //This method finds out the index of a window that has the same app token as
857 //win. used for z ordering the windows in mWindows
858 private int findIdxBasedOnAppTokens(WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -0700859 WindowList windows = win.getWindowList();
860 for(int j = windows.size() - 1; j >= 0; j--) {
861 WindowState wentry = windows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800862 if(wentry.mAppToken == win.mAppToken) {
863 return j;
864 }
865 }
866 return -1;
867 }
Romain Guy06882f82009-06-10 13:36:04 -0700868
Craig Mautnerefb735d2012-09-07 15:40:24 -0700869 /**
870 * Return the list of Windows from the passed token on the given Display.
871 * @param token The token with all the windows.
872 * @param displayContent The display we are interested in.
873 * @return List of windows from token that are on displayContent.
874 */
Craig Mautner69b08182012-09-05 13:07:13 -0700875 WindowList getTokenWindowsOnDisplay(WindowToken token, DisplayContent displayContent) {
876 final WindowList windowList = new WindowList();
877 final int count = token.windows.size();
878 for (int i = 0; i < count; i++) {
879 final WindowState win = token.windows.get(i);
Craig Mautnerdf88d732014-01-27 09:21:32 -0800880 if (win.getDisplayContent() == displayContent) {
Craig Mautner69b08182012-09-05 13:07:13 -0700881 windowList.add(win);
882 }
883 }
884 return windowList;
885 }
886
Craig Mautner7b1aa772012-11-30 16:14:45 -0800887 /**
888 * Recursive search through a WindowList and all of its windows' children.
889 * @param targetWin The window to search for.
890 * @param windows The list to search.
891 * @return The index of win in windows or of the window that is an ancestor of win.
892 */
893 private int indexOfWinInWindowList(WindowState targetWin, WindowList windows) {
894 for (int i = windows.size() - 1; i >= 0; i--) {
895 final WindowState w = windows.get(i);
896 if (w == targetWin) {
897 return i;
898 }
899 if (!w.mChildWindows.isEmpty()) {
900 if (indexOfWinInWindowList(targetWin, w.mChildWindows) >= 0) {
901 return i;
902 }
903 }
904 }
905 return -1;
906 }
907
Craig Mautnera5eed0b2013-03-16 12:41:54 -0700908 private int addAppWindowToListLocked(final WindowState win) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800909 final IWindow client = win.mClient;
910 final WindowToken token = win.mToken;
Craig Mautnerdf88d732014-01-27 09:21:32 -0800911 final DisplayContent displayContent = win.getDisplayContent();
Romain Guy06882f82009-06-10 13:36:04 -0700912
Craig Mautner59c00972012-07-30 12:10:24 -0700913 final WindowList windows = win.getWindowList();
914 final int N = windows.size();
Craig Mautner69b08182012-09-05 13:07:13 -0700915 WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent);
Craig Mautnera5eed0b2013-03-16 12:41:54 -0700916 int tokenWindowsPos = 0;
917 int windowListPos = tokenWindowList.size();
918 if (!tokenWindowList.isEmpty()) {
919 // If this application has existing windows, we
920 // simply place the new window on top of them... but
921 // keep the starting window on top.
922 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
923 // Base windows go behind everything else.
924 WindowState lowestWindow = tokenWindowList.get(0);
925 placeWindowBefore(lowestWindow, win);
926 tokenWindowsPos = indexOfWinInWindowList(lowestWindow, token.windows);
927 } else {
928 AppWindowToken atoken = win.mAppToken;
929 WindowState lastWindow = tokenWindowList.get(windowListPos - 1);
930 if (atoken != null && lastWindow == atoken.startingWindow) {
931 placeWindowBefore(lastWindow, win);
932 tokenWindowsPos = indexOfWinInWindowList(lastWindow, token.windows);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 } else {
Craig Mautnera5eed0b2013-03-16 12:41:54 -0700934 int newIdx = findIdxBasedOnAppTokens(win);
935 //there is a window above this one associated with the same
936 //apptoken note that the window could be a floating window
937 //that was created later or a window at the top of the list of
938 //windows associated with this token.
Craig Mautner58458122013-09-14 14:59:50 -0700939 if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
Craig Mautnerb1885b852013-09-16 22:50:50 -0700940 "not Base app: Adding window " + win + " at " + (newIdx + 1) + " of " +
941 N);
Craig Mautnera5eed0b2013-03-16 12:41:54 -0700942 windows.add(newIdx + 1, win);
943 if (newIdx < 0) {
944 // No window from token found on win's display.
945 tokenWindowsPos = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800946 } else {
Craig Mautnera5eed0b2013-03-16 12:41:54 -0700947 tokenWindowsPos = indexOfWinInWindowList(
948 windows.get(newIdx), token.windows) + 1;
949 }
950 mWindowsChanged = true;
951 }
952 }
953 return tokenWindowsPos;
954 }
955
956 // No windows from this token on this display
957 if (localLOGV) Slog.v(TAG, "Figuring out where to add app window " + client.asBinder()
958 + " (token=" + token + ")");
959 // Figure out where the window should go, based on the
960 // order of applications.
961 WindowState pos = null;
962
Craig Mautner018be3d2013-08-27 13:25:17 -0700963 final ArrayList<Task> tasks = displayContent.getTasks();
Craig Mautnera5eed0b2013-03-16 12:41:54 -0700964 int taskNdx;
965 int tokenNdx = -1;
966 for (taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
967 AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
968 for (tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
969 final AppWindowToken t = tokens.get(tokenNdx);
970 if (t == token) {
971 --tokenNdx;
972 if (tokenNdx < 0) {
973 --taskNdx;
974 if (taskNdx >= 0) {
975 tokenNdx = tasks.get(taskNdx).mAppTokens.size() - 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800976 }
977 }
Craig Mautnera5eed0b2013-03-16 12:41:54 -0700978 break;
979 }
980
981 // We haven't reached the token yet; if this token
982 // is not going to the bottom and has windows on this display, we can
983 // use it as an anchor for when we do reach the token.
984 tokenWindowList = getTokenWindowsOnDisplay(t, displayContent);
985 if (!t.sendingToBottom && tokenWindowList.size() > 0) {
986 pos = tokenWindowList.get(0);
987 }
988 }
989 if (tokenNdx >= 0) {
990 // early exit
991 break;
992 }
993 }
994
995 // We now know the index into the apps. If we found
996 // an app window above, that gives us the position; else
997 // we need to look some more.
998 if (pos != null) {
999 // Move behind any windows attached to this one.
1000 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
1001 if (atoken != null) {
1002 tokenWindowList =
1003 getTokenWindowsOnDisplay(atoken, displayContent);
1004 final int NC = tokenWindowList.size();
1005 if (NC > 0) {
1006 WindowState bottom = tokenWindowList.get(0);
1007 if (bottom.mSubLayer < 0) {
1008 pos = bottom;
1009 }
1010 }
1011 }
1012 placeWindowBefore(pos, win);
1013 return tokenWindowsPos;
1014 }
1015
1016 // Continue looking down until we find the first
1017 // token that has windows on this display.
1018 for ( ; taskNdx >= 0; --taskNdx) {
1019 AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
1020 for ( ; tokenNdx >= 0; --tokenNdx) {
1021 final AppWindowToken t = tokens.get(tokenNdx);
1022 tokenWindowList = getTokenWindowsOnDisplay(t, displayContent);
1023 final int NW = tokenWindowList.size();
1024 if (NW > 0) {
1025 pos = tokenWindowList.get(NW-1);
1026 break;
1027 }
1028 }
1029 if (tokenNdx >= 0) {
1030 // found
1031 break;
1032 }
1033 }
1034
1035 if (pos != null) {
1036 // Move in front of any windows attached to this
1037 // one.
1038 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
1039 if (atoken != null) {
1040 final int NC = atoken.windows.size();
1041 if (NC > 0) {
1042 WindowState top = atoken.windows.get(NC-1);
1043 if (top.mSubLayer >= 0) {
1044 pos = top;
1045 }
1046 }
1047 }
1048 placeWindowAfter(pos, win);
1049 return tokenWindowsPos;
1050 }
1051
1052 // Just search for the start of this layer.
1053 final int myLayer = win.mBaseLayer;
1054 int i;
1055 for (i = 0; i < N; i++) {
1056 WindowState w = windows.get(i);
1057 if (w.mBaseLayer > myLayer) {
1058 break;
1059 }
1060 }
Craig Mautner58458122013-09-14 14:59:50 -07001061 if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
Craig Mautnerb1885b852013-09-16 22:50:50 -07001062 "Based on layer: Adding window " + win + " at " + i + " of " + N);
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001063 windows.add(i, win);
1064 mWindowsChanged = true;
1065 return tokenWindowsPos;
1066 }
1067
1068 private void addFreeWindowToListLocked(final WindowState win) {
1069 final WindowList windows = win.getWindowList();
1070
1071 // Figure out where window should go, based on layer.
1072 final int myLayer = win.mBaseLayer;
1073 int i;
1074 for (i = windows.size() - 1; i >= 0; i--) {
1075 if (windows.get(i).mBaseLayer <= myLayer) {
1076 break;
1077 }
1078 }
1079 i++;
Craig Mautner58458122013-09-14 14:59:50 -07001080 if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
Craig Mautnerb1885b852013-09-16 22:50:50 -07001081 "Free window: Adding window " + win + " at " + i + " of " + windows.size());
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001082 windows.add(i, win);
1083 mWindowsChanged = true;
1084 }
1085
1086 private void addAttachedWindowToListLocked(final WindowState win, boolean addToToken) {
1087 final WindowToken token = win.mToken;
Craig Mautnerdf88d732014-01-27 09:21:32 -08001088 final DisplayContent displayContent = win.getDisplayContent();
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001089 final WindowState attached = win.mAttachedWindow;
1090
1091 WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent);
1092
1093 // Figure out this window's ordering relative to the window
1094 // it is attached to.
1095 final int NA = tokenWindowList.size();
1096 final int sublayer = win.mSubLayer;
1097 int largestSublayer = Integer.MIN_VALUE;
1098 WindowState windowWithLargestSublayer = null;
1099 int i;
1100 for (i = 0; i < NA; i++) {
1101 WindowState w = tokenWindowList.get(i);
1102 final int wSublayer = w.mSubLayer;
1103 if (wSublayer >= largestSublayer) {
1104 largestSublayer = wSublayer;
1105 windowWithLargestSublayer = w;
1106 }
1107 if (sublayer < 0) {
1108 // For negative sublayers, we go below all windows
1109 // in the same sublayer.
1110 if (wSublayer >= sublayer) {
1111 if (addToToken) {
1112 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
1113 token.windows.add(i, win);
1114 }
1115 placeWindowBefore(wSublayer >= 0 ? attached : w, win);
1116 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001117 }
1118 } else {
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001119 // For positive sublayers, we go above all windows
1120 // in the same sublayer.
1121 if (wSublayer > sublayer) {
1122 if (addToToken) {
1123 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
1124 token.windows.add(i, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001125 }
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001126 placeWindowBefore(w, win);
1127 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001128 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001129 }
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001130 }
1131 if (i >= NA) {
1132 if (addToToken) {
1133 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
1134 token.windows.add(win);
1135 }
1136 if (sublayer < 0) {
1137 placeWindowBefore(attached, win);
1138 } else {
1139 placeWindowAfter(largestSublayer >= 0
1140 ? windowWithLargestSublayer
1141 : attached,
1142 win);
1143 }
1144 }
1145 }
Craig Mautner59c00972012-07-30 12:10:24 -07001146
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001147 private void addWindowToListInOrderLocked(final WindowState win, boolean addToToken) {
Craig Mautnerb1885b852013-09-16 22:50:50 -07001148 if (DEBUG_FOCUS_LIGHT) Slog.d(TAG, "addWindowToListInOrderLocked: win=" + win +
1149 " Callers=" + Debug.getCallers(4));
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001150 if (win.mAttachedWindow == null) {
1151 final WindowToken token = win.mToken;
1152 int tokenWindowsPos = 0;
1153 if (token.appWindowToken != null) {
1154 tokenWindowsPos = addAppWindowToListLocked(win);
1155 } else {
1156 addFreeWindowToListLocked(win);
1157 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001158 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001159 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001160 token.windows.add(tokenWindowsPos, win);
1161 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001162 } else {
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001163 addAttachedWindowToListLocked(win, addToToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001164 }
Romain Guy06882f82009-06-10 13:36:04 -07001165
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001166 if (win.mAppToken != null && addToToken) {
1167 win.mAppToken.allAppWindows.add(win);
1168 }
1169 }
Romain Guy06882f82009-06-10 13:36:04 -07001170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001171 static boolean canBeImeTarget(WindowState w) {
1172 final int fl = w.mAttrs.flags
1173 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
Dianne Hackborne75d8722011-01-27 19:37:40 -08001174 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)
Craig Mautner65d11b32012-10-01 13:59:52 -07001175 || w.mAttrs.type == TYPE_APPLICATION_STARTING) {
Dianne Hackborne75d8722011-01-27 19:37:40 -08001176 if (DEBUG_INPUT_METHOD) {
1177 Slog.i(TAG, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
1178 if (!w.isVisibleOrAdding()) {
Mathias Agopian29479eb2013-02-14 14:36:04 -08001179 Slog.i(TAG, " mSurface=" + w.mWinAnimator.mSurfaceControl
Dianne Hackborne75d8722011-01-27 19:37:40 -08001180 + " relayoutCalled=" + w.mRelayoutCalled + " viewVis=" + w.mViewVisibility
Dianne Hackbornac920872012-05-22 11:49:49 -07001181 + " policyVis=" + w.mPolicyVisibility
1182 + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim
1183 + " attachHid=" + w.mAttachedHidden
Dianne Hackborne75d8722011-01-27 19:37:40 -08001184 + " exiting=" + w.mExiting + " destroying=" + w.mDestroying);
1185 if (w.mAppToken != null) {
1186 Slog.i(TAG, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
1187 }
1188 }
1189 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001190 return w.isVisibleOrAdding();
1191 }
1192 return false;
1193 }
Romain Guy06882f82009-06-10 13:36:04 -07001194
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001195 /**
1196 * Dig through the WindowStates and find the one that the Input Method will target.
1197 * @param willMove
1198 * @return The index+1 in mWindows of the discovered target.
1199 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001200 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001201 // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
1202 // same display. Or even when the current IME/target are not on the same screen as the next
1203 // IME/target. For now only look for input windows on the main screen.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001204 WindowList windows = getDefaultWindowListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001205 WindowState w = null;
Craig Mautner22b9a5e2013-09-17 14:50:56 -07001206 int i;
1207 for (i = windows.size() - 1; i >= 0; --i) {
1208 WindowState win = windows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -07001209
Dianne Hackborne75d8722011-01-27 19:37:40 -08001210 if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG, "Checking window @" + i
Craig Mautner22b9a5e2013-09-17 14:50:56 -07001211 + " " + win + " fl=0x" + Integer.toHexString(win.mAttrs.flags));
1212 if (canBeImeTarget(win)) {
1213 w = win;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001214 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -07001215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001216 // Yet more tricksyness! If this window is a "starting"
1217 // window, we do actually want to be on top of it, but
1218 // it is not -really- where input will go. So if the caller
1219 // is not actually looking to move the IME, look down below
1220 // for a real window to target...
1221 if (!willMove
Craig Mautner65d11b32012-10-01 13:59:52 -07001222 && w.mAttrs.type == TYPE_APPLICATION_STARTING
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001223 && i > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001224 WindowState wb = windows.get(i-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001225 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1226 i--;
1227 w = wb;
1228 }
1229 }
1230 break;
1231 }
1232 }
Romain Guy06882f82009-06-10 13:36:04 -07001233
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001234 // Now w is either mWindows[0] or an IME (or null if mWindows is empty).
1235
Dianne Hackborne75d8722011-01-27 19:37:40 -08001236 if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG, "Proposed new IME target: " + w);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001237
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001238 // Now, a special case -- if the last target's window is in the
1239 // process of exiting, and is above the new target, keep on the
1240 // last target to avoid flicker. Consider for example a Dialog with
1241 // the IME shown: when the Dialog is dismissed, we want to keep
1242 // the IME above it until it is completely gone so it doesn't drop
1243 // behind the dialog or its full-screen scrim.
Craig Mautner59c00972012-07-30 12:10:24 -07001244 final WindowState curTarget = mInputMethodTarget;
Craig Mautnerae879622013-10-03 14:07:45 -07001245 if (curTarget != null
Craig Mautner59c00972012-07-30 12:10:24 -07001246 && curTarget.isDisplayedLw()
Craig Mautnera987d432012-10-11 14:07:58 -07001247 && curTarget.isClosing()
Craig Mautnerae879622013-10-03 14:07:45 -07001248 && (w == null || curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) {
Craig Mautnere6f7d5052012-10-08 10:34:17 -07001249 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Current target higher, not changing");
1250 return windows.indexOf(curTarget) + 1;
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001251 }
Romain Guy06882f82009-06-10 13:36:04 -07001252
Joe Onorato8a9b2202010-02-26 18:56:32 -08001253 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001254 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -07001255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001256 if (willMove && w != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07001257 AppWindowToken token = curTarget == null ? null : curTarget.mAppToken;
1258 if (token != null) {
Romain Guy06882f82009-06-10 13:36:04 -07001259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001260 // Now some fun for dealing with window animations that
1261 // modify the Z order. We need to look at all windows below
1262 // the current target that are in this app, finding the highest
1263 // visible one in layering.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001264 WindowState highestTarget = null;
1265 int highestPos = 0;
Craig Mautner59431632012-04-04 11:56:44 -07001266 if (token.mAppAnimator.animating || token.mAppAnimator.animation != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07001267 WindowList curWindows = curTarget.getWindowList();
1268 int pos = curWindows.indexOf(curTarget);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001269 while (pos >= 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001270 WindowState win = curWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001271 if (win.mAppToken != token) {
1272 break;
1273 }
1274 if (!win.mRemoved) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001275 if (highestTarget == null || win.mWinAnimator.mAnimLayer >
1276 highestTarget.mWinAnimator.mAnimLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001277 highestTarget = win;
1278 highestPos = pos;
1279 }
1280 }
1281 pos--;
1282 }
1283 }
Romain Guy06882f82009-06-10 13:36:04 -07001284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001285 if (highestTarget != null) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08001286 if (DEBUG_INPUT_METHOD) Slog.v(TAG, mAppTransition + " " + highestTarget
Craig Mautnera2c77052012-03-26 12:14:43 -07001287 + " animating=" + highestTarget.mWinAnimator.isAnimating()
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001288 + " layer=" + highestTarget.mWinAnimator.mAnimLayer
1289 + " new layer=" + w.mWinAnimator.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001290
Craig Mautner164d4bb2012-11-26 13:51:23 -08001291 if (mAppTransition.isTransitionSet()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001292 // If we are currently setting up for an animation,
1293 // hold everything until we can find out what will happen.
1294 mInputMethodTargetWaitingAnim = true;
1295 mInputMethodTarget = highestTarget;
1296 return highestPos + 1;
Craig Mautnera2c77052012-03-26 12:14:43 -07001297 } else if (highestTarget.mWinAnimator.isAnimating() &&
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001298 highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001299 // If the window we are currently targeting is involved
1300 // with an animation, and it is on top of the next target
1301 // we will be over, then hold off on moving until
1302 // that is done.
Dianne Hackborne75d8722011-01-27 19:37:40 -08001303 mInputMethodTargetWaitingAnim = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001304 mInputMethodTarget = highestTarget;
1305 return highestPos + 1;
1306 }
1307 }
1308 }
1309 }
Romain Guy06882f82009-06-10 13:36:04 -07001310
Joe Onorato8a9b2202010-02-26 18:56:32 -08001311 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001312 if (w != null) {
1313 if (willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001314 if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to "
1315 + w + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001316 mInputMethodTarget = w;
Dianne Hackborne75d8722011-01-27 19:37:40 -08001317 mInputMethodTargetWaitingAnim = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001318 if (w.mAppToken != null) {
Craig Mautner59431632012-04-04 11:56:44 -07001319 setInputMethodAnimLayerAdjustment(w.mAppToken.mAppAnimator.animLayerAdjustment);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001320 } else {
1321 setInputMethodAnimLayerAdjustment(0);
1322 }
1323 }
1324 return i+1;
1325 }
1326 if (willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001327 if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to null."
1328 + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001329 mInputMethodTarget = null;
1330 setInputMethodAnimLayerAdjustment(0);
1331 }
1332 return -1;
1333 }
Romain Guy06882f82009-06-10 13:36:04 -07001334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001335 void addInputMethodWindowToListLocked(WindowState win) {
1336 int pos = findDesiredInputMethodWindowIndexLocked(true);
1337 if (pos >= 0) {
1338 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001339 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001340 TAG, "Adding input method window " + win + " at " + pos);
Craig Mautner59c00972012-07-30 12:10:24 -07001341 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001342 getDefaultWindowListLocked().add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001343 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001344 moveInputMethodDialogsLocked(pos+1);
1345 return;
1346 }
1347 win.mTargetAppToken = null;
1348 addWindowToListInOrderLocked(win, true);
1349 moveInputMethodDialogsLocked(pos);
1350 }
Romain Guy06882f82009-06-10 13:36:04 -07001351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001352 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001353 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001354 mInputMethodAnimLayerAdjustment = adj;
1355 WindowState imw = mInputMethodWindow;
1356 if (imw != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001357 imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001358 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001359 + " anim layer: " + imw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001360 int wi = imw.mChildWindows.size();
1361 while (wi > 0) {
1362 wi--;
Jeff Browne33348b2010-07-15 23:54:05 -07001363 WindowState cw = imw.mChildWindows.get(wi);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001364 cw.mWinAnimator.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001365 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001366 + " anim layer: " + cw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001367 }
1368 }
1369 int di = mInputMethodDialogs.size();
1370 while (di > 0) {
1371 di --;
1372 imw = mInputMethodDialogs.get(di);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001373 imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001374 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001375 + " anim layer: " + imw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001376 }
1377 }
Romain Guy06882f82009-06-10 13:36:04 -07001378
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001379 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -07001380 WindowList windows = win.getWindowList();
1381 int wpos = windows.indexOf(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001382 if (wpos >= 0) {
1383 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001384 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
Craig Mautner59c00972012-07-30 12:10:24 -07001385 windows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001386 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001387 int NC = win.mChildWindows.size();
1388 while (NC > 0) {
1389 NC--;
Jeff Browne33348b2010-07-15 23:54:05 -07001390 WindowState cw = win.mChildWindows.get(NC);
Craig Mautner59c00972012-07-30 12:10:24 -07001391 int cpos = windows.indexOf(cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001392 if (cpos >= 0) {
1393 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001394 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001395 + cpos + ": " + cw);
Craig Mautner59c00972012-07-30 12:10:24 -07001396 windows.remove(cpos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001397 }
1398 }
1399 }
1400 return interestingPos;
1401 }
Romain Guy06882f82009-06-10 13:36:04 -07001402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001403 private void reAddWindowToListInOrderLocked(WindowState win) {
1404 addWindowToListInOrderLocked(win, false);
1405 // This is a hack to get all of the child windows added as well
1406 // at the right position. Child windows should be rare and
1407 // this case should be rare, so it shouldn't be that big a deal.
Craig Mautner59c00972012-07-30 12:10:24 -07001408 WindowList windows = win.getWindowList();
1409 int wpos = windows.indexOf(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001410 if (wpos >= 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001411 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos + ": " + win);
1412 windows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001413 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001414 reAddWindowLocked(wpos, win);
1415 }
1416 }
Romain Guy06882f82009-06-10 13:36:04 -07001417
Craig Mautner59c00972012-07-30 12:10:24 -07001418 void logWindowList(final WindowList windows, String prefix) {
1419 int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001420 while (N > 0) {
1421 N--;
Craig Mautner59c00972012-07-30 12:10:24 -07001422 Slog.v(TAG, prefix + "#" + N + ": " + windows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001423 }
1424 }
Romain Guy06882f82009-06-10 13:36:04 -07001425
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001426 void moveInputMethodDialogsLocked(int pos) {
1427 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001428
Craig Mautner59c00972012-07-30 12:10:24 -07001429 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001430 WindowList windows = getDefaultWindowListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001431 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001432 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001433 for (int i=0; i<N; i++) {
1434 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1435 }
1436 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001437 Slog.v(TAG, "Window list w/pos=" + pos);
Craig Mautner59c00972012-07-30 12:10:24 -07001438 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001439 }
Romain Guy06882f82009-06-10 13:36:04 -07001440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001441 if (pos >= 0) {
1442 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
Craig Mautner59c00972012-07-30 12:10:24 -07001443 if (pos < windows.size()) {
1444 WindowState wp = windows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001445 if (wp == mInputMethodWindow) {
1446 pos++;
1447 }
1448 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001449 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001450 for (int i=0; i<N; i++) {
1451 WindowState win = dialogs.get(i);
1452 win.mTargetAppToken = targetAppToken;
1453 pos = reAddWindowLocked(pos, win);
1454 }
1455 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001456 Slog.v(TAG, "Final window list:");
Craig Mautner59c00972012-07-30 12:10:24 -07001457 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001458 }
1459 return;
1460 }
1461 for (int i=0; i<N; i++) {
1462 WindowState win = dialogs.get(i);
1463 win.mTargetAppToken = null;
1464 reAddWindowToListInOrderLocked(win);
1465 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001466 Slog.v(TAG, "No IM target, final list:");
Craig Mautner59c00972012-07-30 12:10:24 -07001467 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001468 }
1469 }
1470 }
Romain Guy06882f82009-06-10 13:36:04 -07001471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001472 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1473 final WindowState imWin = mInputMethodWindow;
1474 final int DN = mInputMethodDialogs.size();
1475 if (imWin == null && DN == 0) {
1476 return false;
1477 }
Romain Guy06882f82009-06-10 13:36:04 -07001478
Craig Mautner59c00972012-07-30 12:10:24 -07001479 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001480 WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07001481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001482 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1483 if (imPos >= 0) {
1484 // In this case, the input method windows are to be placed
1485 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001486
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487 // First check to see if the input method windows are already
1488 // located here, and contiguous.
Craig Mautner59c00972012-07-30 12:10:24 -07001489 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001490 WindowState firstImWin = imPos < N
Craig Mautner59c00972012-07-30 12:10:24 -07001491 ? windows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001493 // Figure out the actual input method window that should be
1494 // at the bottom of their stack.
1495 WindowState baseImWin = imWin != null
1496 ? imWin : mInputMethodDialogs.get(0);
1497 if (baseImWin.mChildWindows.size() > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001498 WindowState cw = baseImWin.mChildWindows.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001499 if (cw.mSubLayer < 0) baseImWin = cw;
1500 }
Romain Guy06882f82009-06-10 13:36:04 -07001501
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001502 if (firstImWin == baseImWin) {
1503 // The windows haven't moved... but are they still contiguous?
1504 // First find the top IM window.
1505 int pos = imPos+1;
1506 while (pos < N) {
Craig Mautner59c00972012-07-30 12:10:24 -07001507 if (!(windows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001508 break;
1509 }
1510 pos++;
1511 }
1512 pos++;
1513 // Now there should be no more input method windows above.
1514 while (pos < N) {
Craig Mautner59c00972012-07-30 12:10:24 -07001515 if ((windows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001516 break;
1517 }
1518 pos++;
1519 }
1520 if (pos >= N) {
Carrie Xu5c971842012-10-30 17:28:39 +08001521 // Z order is good.
1522 // The IM target window may be changed, so update the mTargetAppToken.
1523 if (imWin != null) {
1524 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1525 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001526 return false;
1527 }
1528 }
Romain Guy06882f82009-06-10 13:36:04 -07001529
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001530 if (imWin != null) {
1531 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001532 Slog.v(TAG, "Moving IM from " + imPos);
Craig Mautner59c00972012-07-30 12:10:24 -07001533 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001534 }
1535 imPos = tmpRemoveWindowLocked(imPos, imWin);
1536 if (DEBUG_INPUT_METHOD) {
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001537 Slog.v(TAG, "List after removing with new pos " + imPos + ":");
Craig Mautner59c00972012-07-30 12:10:24 -07001538 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001539 }
1540 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1541 reAddWindowLocked(imPos, imWin);
1542 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001543 Slog.v(TAG, "List after moving IM to " + imPos + ":");
Craig Mautner59c00972012-07-30 12:10:24 -07001544 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001545 }
1546 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1547 } else {
1548 moveInputMethodDialogsLocked(imPos);
1549 }
Romain Guy06882f82009-06-10 13:36:04 -07001550
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001551 } else {
1552 // In this case, the input method windows go in a fixed layer,
1553 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001555 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001556 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001557 tmpRemoveWindowLocked(0, imWin);
1558 imWin.mTargetAppToken = null;
1559 reAddWindowToListInOrderLocked(imWin);
1560 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001561 Slog.v(TAG, "List with no IM target:");
Craig Mautner59c00972012-07-30 12:10:24 -07001562 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 }
Craig Mautner01cd0e72012-06-18 10:19:11 -07001564 if (DN > 0) moveInputMethodDialogsLocked(-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001565 } else {
Craig Mautner01cd0e72012-06-18 10:19:11 -07001566 moveInputMethodDialogsLocked(-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001567 }
Romain Guy06882f82009-06-10 13:36:04 -07001568
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001569 }
Romain Guy06882f82009-06-10 13:36:04 -07001570
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001571 if (needAssignLayers) {
Craig Mautner59c00972012-07-30 12:10:24 -07001572 assignLayersLocked(windows);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001573 }
Romain Guy06882f82009-06-10 13:36:04 -07001574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001575 return true;
1576 }
Romain Guy06882f82009-06-10 13:36:04 -07001577
Dianne Hackborn25994b42009-09-04 14:21:19 -07001578 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Craig Mautnerad3a9bb2012-03-09 11:31:06 -08001579 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001580 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1581 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
Craig Mautner59431632012-04-04 11:56:44 -07001582 ? wallpaperTarget.mAppToken.mAppAnimator.animation : null)
Dianne Hackborn25994b42009-09-04 14:21:19 -07001583 + " upper=" + mUpperWallpaperTarget
1584 + " lower=" + mLowerWallpaperTarget);
1585 return (wallpaperTarget != null
1586 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
Craig Mautner59431632012-04-04 11:56:44 -07001587 && wallpaperTarget.mAppToken.mAppAnimator.animation != null)))
Dianne Hackborn25994b42009-09-04 14:21:19 -07001588 || mUpperWallpaperTarget != null
1589 || mLowerWallpaperTarget != null;
1590 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001591
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001592 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1593 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001594
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001595 int adjustWallpaperWindowsLocked() {
Craig Mautnera608b882012-03-30 13:03:49 -07001596 mInnerFields.mWallpaperMayChange = false;
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001597 boolean targetChanged = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001598
Craig Mautner59c00972012-07-30 12:10:24 -07001599 // TODO(multidisplay): Wallpapers on main screen only.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001600 final DisplayInfo displayInfo = getDefaultDisplayContentLocked().getDisplayInfo();
John Spurlockef4adae2013-08-26 17:58:58 -04001601 final int dw = displayInfo.logicalWidth;
1602 final int dh = displayInfo.logicalHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001603
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001604 // First find top-most window that has asked to be on top of the
1605 // wallpaper; all wallpapers go behind it.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001606 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07001607 int N = windows.size();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001608 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001609 WindowState foundW = null;
1610 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001611 WindowState topCurW = null;
1612 int topCurI = 0;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001613 int windowDetachedI = -1;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001614 int i = N;
1615 while (i > 0) {
1616 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07001617 w = windows.get(i);
Craig Mautner65d11b32012-10-01 13:59:52 -07001618 if ((w.mAttrs.type == TYPE_WALLPAPER)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001619 if (topCurW == null) {
1620 topCurW = w;
1621 topCurI = i;
1622 }
1623 continue;
1624 }
1625 topCurW = null;
Craig Mautner96868332012-12-04 14:29:11 -08001626 if (w != mAnimator.mWindowDetachedWallpaper && w.mAppToken != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001627 // If this window's app token is hidden and not animating,
1628 // it is of no interest to us.
Craig Mautner59431632012-04-04 11:56:44 -07001629 if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001630 if (DEBUG_WALLPAPER) Slog.v(TAG,
Craig Mautner1d961d42012-05-27 12:02:11 -07001631 "Skipping hidden and not animating token: " + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001632 continue;
1633 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001634 }
Craig Mautnerae446592012-12-06 19:05:05 -08001635 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win #" + i + " " + w + ": isOnScreen="
1636 + w.isOnScreen() + " mDrawState=" + w.mWinAnimator.mDrawState);
1637 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isOnScreen()
1638 && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001639 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001640 "Found wallpaper target: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001641 foundW = w;
1642 foundI = i;
Craig Mautner4d7349b2012-04-20 14:52:47 -07001643 if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001644 // The current wallpaper target is animating, so we'll
1645 // look behind it for another possible target and figure
1646 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001647 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001648 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001649 continue;
1650 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001651 break;
Craig Mautner96868332012-12-04 14:29:11 -08001652 } else if (w == mAnimator.mWindowDetachedWallpaper) {
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001653 windowDetachedI = i;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001654 }
1655 }
1656
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001657 if (foundW == null && windowDetachedI >= 0) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001658 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001659 "Found animating detached wallpaper activity: #" + i + "=" + w);
1660 foundW = w;
1661 foundI = windowDetachedI;
1662 }
1663
Craig Mautner8863cca2012-09-18 15:04:34 -07001664 if (mWallpaperTarget != foundW
1665 && (mLowerWallpaperTarget == null || mLowerWallpaperTarget != foundW)) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001666 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001667 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001668 + " oldTarget: " + mWallpaperTarget);
1669 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001670
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001671 mLowerWallpaperTarget = null;
1672 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001673
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001674 WindowState oldW = mWallpaperTarget;
1675 mWallpaperTarget = foundW;
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001676 targetChanged = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001677
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001678 // Now what is happening... if the current and new targets are
1679 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001680 if (foundW != null && oldW != null) {
Craig Mautnerae446592012-12-06 19:05:05 -08001681 boolean oldAnim = oldW.isAnimatingLw();
1682 boolean foundAnim = foundW.isAnimatingLw();
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001683 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001684 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001685 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001686 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001687 if (foundAnim && oldAnim) {
Craig Mautner59c00972012-07-30 12:10:24 -07001688 int oldI = windows.indexOf(oldW);
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001689 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001690 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001691 }
1692 if (oldI >= 0) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001693 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001694 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001695 + "=" + oldW + "; new#" + foundI
1696 + "=" + foundW);
1697 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001698
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001699 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001700 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001701 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001702 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001703 }
1704 mWallpaperTarget = oldW;
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001705 foundW = oldW;
1706 foundI = oldI;
Craig Mautner711f90a2012-07-03 18:43:52 -07001707 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001708 // Now set the upper and lower wallpaper targets
1709 // correctly, and make sure that we are positioning
1710 // the wallpaper below the lower.
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001711 else if (foundI > oldI) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001712 // The new target is on top of the old one.
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001713 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001714 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001715 }
1716 mUpperWallpaperTarget = foundW;
1717 mLowerWallpaperTarget = oldW;
1718 foundW = oldW;
1719 foundI = oldI;
1720 } else {
1721 // The new target is below the old one.
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001722 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001723 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001724 }
1725 mUpperWallpaperTarget = oldW;
1726 mLowerWallpaperTarget = foundW;
1727 }
1728 }
1729 }
1730 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001731
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001732 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001733 // Is it time to stop animating?
Craig Mautnerae446592012-12-06 19:05:05 -08001734 if (!mLowerWallpaperTarget.isAnimatingLw() || !mUpperWallpaperTarget.isAnimatingLw()) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001735 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001736 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001737 }
1738 mLowerWallpaperTarget = null;
1739 mUpperWallpaperTarget = null;
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001740 mWallpaperTarget = foundW;
1741 targetChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001742 }
1743 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001744
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001745 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001746 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001747 // The window is visible to the compositor... but is it visible
1748 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001749 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001750 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001751
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001752 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001753 // its layer adjustment. Only do this if we are not transfering
1754 // between two wallpaper targets.
1755 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001756 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Craig Mautner59431632012-04-04 11:56:44 -07001757 ? foundW.mAppToken.mAppAnimator.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001758
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001759 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1760 * TYPE_LAYER_MULTIPLIER
1761 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001762
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001763 // Now w is the window we are supposed to be behind... but we
1764 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001765 // AND any starting window associated with it, AND below the
1766 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001767 while (foundI > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001768 WindowState wb = windows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001769 if (wb.mBaseLayer < maxLayer &&
1770 wb.mAttachedWindow != foundW &&
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001771 (foundW.mAttachedWindow == null ||
1772 wb.mAttachedWindow != foundW.mAttachedWindow) &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001773 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001774 foundW.mToken == null || wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001775 // This window is not related to the previous one in any
1776 // interesting way, so stop here.
1777 break;
1778 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001779 foundW = wb;
1780 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001781 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001782 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001783 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001784 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001785
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001786 if (foundW == null && topCurW != null) {
1787 // There is no wallpaper target, so it goes at the bottom.
1788 // We will assume it is the same place as last time, if known.
1789 foundW = topCurW;
1790 foundI = topCurI+1;
1791 } else {
1792 // Okay i is the position immediately above the wallpaper. Look at
1793 // what is below it for later.
Craig Mautner59c00972012-07-30 12:10:24 -07001794 foundW = foundI > 0 ? windows.get(foundI-1) : null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001795 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001796
Dianne Hackborn284ac932009-08-28 10:34:25 -07001797 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001798 if (mWallpaperTarget.mWallpaperX >= 0) {
1799 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001800 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001801 }
1802 if (mWallpaperTarget.mWallpaperY >= 0) {
1803 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001804 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001805 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001806 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001807
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001808 // Start stepping backwards from here, ensuring that our wallpaper windows
1809 // are correctly placed.
Craig Mautnerae446592012-12-06 19:05:05 -08001810 int changed = 0;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001811 int curTokenIndex = mWallpaperTokens.size();
1812 while (curTokenIndex > 0) {
1813 curTokenIndex--;
1814 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001815 if (token.hidden == visible) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001816 if (DEBUG_WALLPAPER_LIGHT) Slog.d(TAG,
1817 "Wallpaper token " + token + " hidden=" + !visible);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001818 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1819 token.hidden = !visible;
1820 // Need to do a layout to ensure the wallpaper now has the
1821 // correct size.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001822 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001823 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001824
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001825 int curWallpaperIndex = token.windows.size();
1826 while (curWallpaperIndex > 0) {
1827 curWallpaperIndex--;
1828 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001829
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001830 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001831 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001832 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001833
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001834 // First, make sure the client has the current visibility
1835 // state.
Craig Mautner507a2ee2012-06-13 08:39:38 -07001836 dispatchWallpaperVisibility(wallpaper, visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001837
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001838 wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001839 if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "adjustWallpaper win "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001840 + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001841
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001842 // First, if this window is at the current index, then all
1843 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001844 if (wallpaper == foundW) {
1845 foundI--;
1846 foundW = foundI > 0
Craig Mautner59c00972012-07-30 12:10:24 -07001847 ? windows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001848 continue;
1849 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001850
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001851 // The window didn't match... the current wallpaper window,
1852 // wherever it is, is in the wrong place, so make sure it is
1853 // not in the list.
Craig Mautner59c00972012-07-30 12:10:24 -07001854 int oldIndex = windows.indexOf(wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001855 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001856 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001857 + oldIndex + ": " + wallpaper);
Craig Mautner59c00972012-07-30 12:10:24 -07001858 windows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001859 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001860 if (oldIndex < foundI) {
1861 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001862 }
1863 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001864
Craig Mautner58004432013-10-14 12:58:42 -07001865 // Now stick it in. For apps over wallpaper keep the wallpaper at the bottommost
1866 // layer. For keyguard over wallpaper put the wallpaper under the keyguard.
1867 int insertionIndex = 0;
1868 if (visible && foundW != null) {
1869 final int type = foundW.mAttrs.type;
1870 if (type == TYPE_KEYGUARD || type == TYPE_KEYGUARD_SCRIM) {
1871 insertionIndex = windows.indexOf(foundW);
1872 }
1873 }
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001874 if (DEBUG_WALLPAPER_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001875 Slog.v(TAG, "Moving wallpaper " + wallpaper
Craig Mautner58004432013-10-14 12:58:42 -07001876 + " from " + oldIndex + " to " + insertionIndex);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001877 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001878
Craig Mautner58004432013-10-14 12:58:42 -07001879 windows.add(insertionIndex, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001880 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001881 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001882 }
1883 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001884
Craig Mautner5457e612013-05-10 16:25:02 -07001885 /*
Craig Mautner05d29032013-05-03 13:40:13 -07001886 final TaskStack targetStack =
1887 mWallpaperTarget == null ? null : mWallpaperTarget.getStack();
1888 if ((changed & ADJUST_WALLPAPER_LAYERS_CHANGED) != 0 &&
1889 targetStack != null && !targetStack.isHomeStack()) {
1890 // If the wallpaper target is not on the home stack then make sure that all windows
1891 // from other non-home stacks are above the wallpaper.
1892 for (i = foundI - 1; i >= 0; --i) {
1893 WindowState win = windows.get(i);
1894 if (!win.isVisibleLw()) {
1895 continue;
1896 }
1897 final TaskStack winStack = win.getStack();
1898 if (winStack != null && !winStack.isHomeStack() && winStack != targetStack) {
1899 windows.remove(i);
1900 windows.add(foundI + 1, win);
1901 }
1902 }
1903 }
Craig Mautner5457e612013-05-10 16:25:02 -07001904 */
Craig Mautner05d29032013-05-03 13:40:13 -07001905
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001906 if (targetChanged && DEBUG_WALLPAPER_LIGHT) {
1907 Slog.d(TAG, "New wallpaper: target=" + mWallpaperTarget
1908 + " lower=" + mLowerWallpaperTarget + " upper="
1909 + mUpperWallpaperTarget);
1910 }
1911
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001912 return changed;
1913 }
1914
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001915 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001916 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001917 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001918 mWallpaperAnimLayerAdjustment = adj;
1919 int curTokenIndex = mWallpaperTokens.size();
1920 while (curTokenIndex > 0) {
1921 curTokenIndex--;
1922 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1923 int curWallpaperIndex = token.windows.size();
1924 while (curWallpaperIndex > 0) {
1925 curWallpaperIndex--;
1926 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001927 wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + adj;
Craig Mautneref25d7a2012-05-15 23:01:47 -07001928 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "setWallpaper win "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001929 + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001930 }
1931 }
1932 }
1933
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001934 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
1935 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001936 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001937 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001938 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001939 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackbornffb3d932011-05-17 17:44:51 -07001940 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001941 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
1942 changed = wallpaperWin.mXOffset != offset;
1943 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001944 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001945 + wallpaperWin + " x: " + offset);
1946 wallpaperWin.mXOffset = offset;
1947 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001948 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001949 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001950 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001951 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001952 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001953
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001954 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001955 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001956 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1957 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1958 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001959 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001960 + wallpaperWin + " y: " + offset);
1961 changed = true;
1962 wallpaperWin.mYOffset = offset;
1963 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001964 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001965 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001966 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001967 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001968 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001969
Craig Mautnerbb1449b2012-03-23 16:11:14 -07001970 if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
Chet Haasea8e5a2b2011-10-28 13:18:16 -07001971 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001972 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001973 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001974 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
1975 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001976 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001977 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001978 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001979 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001980 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
1981 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001982 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001983 if (mWaitingOnWallpaper != null) {
1984 long start = SystemClock.uptimeMillis();
1985 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
1986 < start) {
1987 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001988 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07001989 "Waiting for offset complete...");
1990 mWindowMap.wait(WALLPAPER_TIMEOUT);
1991 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001992 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001993 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07001994 if ((start+WALLPAPER_TIMEOUT)
1995 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001996 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07001997 + wallpaperWin);
1998 mLastWallpaperTimeoutTime = start;
1999 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002000 }
Dianne Hackborn75804932009-10-20 20:15:20 -07002001 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002002 }
2003 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002004 } catch (RemoteException e) {
2005 }
2006 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002007
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002008 return changed;
2009 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002010
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002011 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002012 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002013 if (mWaitingOnWallpaper != null &&
2014 mWaitingOnWallpaper.mClient.asBinder() == window) {
2015 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07002016 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002017 }
2018 }
2019 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002020
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002021 void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08002022 final DisplayContent displayContent = changingTarget.getDisplayContent();
2023 if (displayContent == null) {
2024 return;
2025 }
Craig Mautner59c00972012-07-30 12:10:24 -07002026 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
John Spurlockef4adae2013-08-26 17:58:58 -04002027 final int dw = displayInfo.logicalWidth;
2028 final int dh = displayInfo.logicalHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002029
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002030 WindowState target = mWallpaperTarget;
2031 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002032 if (target.mWallpaperX >= 0) {
2033 mLastWallpaperX = target.mWallpaperX;
2034 } else if (changingTarget.mWallpaperX >= 0) {
2035 mLastWallpaperX = changingTarget.mWallpaperX;
2036 }
2037 if (target.mWallpaperY >= 0) {
2038 mLastWallpaperY = target.mWallpaperY;
2039 } else if (changingTarget.mWallpaperY >= 0) {
2040 mLastWallpaperY = changingTarget.mWallpaperY;
2041 }
2042 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002043
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002044 int curTokenIndex = mWallpaperTokens.size();
2045 while (curTokenIndex > 0) {
2046 curTokenIndex--;
2047 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2048 int curWallpaperIndex = token.windows.size();
2049 while (curWallpaperIndex > 0) {
2050 curWallpaperIndex--;
2051 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2052 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002053 WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
2054 winAnimator.computeShownFrameLocked();
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002055 // No need to lay out the windows - we can just set the wallpaper position
2056 // directly.
Craig Mautner58106812012-12-28 12:27:40 -08002057 winAnimator.setWallpaperOffset(wallpaper.mShownFrame);
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002058 // We only want to be synchronous with one wallpaper.
2059 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002060 }
2061 }
2062 }
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002063 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002064
Craig Mautner507a2ee2012-06-13 08:39:38 -07002065 /**
2066 * Check wallpaper for visiblity change and notify window if so.
2067 * @param wallpaper The wallpaper to test and notify.
2068 * @param visible Current visibility.
2069 */
2070 void dispatchWallpaperVisibility(final WindowState wallpaper, final boolean visible) {
2071 if (wallpaper.mWallpaperVisible != visible) {
2072 wallpaper.mWallpaperVisible = visible;
2073 try {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07002074 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
2075 "Updating vis of wallpaper " + wallpaper
2076 + ": " + visible + " from:\n" + Debug.getCallers(4, " "));
Craig Mautner507a2ee2012-06-13 08:39:38 -07002077 wallpaper.mClient.dispatchAppVisibility(visible);
2078 } catch (RemoteException e) {
2079 }
2080 }
2081 }
2082
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002083 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07002084 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Craig Mautnerdf88d732014-01-27 09:21:32 -08002085 final DisplayContent displayContent = mWallpaperTarget.getDisplayContent();
2086 if (displayContent == null) {
2087 return;
2088 }
Craig Mautner59c00972012-07-30 12:10:24 -07002089 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
John Spurlockef4adae2013-08-26 17:58:58 -04002090 final int dw = displayInfo.logicalWidth;
2091 final int dh = displayInfo.logicalHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002092
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002093 int curTokenIndex = mWallpaperTokens.size();
2094 while (curTokenIndex > 0) {
2095 curTokenIndex--;
2096 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002097 if (token.hidden == visible) {
2098 token.hidden = !visible;
2099 // Need to do a layout to ensure the wallpaper now has the
2100 // correct size.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07002101 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002102 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002103
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002104 int curWallpaperIndex = token.windows.size();
2105 while (curWallpaperIndex > 0) {
2106 curWallpaperIndex--;
2107 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2108 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002109 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002110 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002111
Craig Mautner507a2ee2012-06-13 08:39:38 -07002112 dispatchWallpaperVisibility(wallpaper, visible);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002113 }
2114 }
2115 }
Craig Mautner711f90a2012-07-03 18:43:52 -07002116
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002117 public int addWindow(Session session, IWindow client, int seq,
Craig Mautner6881a102012-07-27 13:04:51 -07002118 WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002119 Rect outContentInsets, InputChannel outInputChannel) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08002120 int[] appOp = new int[1];
2121 int res = mPolicy.checkAddPermission(attrs, appOp);
Jeff Brown98365d72012-08-19 20:30:52 -07002122 if (res != WindowManagerGlobal.ADD_OKAY) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002123 return res;
2124 }
Romain Guy06882f82009-06-10 13:36:04 -07002125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002126 boolean reportNewConfig = false;
2127 WindowState attachedWindow = null;
2128 WindowState win = null;
Dianne Hackborn5132b372010-07-29 12:51:35 -07002129 long origId;
Craig Mautner88400d32012-09-30 12:35:45 -07002130 final int type = attrs.type;
Romain Guy06882f82009-06-10 13:36:04 -07002131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002132 synchronized(mWindowMap) {
Jeff Browne215f262012-09-10 16:01:14 -07002133 if (!mDisplayReady) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07002134 throw new IllegalStateException("Display has not been initialialized");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002135 }
Romain Guy06882f82009-06-10 13:36:04 -07002136
Craig Mautner2d5618c2012-10-18 13:55:47 -07002137 final DisplayContent displayContent = getDisplayContentLocked(displayId);
2138 if (displayContent == null) {
Jeff Browna506a6e2013-06-04 00:02:38 -07002139 Slog.w(TAG, "Attempted to add window to a display that does not exist: "
2140 + displayId + ". Aborting.");
2141 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
2142 }
2143 if (!displayContent.hasAccess(session.mUid)) {
2144 Slog.w(TAG, "Attempted to add window to a display for which the application "
2145 + "does not have access: " + displayId + ". Aborting.");
Craig Mautner2d5618c2012-10-18 13:55:47 -07002146 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
2147 }
2148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002149 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002150 Slog.w(TAG, "Window " + client + " is already added");
Jeff Brown98365d72012-08-19 20:30:52 -07002151 return WindowManagerGlobal.ADD_DUPLICATE_ADD;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002152 }
2153
Craig Mautner88400d32012-09-30 12:35:45 -07002154 if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002155 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002156 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002157 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002158 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002159 return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002160 }
2161 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
2162 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002163 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002164 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002165 return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002166 }
2167 }
2168
keunyounga446bf02013-06-21 19:07:57 -07002169 if (type == TYPE_PRIVATE_PRESENTATION && !displayContent.isPrivate()) {
2170 Slog.w(TAG, "Attempted to add private presentation window to a non-private display. Aborting.");
2171 return WindowManagerGlobal.ADD_PERMISSION_DENIED;
2172 }
2173
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002174 boolean addToken = false;
2175 WindowToken token = mTokenMap.get(attrs.token);
2176 if (token == null) {
Craig Mautner88400d32012-09-30 12:35:45 -07002177 if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002178 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002179 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002180 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002181 }
Craig Mautner88400d32012-09-30 12:35:45 -07002182 if (type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002183 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002184 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002185 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002186 }
Craig Mautner88400d32012-09-30 12:35:45 -07002187 if (type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002188 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002189 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002190 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002191 }
Craig Mautner88400d32012-09-30 12:35:45 -07002192 if (type == TYPE_DREAM) {
Daniel Sandler7d276c32012-01-30 14:33:52 -05002193 Slog.w(TAG, "Attempted to add Dream window with unknown token "
2194 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002195 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Daniel Sandler7d276c32012-01-30 14:33:52 -05002196 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002197 token = new WindowToken(this, attrs.token, -1, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002198 addToken = true;
Craig Mautner88400d32012-09-30 12:35:45 -07002199 } else if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002200 AppWindowToken atoken = token.appWindowToken;
2201 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002202 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002203 + token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002204 return WindowManagerGlobal.ADD_NOT_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002205 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002206 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002207 + token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002208 return WindowManagerGlobal.ADD_APP_EXITING;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002209 }
Craig Mautner88400d32012-09-30 12:35:45 -07002210 if (type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002211 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002212 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002213 TAG, "**** NO NEED TO START: " + attrs.getTitle());
Jeff Brown98365d72012-08-19 20:30:52 -07002214 return WindowManagerGlobal.ADD_STARTING_NOT_NEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002215 }
Craig Mautner88400d32012-09-30 12:35:45 -07002216 } else if (type == TYPE_INPUT_METHOD) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002217 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002218 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002219 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002220 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002221 }
Craig Mautner88400d32012-09-30 12:35:45 -07002222 } else if (type == TYPE_WALLPAPER) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002223 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002224 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002225 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002226 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002227 }
Craig Mautner88400d32012-09-30 12:35:45 -07002228 } else if (type == TYPE_DREAM) {
Daniel Sandler7d276c32012-01-30 14:33:52 -05002229 if (token.windowType != TYPE_DREAM) {
2230 Slog.w(TAG, "Attempted to add Dream window with bad token "
2231 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002232 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Daniel Sandler7d276c32012-01-30 14:33:52 -05002233 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002234 }
2235
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002236 win = new WindowState(this, session, client, token,
Dianne Hackbornc2293022013-02-06 23:14:49 -08002237 attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002238 if (win.mDeathRecipient == null) {
2239 // Client has apparently died, so there is no reason to
2240 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002241 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002242 + " that is dead, aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002243 return WindowManagerGlobal.ADD_APP_EXITING;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002244 }
2245
2246 mPolicy.adjustWindowParamsLw(win.mAttrs);
Craig Mautner88400d32012-09-30 12:35:45 -07002247 win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));
Romain Guy06882f82009-06-10 13:36:04 -07002248
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002249 res = mPolicy.prepareAddWindowLw(win, attrs);
Jeff Brown98365d72012-08-19 20:30:52 -07002250 if (res != WindowManagerGlobal.ADD_OKAY) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002251 return res;
2252 }
Craig Mautner918b53b2012-07-09 14:15:54 -07002253
Jeff Browncc4f7db2011-08-30 20:34:48 -07002254 if (outInputChannel != null && (attrs.inputFeatures
2255 & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002256 String name = win.makeInputChannelName();
2257 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
Jeff Browncc4f7db2011-08-30 20:34:48 -07002258 win.setInputChannel(inputChannels[0]);
Jeff Brown0a0ab122011-08-12 18:08:08 -07002259 inputChannels[1].transferTo(outInputChannel);
Craig Mautner918b53b2012-07-09 14:15:54 -07002260
Jeff Brown928e0542011-01-10 11:17:36 -08002261 mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002262 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002263
2264 // From now on, no exceptions or errors allowed!
2265
Jeff Brown98365d72012-08-19 20:30:52 -07002266 res = WindowManagerGlobal.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002267
Dianne Hackborn5132b372010-07-29 12:51:35 -07002268 origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002270 if (addToken) {
2271 mTokenMap.put(attrs.token, token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002272 }
2273 win.attach();
2274 mWindowMap.put(client.asBinder(), win);
Dianne Hackbornc2293022013-02-06 23:14:49 -08002275 if (win.mAppOp != AppOpsManager.OP_NONE) {
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002276 if (mAppOps.startOpNoThrow(win.mAppOp, win.getOwningUid(), win.getOwningPackage())
2277 != AppOpsManager.MODE_ALLOWED) {
2278 win.setAppOpVisibilityLw(false);
2279 }
Dianne Hackbornc2293022013-02-06 23:14:49 -08002280 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002281
Craig Mautner88400d32012-09-30 12:35:45 -07002282 if (type == TYPE_APPLICATION_STARTING && token.appWindowToken != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002283 token.appWindowToken.startingWindow = win;
Craig Mautner38b24782012-07-02 16:21:28 -07002284 if (DEBUG_STARTING_WINDOW) Slog.v (TAG, "addWindow: " + token.appWindowToken
2285 + " startingWindow=" + win);
Craig Mautner68cc2412013-10-01 10:39:43 -07002286 Message m = mH.obtainMessage(H.REMOVE_STARTING_TIMEOUT, token.appWindowToken);
2287 mH.sendMessageDelayed(m, STARTING_WINDOW_TIMEOUT_DURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002288 }
2289
2290 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002291
Craig Mautner88400d32012-09-30 12:35:45 -07002292 if (type == TYPE_INPUT_METHOD) {
satok1bc0a492012-04-25 22:47:12 +09002293 win.mGivenInsetsPending = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002294 mInputMethodWindow = win;
2295 addInputMethodWindowToListLocked(win);
2296 imMayMove = false;
Craig Mautner88400d32012-09-30 12:35:45 -07002297 } else if (type == TYPE_INPUT_METHOD_DIALOG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002298 mInputMethodDialogs.add(win);
2299 addWindowToListInOrderLocked(win, true);
Craig Mautnerc00204b2013-03-05 15:02:14 -08002300 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002301 imMayMove = false;
2302 } else {
2303 addWindowToListInOrderLocked(win, true);
Craig Mautner88400d32012-09-30 12:35:45 -07002304 if (type == TYPE_WALLPAPER) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002305 mLastWallpaperTimeoutTime = 0;
Craig Mautnerae446592012-12-06 19:05:05 -08002306 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002307 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Craig Mautnerae446592012-12-06 19:05:05 -08002308 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborn7ad44382012-10-18 17:46:00 -07002309 } else if (mWallpaperTarget != null
2310 && mWallpaperTarget.mLayer >= win.mBaseLayer) {
2311 // If there is currently a wallpaper being shown, and
2312 // the base layer of the new window is below the current
2313 // layer of the target window, then adjust the wallpaper.
2314 // This is to avoid a new window being placed between the
2315 // wallpaper and its target.
Craig Mautnerae446592012-12-06 19:05:05 -08002316 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002317 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002318 }
Romain Guy06882f82009-06-10 13:36:04 -07002319
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002320 win.mWinAnimator.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002321
Craig Mautner69b08182012-09-05 13:07:13 -07002322 if (displayContent.isDefaultDisplay) {
2323 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
2324 } else {
2325 outContentInsets.setEmpty();
2326 }
Romain Guy06882f82009-06-10 13:36:04 -07002327
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002328 if (mInTouchMode) {
Jeff Brown98365d72012-08-19 20:30:52 -07002329 res |= WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002330 }
Craig Mautner764983d2012-03-22 11:37:36 -07002331 if (win.mAppToken == null || !win.mAppToken.clientHidden) {
Jeff Brown98365d72012-08-19 20:30:52 -07002332 res |= WindowManagerGlobal.ADD_FLAG_APP_VISIBLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002333 }
Romain Guy06882f82009-06-10 13:36:04 -07002334
Jeff Brown2e44b072011-01-24 15:21:56 -08002335 mInputMonitor.setUpdateInputWindowsNeededLw();
2336
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002337 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002338 if (win.canReceiveKeys()) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002339 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
2340 false /*updateInputWindows*/);
Jeff Brown349703e2010-06-22 01:27:15 -07002341 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002342 imMayMove = false;
2343 }
2344 }
Romain Guy06882f82009-06-10 13:36:04 -07002345
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002346 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002347 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002348 }
Romain Guy06882f82009-06-10 13:36:04 -07002349
Craig Mautner59c00972012-07-30 12:10:24 -07002350 assignLayersLocked(displayContent.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002351 // Don't do layout here, the window must call
2352 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002353
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002354 if (focusChanged) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002355 finishUpdateFocusedWindowAfterAssignLayersLocked(false /*updateInputWindows*/);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002356 }
Jeff Brown2e44b072011-01-24 15:21:56 -08002357 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08002358
Joe Onorato8a9b2202010-02-26 18:56:32 -08002359 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002360 TAG, "New client " + client.asBinder()
2361 + ": window=" + win);
Craig Mautner9e809442012-06-22 17:13:04 -07002362
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002363 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002364 reportNewConfig = true;
2365 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002366 }
2367
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002368 if (reportNewConfig) {
2369 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002370 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07002371
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002372 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002374 return res;
2375 }
Romain Guy06882f82009-06-10 13:36:04 -07002376
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002377 public void removeWindow(Session session, IWindow client) {
2378 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002379 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002380 if (win == null) {
2381 return;
2382 }
2383 removeWindowLocked(session, win);
2384 }
2385 }
Romain Guy06882f82009-06-10 13:36:04 -07002386
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002387 public void removeWindowLocked(Session session, WindowState win) {
Craig Mautner68cc2412013-10-01 10:39:43 -07002388 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
2389 if (DEBUG_STARTING_WINDOW) Slog.d(TAG, "Starting window removed " + win);
2390 removeStartingWindowTimeout(win.mAppToken);
2391 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002392
Craig Mautner58458122013-09-14 14:59:50 -07002393 if (localLOGV || DEBUG_FOCUS || DEBUG_FOCUS_LIGHT && win==mCurrentFocus) Slog.v(
Craig Mautnere2dd83a2013-10-07 17:01:41 -07002394 TAG, "Remove " + win + " client="
2395 + Integer.toHexString(System.identityHashCode(win.mClient.asBinder()))
2396 + ", surface=" + win.mWinAnimator.mSurfaceControl + " Callers="
2397 + Debug.getCallers(4));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002398
2399 final long origId = Binder.clearCallingIdentity();
Craig Mautner764983d2012-03-22 11:37:36 -07002400
Jeff Brownc5ed5912010-07-14 18:48:53 -07002401 win.disposeInputChannel();
Romain Guy06882f82009-06-10 13:36:04 -07002402
Joe Onorato8a9b2202010-02-26 18:56:32 -08002403 if (DEBUG_APP_TRANSITIONS) Slog.v(
Mathias Agopian29479eb2013-02-14 14:36:04 -08002404 TAG, "Remove " + win + ": mSurface=" + win.mWinAnimator.mSurfaceControl
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002405 + " mExiting=" + win.mExiting
Craig Mautnera2c77052012-03-26 12:14:43 -07002406 + " isAnimating=" + win.mWinAnimator.isAnimating()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002407 + " app-animation="
Craig Mautner59431632012-04-04 11:56:44 -07002408 + (win.mAppToken != null ? win.mAppToken.mAppAnimator.animation : null)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002409 + " inPendingTransaction="
2410 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2411 + " mDisplayFrozen=" + mDisplayFrozen);
2412 // Visibility of the removed window. Will be used later to update orientation later on.
2413 boolean wasVisible = false;
2414 // First, see if we need to run an animation. If we do, we have
2415 // to hold off on removing the window until the animation is done.
2416 // If the display is frozen, just remove immediately, since the
2417 // animation wouldn't be seen.
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002418 if (win.mHasSurface && okToDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002419 // If we are not currently running the exit animation, we
2420 // need to see about starting one.
Craig Mautner764983d2012-03-22 11:37:36 -07002421 wasVisible = win.isWinVisibleLw();
2422 if (wasVisible) {
Romain Guy06882f82009-06-10 13:36:04 -07002423
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002424 int transit = WindowManagerPolicy.TRANSIT_EXIT;
Craig Mautnerbb1449b2012-03-23 16:11:14 -07002425 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002426 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2427 }
2428 // Try starting an animation.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002429 if (win.mWinAnimator.applyAnimationLocked(transit, false)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002430 win.mExiting = true;
2431 }
Svetoslav Ganov545252f2012-12-10 18:29:24 -08002432 //TODO (multidisplay): Magnification is supported only for the default display.
2433 if (mDisplayMagnifier != null
2434 && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
2435 mDisplayMagnifier.onWindowTransitionLocked(win, transit);
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07002436 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002437 }
Craig Mautnera2c77052012-03-26 12:14:43 -07002438 if (win.mExiting || win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002439 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002440 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002441 win.mExiting = true;
2442 win.mRemoveOnExit = true;
Craig Mautnerdf88d732014-01-27 09:21:32 -08002443 final DisplayContent displayContent = win.getDisplayContent();
2444 if (displayContent != null) {
2445 displayContent.layoutNeeded = true;
2446 }
Jeff Brown3a22cd92011-01-21 13:59:04 -08002447 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2448 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002449 performLayoutAndPlaceSurfacesLocked();
2450 if (win.mAppToken != null) {
2451 win.mAppToken.updateReportedVisibilityLocked();
2452 }
2453 //dump();
2454 Binder.restoreCallingIdentity(origId);
2455 return;
2456 }
2457 }
2458
2459 removeWindowInnerLocked(session, win);
2460 // Removing a visible window will effect the computed orientation
2461 // So just update orientation if needed.
Craig Mautner2268e7e2012-12-13 15:40:00 -08002462 if (wasVisible && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002463 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002464 }
Jeff Brown3a22cd92011-01-21 13:59:04 -08002465 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002466 Binder.restoreCallingIdentity(origId);
2467 }
Romain Guy06882f82009-06-10 13:36:04 -07002468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002469 private void removeWindowInnerLocked(Session session, WindowState win) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002470 if (win.mRemoved) {
2471 // Nothing to do.
2472 return;
2473 }
2474
2475 for (int i=win.mChildWindows.size()-1; i>=0; i--) {
2476 WindowState cwin = win.mChildWindows.get(i);
2477 Slog.w(TAG, "Force-removing child win " + cwin + " from container "
2478 + win);
2479 removeWindowInnerLocked(cwin.mSession, cwin);
2480 }
2481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002482 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002484 if (mInputMethodTarget == win) {
2485 moveInputMethodWindowsIfNeededLocked(false);
2486 }
Romain Guy06882f82009-06-10 13:36:04 -07002487
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002488 if (false) {
2489 RuntimeException e = new RuntimeException("here");
2490 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002491 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002492 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002494 mPolicy.removeWindowLw(win);
2495 win.removeLocked();
2496
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002497 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002498 mWindowMap.remove(win.mClient.asBinder());
Dianne Hackbornc2293022013-02-06 23:14:49 -08002499 if (win.mAppOp != AppOpsManager.OP_NONE) {
2500 mAppOps.finishOp(win.mAppOp, win.getOwningUid(), win.getOwningPackage());
2501 }
Craig Mautner59c00972012-07-30 12:10:24 -07002502
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002503 mPendingRemove.remove(win);
Craig Mautner860f6602012-10-18 09:38:10 -07002504 mResizingWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002505 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002506 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002507
2508 if (mInputMethodWindow == win) {
2509 mInputMethodWindow = null;
2510 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2511 mInputMethodDialogs.remove(win);
2512 }
Romain Guy06882f82009-06-10 13:36:04 -07002513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002514 final WindowToken token = win.mToken;
2515 final AppWindowToken atoken = win.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002516 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + win + " from " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002517 token.windows.remove(win);
2518 if (atoken != null) {
2519 atoken.allAppWindows.remove(win);
2520 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002521 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002522 TAG, "**** Removing window " + win + ": count="
2523 + token.windows.size());
2524 if (token.windows.size() == 0) {
2525 if (!token.explicit) {
2526 mTokenMap.remove(token.token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002527 } else if (atoken != null) {
2528 atoken.firstWindowDrawn = false;
2529 }
2530 }
2531
2532 if (atoken != null) {
2533 if (atoken.startingWindow == win) {
Craig Mautner38b24782012-07-02 16:21:28 -07002534 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling startingWindow " + win);
Craig Mautner68cc2412013-10-01 10:39:43 -07002535 removeStartingWindowTimeout(atoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002536 atoken.startingWindow = null;
2537 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2538 // If this is the last window and we had requested a starting
2539 // transition window, well there is no point now.
Craig Mautner38b24782012-07-02 16:21:28 -07002540 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling last startingWindow");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002541 atoken.startingData = null;
2542 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2543 // If this is the last window except for a starting transition
2544 // window, we need to get rid of the starting transition.
Craig Mautner68cc2412013-10-01 10:39:43 -07002545 scheduleRemoveStartingWindow(atoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002546 }
2547 }
Romain Guy06882f82009-06-10 13:36:04 -07002548
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002549 if (win.mAttrs.type == TYPE_WALLPAPER) {
2550 mLastWallpaperTimeoutTime = 0;
Craig Mautnerae446592012-12-06 19:05:05 -08002551 getDefaultDisplayContentLocked().pendingLayoutChanges |=
2552 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002553 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Craig Mautnerae446592012-12-06 19:05:05 -08002554 getDefaultDisplayContentLocked().pendingLayoutChanges |=
2555 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002556 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002557
Craig Mautnerdf88d732014-01-27 09:21:32 -08002558 final WindowList windows = win.getWindowList();
2559 if (windows != null) {
2560 windows.remove(win);
2561 if (!mInLayout) {
2562 assignLayersLocked(windows);
2563 final DisplayContent displayContent = win.getDisplayContent();
2564 if (displayContent != null) {
2565 displayContent.layoutNeeded = true;
2566 }
2567 performLayoutAndPlaceSurfacesLocked();
2568 if (win.mAppToken != null) {
2569 win.mAppToken.updateReportedVisibilityLocked();
2570 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002571 }
2572 }
Craig Mautner9e809442012-06-22 17:13:04 -07002573
Jeff Brown2e44b072011-01-24 15:21:56 -08002574 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002575 }
2576
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002577 public void updateAppOpsState() {
2578 synchronized(mWindowMap) {
Craig Mautnerf8924152013-07-16 09:10:55 -07002579 final int numDisplays = mDisplayContents.size();
2580 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2581 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
2582 final int numWindows = windows.size();
2583 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
2584 final WindowState win = windows.get(winNdx);
2585 if (win.mAppOp != AppOpsManager.OP_NONE) {
2586 final int mode = mAppOps.checkOpNoThrow(win.mAppOp, win.getOwningUid(),
2587 win.getOwningPackage());
2588 win.setAppOpVisibilityLw(mode == AppOpsManager.MODE_ALLOWED);
2589 }
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002590 }
2591 }
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002592 }
2593 }
2594
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002595 static void logSurface(WindowState w, String msg, RuntimeException where) {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002596 String str = " SURFACE " + msg + ": " + w;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002597 if (where != null) {
2598 Slog.i(TAG, str, where);
2599 } else {
2600 Slog.i(TAG, str);
2601 }
2602 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002603
Mathias Agopian3866f0d2013-02-11 22:08:48 -08002604 static void logSurface(SurfaceControl s, String title, String msg, RuntimeException where) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002605 String str = " SURFACE " + s + ": " + msg + " / " + title;
2606 if (where != null) {
2607 Slog.i(TAG, str, where);
2608 } else {
2609 Slog.i(TAG, str);
2610 }
2611 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07002612
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002613 void setTransparentRegionWindow(Session session, IWindow client, Region region) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002614 long origId = Binder.clearCallingIdentity();
2615 try {
2616 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002617 WindowState w = windowForClientLocked(session, client, false);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002618 if ((w != null) && w.mHasSurface) {
Craig Mautneref655012013-01-03 11:20:24 -08002619 w.mWinAnimator.setTransparentRegionHintLocked(region);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002620 }
2621 }
2622 } finally {
2623 Binder.restoreCallingIdentity(origId);
2624 }
2625 }
2626
2627 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002628 int touchableInsets, Rect contentInsets,
Jeff Brownfbf09772011-01-16 14:06:57 -08002629 Rect visibleInsets, Region touchableRegion) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002630 long origId = Binder.clearCallingIdentity();
2631 try {
2632 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002633 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002634 if (w != null) {
2635 w.mGivenInsetsPending = false;
2636 w.mGivenContentInsets.set(contentInsets);
2637 w.mGivenVisibleInsets.set(visibleInsets);
Jeff Brownfbf09772011-01-16 14:06:57 -08002638 w.mGivenTouchableRegion.set(touchableRegion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002639 w.mTouchableInsets = touchableInsets;
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002640 if (w.mGlobalScale != 1) {
2641 w.mGivenContentInsets.scale(w.mGlobalScale);
2642 w.mGivenVisibleInsets.scale(w.mGlobalScale);
2643 w.mGivenTouchableRegion.scale(w.mGlobalScale);
2644 }
Craig Mautnerdf88d732014-01-27 09:21:32 -08002645 final DisplayContent displayContent = w.getDisplayContent();
2646 if (displayContent != null) {
2647 displayContent.layoutNeeded = true;
2648 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002649 performLayoutAndPlaceSurfacesLocked();
2650 }
2651 }
2652 } finally {
2653 Binder.restoreCallingIdentity(origId);
2654 }
2655 }
Romain Guy06882f82009-06-10 13:36:04 -07002656
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002657 public void getWindowDisplayFrame(Session session, IWindow client,
2658 Rect outDisplayFrame) {
2659 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002660 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002661 if (win == null) {
2662 outDisplayFrame.setEmpty();
2663 return;
2664 }
2665 outDisplayFrame.set(win.mDisplayFrame);
2666 }
2667 }
2668
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002669 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2670 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002671 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2672 window.mWallpaperX = x;
2673 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002674 window.mWallpaperXStep = xStep;
2675 window.mWallpaperYStep = yStep;
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002676 updateWallpaperOffsetLocked(window, true);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002677 }
2678 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002679
Dianne Hackborn75804932009-10-20 20:15:20 -07002680 void wallpaperCommandComplete(IBinder window, Bundle result) {
2681 synchronized (mWindowMap) {
2682 if (mWaitingOnWallpaper != null &&
2683 mWaitingOnWallpaper.mClient.asBinder() == window) {
2684 mWaitingOnWallpaper = null;
2685 mWindowMap.notifyAll();
2686 }
2687 }
2688 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002689
Dianne Hackborn75804932009-10-20 20:15:20 -07002690 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2691 String action, int x, int y, int z, Bundle extras, boolean sync) {
2692 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2693 || window == mUpperWallpaperTarget) {
2694 boolean doWait = sync;
2695 int curTokenIndex = mWallpaperTokens.size();
2696 while (curTokenIndex > 0) {
2697 curTokenIndex--;
2698 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2699 int curWallpaperIndex = token.windows.size();
2700 while (curWallpaperIndex > 0) {
2701 curWallpaperIndex--;
2702 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2703 try {
2704 wallpaper.mClient.dispatchWallpaperCommand(action,
2705 x, y, z, extras, sync);
2706 // We only want to be synchronous with one wallpaper.
2707 sync = false;
2708 } catch (RemoteException e) {
2709 }
2710 }
2711 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002712
Dianne Hackborn75804932009-10-20 20:15:20 -07002713 if (doWait) {
2714 // XXX Need to wait for result.
2715 }
2716 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002717
Dianne Hackborn75804932009-10-20 20:15:20 -07002718 return null;
2719 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002720
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002721 public void setUniverseTransformLocked(WindowState window, float alpha,
2722 float offx, float offy, float dsdx, float dtdx, float dsdy, float dtdy) {
2723 Transformation transform = window.mWinAnimator.mUniverseTransform;
2724 transform.setAlpha(alpha);
2725 Matrix matrix = transform.getMatrix();
2726 matrix.getValues(mTmpFloats);
2727 mTmpFloats[Matrix.MTRANS_X] = offx;
2728 mTmpFloats[Matrix.MTRANS_Y] = offy;
2729 mTmpFloats[Matrix.MSCALE_X] = dsdx;
2730 mTmpFloats[Matrix.MSKEW_Y] = dtdx;
2731 mTmpFloats[Matrix.MSKEW_X] = dsdy;
2732 mTmpFloats[Matrix.MSCALE_Y] = dtdy;
2733 matrix.setValues(mTmpFloats);
Craig Mautnerdf88d732014-01-27 09:21:32 -08002734 final DisplayContent displayContent = window.getDisplayContent();
2735 if (displayContent == null) {
2736 return;
2737 }
2738
2739 final DisplayInfo displayInfo = window.getDisplayContent().getDisplayInfo();
Jeff Brownfa25bf52012-07-23 19:26:30 -07002740 final RectF dispRect = new RectF(0, 0,
Craig Mautner59c00972012-07-30 12:10:24 -07002741 displayInfo.logicalWidth, displayInfo.logicalHeight);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002742 matrix.mapRect(dispRect);
Jeff Brownfa25bf52012-07-23 19:26:30 -07002743 window.mGivenTouchableRegion.set(0, 0,
Craig Mautner59c00972012-07-30 12:10:24 -07002744 displayInfo.logicalWidth, displayInfo.logicalHeight);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002745 window.mGivenTouchableRegion.op((int)dispRect.left, (int)dispRect.top,
2746 (int)dispRect.right, (int)dispRect.bottom, Region.Op.DIFFERENCE);
2747 window.mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
Craig Mautnerdf88d732014-01-27 09:21:32 -08002748 displayContent.layoutNeeded = true;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002749 performLayoutAndPlaceSurfacesLocked();
2750 }
2751
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002752 public void onRectangleOnScreenRequested(IBinder token, Rect rectangle, boolean immediate) {
2753 synchronized (mWindowMap) {
Svetoslav Ganov545252f2012-12-10 18:29:24 -08002754 if (mDisplayMagnifier != null) {
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07002755 WindowState window = mWindowMap.get(token);
Svetoslav Ganov545252f2012-12-10 18:29:24 -08002756 //TODO (multidisplay): Magnification is supported only for the default display.
2757 if (window != null && window.getDisplayId() == Display.DEFAULT_DISPLAY) {
2758 mDisplayMagnifier.onRectangleOnScreenRequestedLocked(rectangle, immediate);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002759 }
2760 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002761 }
2762 }
2763
Dianne Hackborne3f23a32013-03-01 13:25:35 -08002764 public IWindowId getWindowId(IBinder token) {
2765 synchronized (mWindowMap) {
2766 WindowState window = mWindowMap.get(token);
2767 return window != null ? window.mWindowId : null;
2768 }
2769 }
2770
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002771 public int relayoutWindow(Session session, IWindow client, int seq,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002772 WindowManager.LayoutParams attrs, int requestedWidth,
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002773 int requestedHeight, int viewVisibility, int flags,
Dianne Hackbornc4aad012013-02-22 15:05:25 -08002774 Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
Dianne Hackborn5c58de32012-04-28 19:52:37 -07002775 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07002776 boolean toBeDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002777 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002778 boolean configChanged;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002779 boolean surfaceChanged = false;
Dianne Hackborn12d3a942012-04-27 14:16:30 -07002780 boolean animating;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002781
2782 // if they don't have this permission, mask out the status bar bits
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002783 int systemUiVisibility = 0;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002784 if (attrs != null) {
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002785 systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
2786 if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -07002787 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
2788 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002789 systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
Dianne Hackborna44abeb2011-08-08 19:24:01 -07002790 }
Joe Onoratoac0ee892011-01-30 15:38:30 -08002791 }
2792 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002793 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002794
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002795 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002796 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002797 if (win == null) {
2798 return 0;
2799 }
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002800 WindowStateAnimator winAnimator = win.mWinAnimator;
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08002801 if (win.mRequestedWidth != requestedWidth
2802 || win.mRequestedHeight != requestedHeight) {
2803 win.mLayoutNeeded = true;
2804 win.mRequestedWidth = requestedWidth;
2805 win.mRequestedHeight = requestedHeight;
2806 }
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002807 if (attrs != null && seq == win.mSeq) {
2808 win.mSystemUiVisibility = systemUiVisibility;
2809 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002810
2811 if (attrs != null) {
2812 mPolicy.adjustWindowParamsLw(attrs);
2813 }
Romain Guy06882f82009-06-10 13:36:04 -07002814
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002815 winAnimator.mSurfaceDestroyDeferred =
Jeff Brown98365d72012-08-19 20:30:52 -07002816 (flags&WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002817
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002818 int attrChanges = 0;
2819 int flagChanges = 0;
2820 if (attrs != null) {
Dianne Hackborn0e60db22011-09-01 11:17:57 -07002821 if (win.mAttrs.type != attrs.type) {
2822 throw new IllegalArgumentException(
2823 "Window type can not be changed after the window is added.");
2824 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002825 flagChanges = win.mAttrs.flags ^= attrs.flags;
2826 attrChanges = win.mAttrs.copyFrom(attrs);
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002827 if ((attrChanges & (WindowManager.LayoutParams.LAYOUT_CHANGED
2828 | WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED)) != 0) {
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08002829 win.mLayoutNeeded = true;
2830 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002831 }
2832
Dianne Hackborn7ff30112012-11-08 11:12:09 -08002833 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": viewVisibility=" + viewVisibility
Chet Haased5d11af2012-10-31 08:57:17 -07002834 + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002835
Adam Lesinski95c42972013-10-02 10:13:27 -07002836 win.mEnforceSizeCompat =
2837 (win.mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07002838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002839 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002840 winAnimator.mAlpha = attrs.alpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002841 }
2842
2843 final boolean scaledWindow =
2844 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2845
2846 if (scaledWindow) {
2847 // requested{Width|Height} Surface's physical size
2848 // attrs.{width|height} Size on screen
2849 win.mHScale = (attrs.width != requestedWidth) ?
2850 (attrs.width / (float)requestedWidth) : 1.0f;
2851 win.mVScale = (attrs.height != requestedHeight) ?
2852 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002853 } else {
2854 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002855 }
2856
Craig Mautner65d11b32012-10-01 13:59:52 -07002857 boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002858
Craig Mautner69b08182012-09-05 13:07:13 -07002859 final boolean isDefaultDisplay = win.isDefaultDisplay();
2860 boolean focusMayChange = isDefaultDisplay && (win.mViewVisibility != viewVisibility
Craig Mautner65d11b32012-10-01 13:59:52 -07002861 || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0)
Craig Mautner69b08182012-09-05 13:07:13 -07002862 || (!win.mRelayoutCalled));
Romain Guy06882f82009-06-10 13:36:04 -07002863
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002864 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2865 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07002866 wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002867
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002868 win.mRelayoutCalled = true;
2869 final int oldVisibility = win.mViewVisibility;
2870 win.mViewVisibility = viewVisibility;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07002871 if (DEBUG_SCREEN_ON) {
2872 RuntimeException stack = new RuntimeException();
2873 stack.fillInStackTrace();
2874 Slog.i(TAG, "Relayout " + win + ": oldVis=" + oldVisibility
2875 + " newVis=" + viewVisibility, stack);
2876 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002877 if (viewVisibility == View.VISIBLE &&
2878 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07002879 toBeDisplayed = !win.isVisibleLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002880 if (win.mExiting) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002881 winAnimator.cancelExitAnimationForNextAnimationLocked();
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002882 win.mExiting = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002883 }
2884 if (win.mDestroying) {
2885 win.mDestroying = false;
2886 mDestroySurface.remove(win);
2887 }
2888 if (oldVisibility == View.GONE) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002889 winAnimator.mEnterAnimationPending = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002890 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002891 if (toBeDisplayed) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07002892 if (win.isDrawnLw() && okToDisplay()) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002893 winAnimator.applyEnterAnimationLocked();
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002894 }
2895 if ((win.mAttrs.flags
2896 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2897 if (DEBUG_VISIBILITY) Slog.v(TAG,
2898 "Relayout window turning screen on: " + win);
2899 win.mTurnOnScreen = true;
2900 }
Craig Mautnera3f4bf52012-10-10 20:37:48 -07002901 if (win.isConfigChanged()) {
2902 if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + win
Craig Mautnere8552142012-11-07 13:55:47 -08002903 + " visible with new config: " + mCurConfiguration);
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002904 outConfig.setTo(mCurConfiguration);
2905 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002906 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002907 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2908 // To change the format, we need to re-build the surface.
Craig Mautner96868332012-12-04 14:29:11 -08002909 winAnimator.destroySurfaceLocked();
Craig Mautnerbf08af32012-05-16 19:43:42 -07002910 toBeDisplayed = true;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002911 surfaceChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002912 }
2913 try {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002914 if (!win.mHasSurface) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002915 surfaceChanged = true;
2916 }
Mathias Agopian29479eb2013-02-14 14:36:04 -08002917 SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
2918 if (surfaceControl != null) {
2919 outSurface.copyFrom(surfaceControl);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002920 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002921 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002922 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002923 // For some reason there isn't a surface. Clear the
2924 // caller's object so they see the same state.
2925 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002926 }
2927 } catch (Exception e) {
Jeff Brown2e44b072011-01-24 15:21:56 -08002928 mInputMonitor.updateInputWindowsLw(true /*force*/);
Craig Mautner9e809442012-06-22 17:13:04 -07002929
Joe Onorato8a9b2202010-02-26 18:56:32 -08002930 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002931 + client + " (" + win.mAttrs.getTitle() + ")",
2932 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002933 Binder.restoreCallingIdentity(origId);
2934 return 0;
2935 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002936 if (toBeDisplayed) {
Craig Mautner69b08182012-09-05 13:07:13 -07002937 focusMayChange = isDefaultDisplay;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002938 }
2939 if (win.mAttrs.type == TYPE_INPUT_METHOD
2940 && mInputMethodWindow == null) {
2941 mInputMethodWindow = win;
2942 imMayMove = true;
2943 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002944 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2945 && win.mAppToken != null
2946 && win.mAppToken.startingWindow != null) {
2947 // Special handling of starting window over the base
2948 // window of the app: propagate lock screen flags to it,
2949 // to provide the correct semantics while starting.
2950 final int mask =
2951 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002952 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2953 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002954 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2955 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2956 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002957 } else {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002958 winAnimator.mEnterAnimationPending = false;
Mathias Agopian29479eb2013-02-14 14:36:04 -08002959 if (winAnimator.mSurfaceControl != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002960 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Craig Mautnerbf08af32012-05-16 19:43:42 -07002961 + ": mExiting=" + win.mExiting);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002962 // If we are not currently running the exit animation, we
2963 // need to see about starting one.
Craig Mautnerbf08af32012-05-16 19:43:42 -07002964 if (!win.mExiting) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002965 surfaceChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002966 // Try starting an animation; if there isn't one, we
2967 // can destroy the surface right away.
2968 int transit = WindowManagerPolicy.TRANSIT_EXIT;
Craig Mautnerbb1449b2012-03-23 16:11:14 -07002969 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002970 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2971 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002972 if (win.isWinVisibleLw() &&
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002973 winAnimator.applyAnimationLocked(transit, false)) {
Craig Mautner69b08182012-09-05 13:07:13 -07002974 focusMayChange = isDefaultDisplay;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002975 win.mExiting = true;
Craig Mautnera2c77052012-03-26 12:14:43 -07002976 } else if (win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002977 // Currently in a hide animation... turn this into
2978 // an exit.
2979 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002980 } else if (win == mWallpaperTarget) {
2981 // If the wallpaper is currently behind this
2982 // window, we need to change both of them inside
2983 // of a transaction to avoid artifacts.
2984 win.mExiting = true;
Craig Mautnera2c77052012-03-26 12:14:43 -07002985 win.mWinAnimator.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002986 } else {
2987 if (mInputMethodWindow == win) {
2988 mInputMethodWindow = null;
2989 }
Craig Mautner96868332012-12-04 14:29:11 -08002990 winAnimator.destroySurfaceLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002991 }
Svetoslav Ganov545252f2012-12-10 18:29:24 -08002992 //TODO (multidisplay): Magnification is supported only for the default
2993 if (mDisplayMagnifier != null
2994 && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
2995 mDisplayMagnifier.onWindowTransitionLocked(win, transit);
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07002996 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002997 }
2998 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002999
Craig Mautnerbf08af32012-05-16 19:43:42 -07003000 outSurface.release();
3001 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003002 }
3003
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003004 if (focusMayChange) {
3005 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
Jeff Brown3a22cd92011-01-21 13:59:04 -08003006 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
3007 false /*updateInputWindows*/)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003008 imMayMove = false;
3009 }
3010 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
3011 }
Romain Guy06882f82009-06-10 13:36:04 -07003012
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08003013 // updateFocusedWindowLocked() already assigned layers so we only need to
3014 // reassign them at this point if the IM window state gets shuffled
Craig Mautnerb5eb5502013-01-10 17:29:30 -08003015 if (imMayMove && (moveInputMethodWindowsIfNeededLocked(false) || toBeDisplayed)) {
3016 // Little hack here -- we -should- be able to rely on the
3017 // function to return true if the IME has moved and needs
3018 // its layer recomputed. However, if the IME was hidden
3019 // and isn't actually moved in the list, its layer may be
3020 // out of data so we make sure to recompute it.
3021 assignLayersLocked(win.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003022 }
Craig Mautnerb5eb5502013-01-10 17:29:30 -08003023
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003024 if (wallpaperMayMove) {
Craig Mautnerae446592012-12-06 19:05:05 -08003025 getDefaultDisplayContentLocked().pendingLayoutChanges |=
3026 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003027 }
Romain Guy06882f82009-06-10 13:36:04 -07003028
Craig Mautnerdf88d732014-01-27 09:21:32 -08003029 final DisplayContent displayContent = win.getDisplayContent();
3030 if (displayContent != null) {
3031 displayContent.layoutNeeded = true;
3032 }
Jeff Brown98365d72012-08-19 20:30:52 -07003033 win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003034 configChanged = updateOrientationFromAppTokensLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003035 performLayoutAndPlaceSurfacesLocked();
Craig Mautnerbf08af32012-05-16 19:43:42 -07003036 if (toBeDisplayed && win.mIsWallpaper) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003037 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Jeff Brownfa25bf52012-07-23 19:26:30 -07003038 updateWallpaperOffsetLocked(win,
John Spurlockef4adae2013-08-26 17:58:58 -04003039 displayInfo.logicalWidth, displayInfo.logicalHeight, false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07003040 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003041 if (win.mAppToken != null) {
3042 win.mAppToken.updateReportedVisibilityLocked();
3043 }
Dianne Hackbornffb3d932011-05-17 17:44:51 -07003044 outFrame.set(win.mCompatFrame);
Dianne Hackbornc4aad012013-02-22 15:05:25 -08003045 outOverscanInsets.set(win.mOverscanInsets);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003046 outContentInsets.set(win.mContentInsets);
3047 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003048 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003049 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07003050 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003051 + ", requestedHeight=" + requestedHeight
3052 + ", viewVisibility=" + viewVisibility
3053 + "\nRelayout returning frame=" + outFrame
3054 + ", surface=" + outSurface);
3055
Joe Onorato8a9b2202010-02-26 18:56:32 -08003056 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003057 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
3058
3059 inTouchMode = mInTouchMode;
Dianne Hackborn021d2432013-10-13 15:20:09 -07003060 animating = mAnimator.mAnimating && win.mWinAnimator.isAnimating();
Dianne Hackborn12d3a942012-04-27 14:16:30 -07003061 if (animating && !mRelayoutWhileAnimating.contains(win)) {
3062 mRelayoutWhileAnimating.add(win);
3063 }
3064
Jeff Brown2e44b072011-01-24 15:21:56 -08003065 mInputMonitor.updateInputWindowsLw(true /*force*/);
Chet Haased5d11af2012-10-31 08:57:17 -07003066
3067 if (DEBUG_LAYOUT) {
3068 Slog.v(TAG, "Relayout complete " + win + ": outFrame=" + outFrame.toShortString());
3069 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003070 }
3071
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003072 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003073 sendNewConfiguration();
3074 }
Romain Guy06882f82009-06-10 13:36:04 -07003075
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003076 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07003077
Jeff Brown98365d72012-08-19 20:30:52 -07003078 return (inTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0)
3079 | (toBeDisplayed ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0)
3080 | (surfaceChanged ? WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED : 0)
3081 | (animating ? WindowManagerGlobal.RELAYOUT_RES_ANIMATING : 0);
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003082 }
3083
3084 public void performDeferredDestroyWindow(Session session, IWindow client) {
3085 long origId = Binder.clearCallingIdentity();
3086
3087 try {
Craig Mautnerae446592012-12-06 19:05:05 -08003088 synchronized (mWindowMap) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003089 WindowState win = windowForClientLocked(session, client, false);
3090 if (win == null) {
3091 return;
3092 }
Craig Mautner96868332012-12-04 14:29:11 -08003093 win.mWinAnimator.destroyDeferredSurfaceLocked();
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003094 }
3095 } finally {
3096 Binder.restoreCallingIdentity(origId);
3097 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003098 }
3099
Dianne Hackborn64825172011-03-02 21:32:58 -08003100 public boolean outOfMemoryWindow(Session session, IWindow client) {
3101 long origId = Binder.clearCallingIdentity();
3102
3103 try {
Craig Mautnerae446592012-12-06 19:05:05 -08003104 synchronized (mWindowMap) {
Dianne Hackborn64825172011-03-02 21:32:58 -08003105 WindowState win = windowForClientLocked(session, client, false);
3106 if (win == null) {
3107 return false;
3108 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003109 return reclaimSomeSurfaceMemoryLocked(win.mWinAnimator, "from-client", false);
Dianne Hackborn64825172011-03-02 21:32:58 -08003110 }
3111 } finally {
3112 Binder.restoreCallingIdentity(origId);
3113 }
3114 }
3115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003116 public void finishDrawingWindow(Session session, IWindow client) {
3117 final long origId = Binder.clearCallingIdentity();
Craig Mautneref655012013-01-03 11:20:24 -08003118 try {
3119 synchronized (mWindowMap) {
3120 WindowState win = windowForClientLocked(session, client, false);
3121 if (win != null && win.mWinAnimator.finishDrawingLocked()) {
3122 if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
3123 getDefaultDisplayContentLocked().pendingLayoutChanges |=
3124 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
3125 }
Craig Mautnerdf88d732014-01-27 09:21:32 -08003126 final DisplayContent displayContent = win.getDisplayContent();
3127 if (displayContent != null) {
3128 displayContent.layoutNeeded = true;
3129 }
Craig Mautneref655012013-01-03 11:20:24 -08003130 requestTraversalLocked();
Dianne Hackborn759a39e2009-08-09 17:20:27 -07003131 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003132 }
Craig Mautneref655012013-01-03 11:20:24 -08003133 } finally {
3134 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003135 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003136 }
3137
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003138 @Override
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07003139 public void getWindowFrame(IBinder token, Rect outBounds) {
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003140 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
3141 "getWindowInfo()")) {
3142 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
3143 }
3144 synchronized (mWindowMap) {
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07003145 WindowState windowState = mWindowMap.get(token);
3146 if (windowState != null) {
3147 outBounds.set(windowState.mFrame);
3148 } else {
3149 outBounds.setEmpty();
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003150 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003151 }
3152 }
3153
3154 @Override
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003155 public void setMagnificationSpec(MagnificationSpec spec) {
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07003156 if (!checkCallingPermission(android.Manifest.permission.MAGNIFY_DISPLAY,
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003157 "setMagnificationSpec()")) {
3158 throw new SecurityException("Requires MAGNIFY_DISPLAY permission.");
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003159 }
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003160 synchronized (mWindowMap) {
3161 if (mDisplayMagnifier != null) {
3162 mDisplayMagnifier.setMagnificationSpecLocked(spec);
3163 } else {
3164 throw new IllegalStateException("Magnification callbacks not set!");
3165 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003166 }
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003167 if (Binder.getCallingPid() != android.os.Process.myPid()) {
3168 spec.recycle();
3169 }
3170 }
3171
3172 @Override
3173 public MagnificationSpec getCompatibleMagnificationSpecForWindow(IBinder windowToken) {
3174 if (!checkCallingPermission(android.Manifest.permission.MAGNIFY_DISPLAY,
3175 "getCompatibleMagnificationSpecForWindow()")) {
3176 throw new SecurityException("Requires MAGNIFY_DISPLAY permission.");
3177 }
3178 synchronized (mWindowMap) {
3179 WindowState windowState = mWindowMap.get(windowToken);
3180 if (windowState == null) {
3181 return null;
3182 }
3183 MagnificationSpec spec = null;
3184 if (mDisplayMagnifier != null) {
3185 spec = mDisplayMagnifier.getMagnificationSpecForWindowLocked(windowState);
3186 }
3187 if ((spec == null || spec.isNop()) && windowState.mGlobalScale == 1.0f) {
3188 return null;
3189 }
3190 spec = (spec == null) ? MagnificationSpec.obtain() : MagnificationSpec.obtain(spec);
3191 spec.scale *= windowState.mGlobalScale;
3192 return spec;
3193 }
3194 }
3195
3196 @Override
3197 public void setMagnificationCallbacks(IMagnificationCallbacks callbacks) {
3198 if (!checkCallingPermission(android.Manifest.permission.MAGNIFY_DISPLAY,
3199 "setMagnificationCallbacks()")) {
3200 throw new SecurityException("Requires MAGNIFY_DISPLAY permission.");
3201 }
3202 synchronized (mWindowMap) {
3203 if (mDisplayMagnifier == null) {
3204 mDisplayMagnifier = new DisplayMagnifier(this, callbacks);
3205 } else {
3206 if (callbacks == null) {
Svetoslavcb9a61b2013-01-22 18:11:42 -08003207 if (mDisplayMagnifier != null) {
3208 mDisplayMagnifier.destroyLocked();
3209 mDisplayMagnifier = null;
3210 }
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003211 } else {
3212 throw new IllegalStateException("Magnification callbacks already set!");
3213 }
3214 }
3215 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003216 }
3217
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003218 private boolean applyAnimationLocked(AppWindowToken atoken,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07003219 WindowManager.LayoutParams lp, int transit, boolean enter) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003220 // Only apply an animation if the display isn't frozen. If it is
3221 // frozen, there is no reason to animate and it can cause strange
3222 // artifacts when we unfreeze the display if some different animation
3223 // is running.
Craig Mautner2fb98b12012-03-20 17:24:00 -07003224 if (okToDisplay()) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003225 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Craig Mautner9339c402012-11-30 11:23:56 -08003226 final int width = displayInfo.appWidth;
3227 final int height = displayInfo.appHeight;
Craig Mautner164d4bb2012-11-26 13:51:23 -08003228 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "applyAnimation: atoken="
3229 + atoken);
Craig Mautner9339c402012-11-30 11:23:56 -08003230 Animation a = mAppTransition.loadAnimation(lp, transit, enter, width, height);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003231 if (a != null) {
3232 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003233 RuntimeException e = null;
3234 if (!HIDE_STACK_CRAWLS) {
3235 e = new RuntimeException();
3236 e.fillInStackTrace();
3237 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003238 Slog.v(TAG, "Loaded animation " + a + " for " + atoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003239 }
Craig Mautner9339c402012-11-30 11:23:56 -08003240 atoken.mAppAnimator.setAnimation(a, width, height);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003241 }
3242 } else {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003243 atoken.mAppAnimator.clearAnimation();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003244 }
3245
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003246 return atoken.mAppAnimator.animation != null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003247 }
3248
3249 // -------------------------------------------------------------
3250 // Application Window Tokens
3251 // -------------------------------------------------------------
3252
Craig Mautner00af9fe2013-03-25 09:13:41 -07003253 public void validateAppTokens(int stackId, List<TaskGroup> tasks) {
Craig Mautner343ad712013-02-13 22:37:26 -08003254 synchronized (mWindowMap) {
3255 int t = tasks.size() - 1;
3256 if (t < 0) {
3257 Slog.w(TAG, "validateAppTokens: empty task list");
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08003258 return;
3259 }
3260
Craig Mautner343ad712013-02-13 22:37:26 -08003261 TaskGroup task = tasks.get(0);
3262 int taskId = task.taskId;
Craig Mautnerc00204b2013-03-05 15:02:14 -08003263 Task targetTask = mTaskIdToTask.get(taskId);
3264 DisplayContent displayContent = targetTask.getDisplayContent();
Craig Mautner343ad712013-02-13 22:37:26 -08003265 if (displayContent == null) {
3266 Slog.w(TAG, "validateAppTokens: no Display for taskId=" + taskId);
3267 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003268 }
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08003269
Craig Mautner00af9fe2013-03-25 09:13:41 -07003270 final ArrayList<Task> localTasks = mStackIdToStack.get(stackId).getTasks();
Craig Mautnerf81b90872013-02-26 13:02:43 -08003271 int taskNdx;
3272 for (taskNdx = localTasks.size() - 1; taskNdx >= 0 && t >= 0; --taskNdx, --t) {
3273 AppTokenList localTokens = localTasks.get(taskNdx).mAppTokens;
Craig Mautner343ad712013-02-13 22:37:26 -08003274 task = tasks.get(t);
3275 List<IApplicationToken> tokens = task.tokens;
Craig Mautner343ad712013-02-13 22:37:26 -08003276
3277 DisplayContent lastDisplayContent = displayContent;
Craig Mautnerc00204b2013-03-05 15:02:14 -08003278 displayContent = mTaskIdToTask.get(taskId).getDisplayContent();
Craig Mautner343ad712013-02-13 22:37:26 -08003279 if (displayContent != lastDisplayContent) {
3280 Slog.w(TAG, "validateAppTokens: displayContent changed in TaskGroup list!");
3281 return;
3282 }
3283
Craig Mautnerf81b90872013-02-26 13:02:43 -08003284 int tokenNdx;
3285 int v;
3286 for (tokenNdx = localTokens.size() - 1, v = task.tokens.size() - 1;
3287 tokenNdx >= 0 && v >= 0; ) {
3288 final AppWindowToken atoken = localTokens.get(tokenNdx);
Craig Mautner343ad712013-02-13 22:37:26 -08003289 if (atoken.removed) {
Craig Mautnerf81b90872013-02-26 13:02:43 -08003290 --tokenNdx;
Craig Mautner343ad712013-02-13 22:37:26 -08003291 continue;
3292 }
3293 if (tokens.get(v) != atoken.token) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08003294 break;
Craig Mautner343ad712013-02-13 22:37:26 -08003295 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08003296 --tokenNdx;
Craig Mautner343ad712013-02-13 22:37:26 -08003297 v--;
3298 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08003299
3300 if (tokenNdx >= 0 || v >= 0) {
3301 break;
3302 }
Craig Mautner343ad712013-02-13 22:37:26 -08003303 }
3304
Craig Mautnerf81b90872013-02-26 13:02:43 -08003305 if (taskNdx >= 0 || t >= 0) {
Craig Mautner11bf9a52013-02-19 14:08:51 -08003306 Slog.w(TAG, "validateAppTokens: Mismatch! ActivityManager=" + tasks);
Craig Mautner1d001b62013-06-18 16:52:43 -07003307 Slog.w(TAG, "validateAppTokens: Mismatch! WindowManager=" + localTasks);
Craig Mautnerb44de0d2013-02-21 20:00:58 -08003308 Slog.w(TAG, "validateAppTokens: Mismatch! Callers=" + Debug.getCallers(4));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003309 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003310 }
3311 }
3312
Craig Mautner00af9fe2013-03-25 09:13:41 -07003313 public void validateStackOrder(Integer[] remoteStackIds) {
3314 // TODO:
3315 }
3316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003317 boolean checkCallingPermission(String permission, String func) {
3318 // Quick check: if the calling permission is me, it's all okay.
3319 if (Binder.getCallingPid() == Process.myPid()) {
3320 return true;
3321 }
Romain Guy06882f82009-06-10 13:36:04 -07003322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003323 if (mContext.checkCallingPermission(permission)
3324 == PackageManager.PERMISSION_GRANTED) {
3325 return true;
3326 }
3327 String msg = "Permission Denial: " + func + " from pid="
3328 + Binder.getCallingPid()
3329 + ", uid=" + Binder.getCallingUid()
3330 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003331 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003332 return false;
3333 }
Craig Mautner9e809442012-06-22 17:13:04 -07003334
Craig Mautner2fb98b12012-03-20 17:24:00 -07003335 boolean okToDisplay() {
3336 return !mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully();
3337 }
Romain Guy06882f82009-06-10 13:36:04 -07003338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003339 AppWindowToken findAppWindowToken(IBinder token) {
3340 WindowToken wtoken = mTokenMap.get(token);
3341 if (wtoken == null) {
3342 return null;
3343 }
3344 return wtoken.appWindowToken;
3345 }
Romain Guy06882f82009-06-10 13:36:04 -07003346
Craig Mautnercf8cbbe2012-03-25 21:54:36 -07003347 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003348 public void addWindowToken(IBinder token, int type) {
3349 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3350 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003351 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003352 }
Romain Guy06882f82009-06-10 13:36:04 -07003353
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003354 synchronized(mWindowMap) {
3355 WindowToken wtoken = mTokenMap.get(token);
3356 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003357 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003358 return;
3359 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003360 wtoken = new WindowToken(this, token, type, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003361 mTokenMap.put(token, wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003362 if (type == TYPE_WALLPAPER) {
3363 mWallpaperTokens.add(wtoken);
3364 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003365 }
3366 }
Romain Guy06882f82009-06-10 13:36:04 -07003367
Craig Mautner9e809442012-06-22 17:13:04 -07003368 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003369 public void removeWindowToken(IBinder token) {
3370 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3371 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003372 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003373 }
3374
3375 final long origId = Binder.clearCallingIdentity();
3376 synchronized(mWindowMap) {
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08003377 DisplayContent displayContent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003378 WindowToken wtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003379 if (wtoken != null) {
3380 boolean delayed = false;
3381 if (!wtoken.hidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003382 final int N = wtoken.windows.size();
3383 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003384
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003385 for (int i=0; i<N; i++) {
3386 WindowState win = wtoken.windows.get(i);
Craig Mautnerdf88d732014-01-27 09:21:32 -08003387 displayContent = win.getDisplayContent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003388
Craig Mautnera2c77052012-03-26 12:14:43 -07003389 if (win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003390 delayed = true;
3391 }
Romain Guy06882f82009-06-10 13:36:04 -07003392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003393 if (win.isVisibleNow()) {
Craig Mautner59c00972012-07-30 12:10:24 -07003394 win.mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT,
3395 false);
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003396 //TODO (multidisplay): Magnification is supported only for the default
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08003397 if (mDisplayMagnifier != null && win.isDefaultDisplay()) {
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003398 mDisplayMagnifier.onWindowTransitionLocked(win,
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07003399 WindowManagerPolicy.TRANSIT_EXIT);
3400 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003401 changed = true;
Craig Mautnerdf88d732014-01-27 09:21:32 -08003402 if (displayContent != null) {
3403 displayContent.layoutNeeded = true;
3404 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003405 }
3406 }
3407
Craig Mautner4b5aa782012-10-02 18:11:25 -07003408 wtoken.hidden = true;
3409
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003410 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003411 performLayoutAndPlaceSurfacesLocked();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003412 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
3413 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003414 }
Romain Guy06882f82009-06-10 13:36:04 -07003415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003416 if (delayed) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003417 if (displayContent != null) {
3418 displayContent.mExitingTokens.add(wtoken);
3419 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003420 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3421 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003422 }
3423 }
Romain Guy06882f82009-06-10 13:36:04 -07003424
Jeff Brown2e44b072011-01-24 15:21:56 -08003425 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003426 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003427 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003428 }
3429 }
3430 Binder.restoreCallingIdentity(origId);
3431 }
3432
Craig Mautner31482a72013-10-02 10:04:13 -07003433 private Task createTask(int taskId, int stackId, int userId, AppWindowToken atoken) {
Craig Mautner9ef471f2014-02-07 13:11:47 -08003434 if (DEBUG_STACK) Slog.i(TAG, "createTask: taskId=" + taskId + " stackId=" + stackId
3435 + " atoken=" + atoken);
Craig Mautner31482a72013-10-02 10:04:13 -07003436 final TaskStack stack = mStackIdToStack.get(stackId);
3437 if (stack == null) {
3438 throw new IllegalArgumentException("addAppToken: invalid stackId=" + stackId);
3439 }
Craig Mautner2c2549c2013-11-12 08:31:15 -08003440 EventLog.writeEvent(EventLogTags.WM_TASK_CREATED, taskId, stackId);
Craig Mautner31482a72013-10-02 10:04:13 -07003441 Task task = new Task(atoken, stack, userId);
Craig Mautner8e797342013-10-09 16:18:29 -07003442 mTaskIdToTask.put(taskId, task);
Craig Mautner31482a72013-10-02 10:04:13 -07003443 stack.addTask(task, true);
Craig Mautner31482a72013-10-02 10:04:13 -07003444 return task;
3445 }
3446
Craig Mautneref25d7a2012-05-15 23:01:47 -07003447 @Override
Craig Mautnerc00204b2013-03-05 15:02:14 -08003448 public void addAppToken(int addPos, IApplicationToken token, int taskId, int stackId,
Craig Mautner5d9f5472013-11-12 14:02:52 -08003449 int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId,
3450 int configChanges) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003451 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3452 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003453 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003454 }
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07003455
Jeff Brown349703e2010-06-22 01:27:15 -07003456 // Get the dispatching timeout here while we are not holding any locks so that it
3457 // can be cached by the AppWindowToken. The timeout value is used later by the
3458 // input dispatcher in code that does hold locks. If we did not cache the value
3459 // here we would run the chance of introducing a deadlock between the window manager
3460 // (which holds locks while updating the input dispatcher state) and the activity manager
3461 // (which holds locks while querying the application token).
3462 long inputDispatchingTimeoutNanos;
3463 try {
3464 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3465 } catch (RemoteException ex) {
3466 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3467 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3468 }
Romain Guy06882f82009-06-10 13:36:04 -07003469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003470 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003471 AppWindowToken atoken = findAppWindowToken(token.asBinder());
3472 if (atoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003473 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003474 return;
3475 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003476 atoken = new AppWindowToken(this, token);
3477 atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08003478 atoken.groupId = taskId;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003479 atoken.appFullscreen = fullscreen;
Craig Mautner5962b122012-10-05 14:45:52 -07003480 atoken.showWhenLocked = showWhenLocked;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003481 atoken.requestedOrientation = requestedOrientation;
Craig Mautner4c5eb222013-11-18 12:59:05 -08003482 atoken.layoutConfigChanges = (configChanges &
3483 (ActivityInfo.CONFIG_SCREEN_SIZE | ActivityInfo.CONFIG_ORIENTATION)) != 0;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003484 if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + atoken
Craig Mautnerac6f8432013-07-17 13:24:59 -07003485 + " to stack=" + stackId + " task=" + taskId + " at " + addPos);
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08003486
Craig Mautnerc00204b2013-03-05 15:02:14 -08003487 Task task = mTaskIdToTask.get(taskId);
3488 if (task == null) {
Craig Mautner31482a72013-10-02 10:04:13 -07003489 task = createTask(taskId, stackId, userId, atoken);
Craig Mautnerc00204b2013-03-05 15:02:14 -08003490 } else {
3491 task.addAppToken(addPos, atoken);
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08003492 }
Craig Mautnerc00204b2013-03-05 15:02:14 -08003493
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003494 mTokenMap.put(token.asBinder(), atoken);
Romain Guy06882f82009-06-10 13:36:04 -07003495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003496 // Application tokens start out hidden.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003497 atoken.hidden = true;
3498 atoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003500 //dump();
3501 }
3502 }
Romain Guy06882f82009-06-10 13:36:04 -07003503
Craig Mautner9e809442012-06-22 17:13:04 -07003504 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003505 public void setAppGroupId(IBinder token, int groupId) {
3506 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner6fbda632012-07-03 09:26:39 -07003507 "setAppGroupId()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003508 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003509 }
3510
3511 synchronized(mWindowMap) {
Craig Mautner32b44d02013-02-21 08:26:06 -08003512 final AppWindowToken atoken = findAppWindowToken(token);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003513 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003514 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003515 return;
3516 }
Craig Mautnerdf88d732014-01-27 09:21:32 -08003517 final Task oldTask = mTaskIdToTask.get(atoken.groupId);
Craig Mautner9ef471f2014-02-07 13:11:47 -08003518 removeAppFromTaskLocked(atoken);
Craig Mautnerc00204b2013-03-05 15:02:14 -08003519
3520 atoken.groupId = groupId;
3521 Task newTask = mTaskIdToTask.get(groupId);
3522 if (newTask == null) {
Craig Mautner31482a72013-10-02 10:04:13 -07003523 newTask = createTask(groupId, oldTask.mStack.mStackId, oldTask.mUserId, atoken);
Craig Mautner32b44d02013-02-21 08:26:06 -08003524 }
Craig Mautnerc00204b2013-03-05 15:02:14 -08003525 newTask.mAppTokens.add(atoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003526 }
3527 }
Romain Guy06882f82009-06-10 13:36:04 -07003528
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003529 public int getOrientationFromWindowsLocked() {
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003530 if (mDisplayFrozen || mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
3531 // If the display is frozen, some activities may be in the middle
3532 // of restarting, and thus have removed their old window. If the
3533 // window has the flag to hide the lock screen, then the lock screen
3534 // can re-appear and inflict its own orientation on us. Keep the
3535 // orientation stable until this all settles down.
3536 return mLastWindowForcedOrientation;
3537 }
3538
Craig Mautner59c00972012-07-30 12:10:24 -07003539 // TODO(multidisplay): Change to the correct display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003540 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07003541 int pos = windows.size() - 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003542 while (pos >= 0) {
Craig Mautnere8552142012-11-07 13:55:47 -08003543 WindowState win = windows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003544 pos--;
Craig Mautnere8552142012-11-07 13:55:47 -08003545 if (win.mAppToken != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003546 // We hit an application window. so the orientation will be determined by the
3547 // app window. No point in continuing further.
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003548 return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003549 }
Craig Mautnere8552142012-11-07 13:55:47 -08003550 if (!win.isVisibleLw() || !win.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003551 continue;
3552 }
Craig Mautnere8552142012-11-07 13:55:47 -08003553 int req = win.mAttrs.screenOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003554 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3555 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3556 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003557 }
Craig Mautner9e809442012-06-22 17:13:04 -07003558
Craig Mautnere8552142012-11-07 13:55:47 -08003559 if (DEBUG_ORIENTATION) Slog.v(TAG, win + " forcing orientation to " + req);
Craig Mautner9e809442012-06-22 17:13:04 -07003560 return (mLastWindowForcedOrientation=req);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003561 }
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003562 return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003563 }
Romain Guy06882f82009-06-10 13:36:04 -07003564
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003565 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003566 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3567 boolean findingBehind = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003568 boolean lastFullscreen = false;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08003569 // TODO: Multi window.
3570 DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautnerd9a22882013-03-16 15:00:36 -07003571 final ArrayList<Task> tasks = displayContent.getTasks();
Craig Mautnerf81b90872013-02-26 13:02:43 -08003572 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
3573 AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
Craig Mautnerd9a22882013-03-16 15:00:36 -07003574 final int firstToken = tokens.size() - 1;
3575 for (int tokenNdx = firstToken; tokenNdx >= 0; --tokenNdx) {
Craig Mautnerf81b90872013-02-26 13:02:43 -08003576 final AppWindowToken atoken = tokens.get(tokenNdx);
Craig Mautnerc5a6e442013-06-05 17:22:35 -07003577
Craig Mautnerf81b90872013-02-26 13:02:43 -08003578 if (DEBUG_APP_ORIENTATION) Slog.v(TAG, "Checking app orientation: " + atoken);
Craig Mautnerc5a6e442013-06-05 17:22:35 -07003579
Craig Mautnerf81b90872013-02-26 13:02:43 -08003580 // if we're about to tear down this window and not seek for
3581 // the behind activity, don't use it for orientation
3582 if (!findingBehind
3583 && (!atoken.hidden && atoken.hiddenRequested)) {
3584 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
3585 + " -- going to hide");
3586 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003587 }
Craig Mautnerc5a6e442013-06-05 17:22:35 -07003588
Craig Mautnerd9a22882013-03-16 15:00:36 -07003589 if (tokenNdx == firstToken) {
3590 // If we have hit a new Task, and the bottom
Craig Mautnerf81b90872013-02-26 13:02:43 -08003591 // of the previous group didn't explicitly say to use
3592 // the orientation behind it, and the last app was
3593 // full screen, then we'll stick with the
3594 // user's orientation.
3595 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3596 && lastFullscreen) {
3597 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
3598 + " -- end of group, return " + lastOrientation);
3599 return lastOrientation;
3600 }
3601 }
Craig Mautnerc5a6e442013-06-05 17:22:35 -07003602
Craig Mautnerf81b90872013-02-26 13:02:43 -08003603 // We ignore any hidden applications on the top.
3604 if (atoken.hiddenRequested || atoken.willBeHidden) {
3605 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
3606 + " -- hidden on top");
3607 continue;
3608 }
Craig Mautnerc5a6e442013-06-05 17:22:35 -07003609
Craig Mautnerd9a22882013-03-16 15:00:36 -07003610 if (tokenNdx == 0) {
3611 // Last token in this task.
Craig Mautnerf81b90872013-02-26 13:02:43 -08003612 lastOrientation = atoken.requestedOrientation;
3613 }
Craig Mautnerc5a6e442013-06-05 17:22:35 -07003614
Craig Mautnerf81b90872013-02-26 13:02:43 -08003615 int or = atoken.requestedOrientation;
3616 // If this application is fullscreen, and didn't explicitly say
3617 // to use the orientation behind it, then just take whatever
3618 // orientation it has and ignores whatever is under it.
3619 lastFullscreen = atoken.appFullscreen;
3620 if (lastFullscreen
3621 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3622 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
3623 + " -- full screen, return " + or);
3624 return or;
3625 }
3626 // If this application has requested an explicit orientation,
3627 // then use it.
3628 if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
3629 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3630 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
3631 + " -- explicitly set, return " + or);
3632 return or;
3633 }
3634 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003635 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003636 }
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003637 if (DEBUG_ORIENTATION) Slog.v(TAG, "No app is requesting an orientation");
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003638 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003639 }
Romain Guy06882f82009-06-10 13:36:04 -07003640
Craig Mautner711f90a2012-07-03 18:43:52 -07003641 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003642 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003643 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003644 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3645 "updateOrientationFromAppTokens()")) {
3646 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3647 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003648
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003649 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003650 long ident = Binder.clearCallingIdentity();
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003651
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003652 synchronized(mWindowMap) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003653 config = updateOrientationFromAppTokensLocked(currentConfig,
3654 freezeThisOneIfNeeded);
3655 }
3656
3657 Binder.restoreCallingIdentity(ident);
3658 return config;
3659 }
3660
3661 private Configuration updateOrientationFromAppTokensLocked(
3662 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
3663 Configuration config = null;
3664
3665 if (updateOrientationFromAppTokensLocked(false)) {
3666 if (freezeThisOneIfNeeded != null) {
Craig Mautner2268e7e2012-12-13 15:40:00 -08003667 AppWindowToken atoken = findAppWindowToken(freezeThisOneIfNeeded);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003668 if (atoken != null) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003669 startAppFreezingScreenLocked(atoken);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003670 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003671 }
3672 config = computeNewConfigurationLocked();
3673
3674 } else if (currentConfig != null) {
3675 // No obvious action we need to take, but if our current
3676 // state mismatches the activity manager's, update it,
3677 // disregarding font scale, which should remain set to
3678 // the value of the previous configuration.
3679 mTempConfiguration.setToDefaults();
3680 mTempConfiguration.fontScale = currentConfig.fontScale;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08003681 if (computeScreenConfigurationLocked(mTempConfiguration)) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003682 if (currentConfig.diff(mTempConfiguration) != 0) {
3683 mWaitingForConfig = true;
Craig Mautner05d29032013-05-03 13:40:13 -07003684 final DisplayContent displayContent = getDefaultDisplayContentLocked();
3685 displayContent.layoutNeeded = true;
Craig Mautner3c174372013-02-21 17:54:37 -08003686 int anim[] = new int[2];
Craig Mautner05d29032013-05-03 13:40:13 -07003687 if (displayContent.isDimming()) {
Craig Mautner3c174372013-02-21 17:54:37 -08003688 anim[0] = anim[1] = 0;
3689 } else {
3690 mPolicy.selectRotationAnimationLw(anim);
3691 }
3692 startFreezingDisplayLocked(false, anim[0], anim[1]);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003693 config = new Configuration(mTempConfiguration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003694 }
3695 }
3696 }
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003697
Dianne Hackborncfaef692009-06-15 14:24:44 -07003698 return config;
3699 }
3700
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003701 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003702 * Determine the new desired orientation of the display, returning
3703 * a non-null new Configuration if it has changed from the current
3704 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3705 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3706 * SCREEN. This will typically be done for you if you call
3707 * sendNewConfiguration().
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003708 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003709 * The orientation is computed from non-application windows first. If none of
3710 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003711 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003712 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3713 * android.os.IBinder)
3714 */
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003715 boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003716 long ident = Binder.clearCallingIdentity();
3717 try {
Craig Mautner2268e7e2012-12-13 15:40:00 -08003718 int req = getOrientationFromWindowsLocked();
3719 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3720 req = getOrientationFromAppTokensLocked();
3721 }
Romain Guy06882f82009-06-10 13:36:04 -07003722
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003723 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003724 mForcedAppOrientation = req;
3725 //send a message to Policy indicating orientation change to take
3726 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003727 mPolicy.setCurrentOrientationLw(req);
Jeff Brown01a98dd2011-09-20 15:08:29 -07003728 if (updateRotationUncheckedLocked(inTransaction)) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003729 // changed
3730 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003731 }
3732 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003733
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003734 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003735 } finally {
3736 Binder.restoreCallingIdentity(ident);
3737 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003738 }
Romain Guy06882f82009-06-10 13:36:04 -07003739
Craig Mautner918b53b2012-07-09 14:15:54 -07003740 @Override
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003741 public void setNewConfiguration(Configuration config) {
3742 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3743 "setNewConfiguration()")) {
3744 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3745 }
3746
3747 synchronized(mWindowMap) {
3748 mCurConfiguration = new Configuration(config);
Dianne Hackborna57c6952013-03-29 14:46:40 -07003749 if (mWaitingForConfig) {
3750 mWaitingForConfig = false;
3751 mLastFinishedFreezeSource = "new-config";
3752 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003753 performLayoutAndPlaceSurfacesLocked();
3754 }
3755 }
Craig Mautner918b53b2012-07-09 14:15:54 -07003756
3757 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003758 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3759 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3760 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003761 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003762 }
Romain Guy06882f82009-06-10 13:36:04 -07003763
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003764 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003765 AppWindowToken atoken = findAppWindowToken(token.asBinder());
3766 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003767 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003768 return;
3769 }
Romain Guy06882f82009-06-10 13:36:04 -07003770
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003771 atoken.requestedOrientation = requestedOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003772 }
3773 }
Romain Guy06882f82009-06-10 13:36:04 -07003774
Craig Mautner76a71652012-09-03 23:23:58 -07003775 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003776 public int getAppOrientation(IApplicationToken token) {
3777 synchronized(mWindowMap) {
3778 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3779 if (wtoken == null) {
3780 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3781 }
Romain Guy06882f82009-06-10 13:36:04 -07003782
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003783 return wtoken.requestedOrientation;
3784 }
3785 }
Romain Guy06882f82009-06-10 13:36:04 -07003786
Craig Mautnerf7666462013-04-28 08:58:21 -07003787 /** Call while in a Surface transaction. */
3788 void setFocusedStackLayer() {
3789 mFocusedStackLayer = 0;
Craig Mautner05d29032013-05-03 13:40:13 -07003790 if (mFocusedApp != null) {
3791 final WindowList windows = mFocusedApp.allAppWindows;
3792 for (int i = windows.size() - 1; i >= 0; --i) {
3793 final WindowState win = windows.get(i);
3794 final int animLayer = win.mWinAnimator.mAnimLayer;
3795 if (win.mAttachedWindow == null && win.isVisibleLw() &&
3796 animLayer > mFocusedStackLayer) {
3797 mFocusedStackLayer = animLayer + LAYER_OFFSET_FOCUSED_STACK;
3798 }
Craig Mautnerf7666462013-04-28 08:58:21 -07003799 }
3800 }
3801 if (DEBUG_LAYERS) Slog.v(TAG, "Setting FocusedStackFrame to layer=" +
3802 mFocusedStackLayer);
3803 mFocusedStackFrame.setLayer(mFocusedStackLayer);
3804 }
3805
3806 void setFocusedStackFrame() {
3807 final TaskStack stack;
3808 if (mFocusedApp != null) {
3809 Task task = mTaskIdToTask.get(mFocusedApp.groupId);
3810 stack = task.mStack;
Craig Mautnerdf88d732014-01-27 09:21:32 -08003811 final DisplayContent displayContent = task.getDisplayContent();
3812 if (displayContent != null) {
3813 displayContent.setTouchExcludeRegion(stack);
3814 }
Craig Mautnerf7666462013-04-28 08:58:21 -07003815 } else {
3816 stack = null;
3817 }
Craig Mautnera9a3fb12013-04-18 10:01:00 -07003818 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setFocusedStackFrame");
3819 SurfaceControl.openTransaction();
3820 try {
3821 if (stack == null) {
3822 mFocusedStackFrame.setVisibility(false);
3823 } else {
Craig Mautnerbdc748af2013-12-02 14:08:25 -08003824 mFocusedStackFrame.setBounds(stack);
3825 final boolean multipleStacks = !stack.isFullscreen();
Craig Mautnera9a3fb12013-04-18 10:01:00 -07003826 mFocusedStackFrame.setVisibility(multipleStacks);
3827 }
3828 } finally {
3829 SurfaceControl.closeTransaction();
3830 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> CLOSE TRANSACTION setFocusedStackFrame");
3831 }
3832 }
3833
Craig Mautner76a71652012-09-03 23:23:58 -07003834 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003835 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3836 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3837 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003838 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003839 }
3840
3841 synchronized(mWindowMap) {
3842 boolean changed = false;
3843 if (token == null) {
Craig Mautner58458122013-09-14 14:59:50 -07003844 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003845 changed = mFocusedApp != null;
3846 mFocusedApp = null;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003847 if (changed) {
3848 mInputMonitor.setFocusedAppLw(null);
Jeff Brown349703e2010-06-22 01:27:15 -07003849 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003850 } else {
3851 AppWindowToken newFocus = findAppWindowToken(token);
3852 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003853 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003854 return;
3855 }
3856 changed = mFocusedApp != newFocus;
Craig Mautner58458122013-09-14 14:59:50 -07003857 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Set focused app to: " + newFocus
3858 + " old focus=" + mFocusedApp + " moveFocusNow=" + moveFocusNow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003859 mFocusedApp = newFocus;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003860 if (changed) {
3861 mInputMonitor.setFocusedAppLw(newFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07003862 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003863 }
3864
3865 if (moveFocusNow && changed) {
3866 final long origId = Binder.clearCallingIdentity();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003867 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003868 Binder.restoreCallingIdentity(origId);
3869 }
3870 }
3871 }
3872
Craig Mautner76a71652012-09-03 23:23:58 -07003873 @Override
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003874 public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003875 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3876 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003877 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003878 }
Romain Guy06882f82009-06-10 13:36:04 -07003879
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003880 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003881 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003882 TAG, "Prepare app transition: transit=" + transit
Craig Mautner164d4bb2012-11-26 13:51:23 -08003883 + " " + mAppTransition
Craig Mautner1d961d42012-05-27 12:02:11 -07003884 + " alwaysKeepCurrent=" + alwaysKeepCurrent
Craig Mautneref25d7a2012-05-15 23:01:47 -07003885 + " Callers=" + Debug.getCallers(3));
Craig Mautner2fb98b12012-03-20 17:24:00 -07003886 if (okToDisplay()) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003887 if (!mAppTransition.isTransitionSet() || mAppTransition.isTransitionNone()) {
3888 mAppTransition.setAppTransition(transit);
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003889 } else if (!alwaysKeepCurrent) {
Craig Mautner4b71aa12012-12-27 17:20:01 -08003890 if (transit == AppTransition.TRANSIT_TASK_OPEN
Craig Mautner164d4bb2012-11-26 13:51:23 -08003891 && mAppTransition.isTransitionEqual(
Craig Mautner4b71aa12012-12-27 17:20:01 -08003892 AppTransition.TRANSIT_TASK_CLOSE)) {
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003893 // Opening a new task always supersedes a close for the anim.
Craig Mautner164d4bb2012-11-26 13:51:23 -08003894 mAppTransition.setAppTransition(transit);
Craig Mautner4b71aa12012-12-27 17:20:01 -08003895 } else if (transit == AppTransition.TRANSIT_ACTIVITY_OPEN
Craig Mautner164d4bb2012-11-26 13:51:23 -08003896 && mAppTransition.isTransitionEqual(
Craig Mautner4b71aa12012-12-27 17:20:01 -08003897 AppTransition.TRANSIT_ACTIVITY_CLOSE)) {
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003898 // Opening a new activity always supersedes a close for the anim.
Craig Mautner164d4bb2012-11-26 13:51:23 -08003899 mAppTransition.setAppTransition(transit);
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003900 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003901 }
Craig Mautner164d4bb2012-11-26 13:51:23 -08003902 mAppTransition.prepare();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003903 mStartingIconInTransition = false;
3904 mSkipAppTransitionAnimation = false;
3905 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
You Kimcb6291c2012-12-04 23:22:28 +09003906 mH.sendEmptyMessageDelayed(H.APP_TRANSITION_TIMEOUT, 5000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003907 }
3908 }
3909 }
3910
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003911 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003912 public int getPendingAppTransition() {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003913 return mAppTransition.getAppTransition();
Dianne Hackborn84375872012-06-01 19:03:50 -07003914 }
3915
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003916 @Override
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003917 public void overridePendingAppTransition(String packageName,
Dianne Hackborn84375872012-06-01 19:03:50 -07003918 int enterAnim, int exitAnim, IRemoteCallback startedCallback) {
3919 synchronized(mWindowMap) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003920 mAppTransition.overridePendingAppTransition(packageName, enterAnim, exitAnim,
3921 startedCallback);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003922 }
3923 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003924
Craig Mautnera91f9e22012-09-14 16:22:08 -07003925 @Override
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003926 public void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
3927 int startHeight) {
Dianne Hackborn84375872012-06-01 19:03:50 -07003928 synchronized(mWindowMap) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003929 mAppTransition.overridePendingAppTransitionScaleUp(startX, startY, startWidth,
3930 startHeight);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003931 }
3932 }
3933
Craig Mautnera91f9e22012-09-14 16:22:08 -07003934 @Override
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003935 public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX,
Michael Jurka832cb222012-04-13 09:32:47 -07003936 int startY, IRemoteCallback startedCallback, boolean scaleUp) {
Dianne Hackborn84375872012-06-01 19:03:50 -07003937 synchronized(mWindowMap) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003938 mAppTransition.overridePendingAppTransitionThumb(srcThumb, startX, startY,
3939 startedCallback, scaleUp);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003940 }
3941 }
3942
Craig Mautnera91f9e22012-09-14 16:22:08 -07003943 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003944 public void executeAppTransition() {
3945 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3946 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003947 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003948 }
Romain Guy06882f82009-06-10 13:36:04 -07003949
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003950 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003951 if (DEBUG_APP_TRANSITIONS) {
3952 RuntimeException e = new RuntimeException("here");
3953 e.fillInStackTrace();
Craig Mautner164d4bb2012-11-26 13:51:23 -08003954 Slog.w(TAG, "Execute app transition: " + mAppTransition, e);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003955 }
Craig Mautner164d4bb2012-11-26 13:51:23 -08003956 if (mAppTransition.isTransitionSet()) {
Craig Mautnerae446592012-12-06 19:05:05 -08003957 mAppTransition.setReady();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003958 final long origId = Binder.clearCallingIdentity();
3959 performLayoutAndPlaceSurfacesLocked();
3960 Binder.restoreCallingIdentity(origId);
3961 }
3962 }
3963 }
3964
Craig Mautnere6f7d5052012-10-08 10:34:17 -07003965 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003966 public void setAppStartingWindow(IBinder token, String pkg,
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07003967 int theme, CompatibilityInfo compatInfo,
Adam Powell04fe6eb2013-05-31 14:39:48 -07003968 CharSequence nonLocalizedLabel, int labelRes, int icon, int logo,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003969 int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003970 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner6fbda632012-07-03 09:26:39 -07003971 "setAppStartingWindow()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003972 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003973 }
3974
3975 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003976 if (DEBUG_STARTING_WINDOW) Slog.v(
Craig Mautner8863cca2012-09-18 15:04:34 -07003977 TAG, "setAppStartingWindow: token=" + token + " pkg=" + pkg
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003978 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003979
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003980 AppWindowToken wtoken = findAppWindowToken(token);
3981 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003982 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003983 return;
3984 }
3985
3986 // If the display is frozen, we won't do anything until the
3987 // actual window is displayed so there is no reason to put in
3988 // the starting window.
Craig Mautner2fb98b12012-03-20 17:24:00 -07003989 if (!okToDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003990 return;
3991 }
Romain Guy06882f82009-06-10 13:36:04 -07003992
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003993 if (wtoken.startingData != null) {
3994 return;
3995 }
Romain Guy06882f82009-06-10 13:36:04 -07003996
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003997 if (transferFrom != null) {
3998 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3999 if (ttoken != null) {
4000 WindowState startingWindow = ttoken.startingWindow;
4001 if (startingWindow != null) {
4002 if (mStartingIconInTransition) {
4003 // In this case, the starting icon has already
4004 // been displayed, so start letting windows get
4005 // shown immediately without any more transitions.
4006 mSkipAppTransitionAnimation = true;
4007 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004008 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
Craig Mautner8863cca2012-09-18 15:04:34 -07004009 "Moving existing starting " + startingWindow + " from " + ttoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004010 + " to " + wtoken);
4011 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07004012
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004013 // Transfer the starting window over to the new
4014 // token.
4015 wtoken.startingData = ttoken.startingData;
4016 wtoken.startingView = ttoken.startingView;
Craig Mautnerf4120952012-06-21 18:25:39 -07004017 wtoken.startingDisplayed = ttoken.startingDisplayed;
Craig Mautner8863cca2012-09-18 15:04:34 -07004018 ttoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004019 wtoken.startingWindow = startingWindow;
Craig Mautnerf4120952012-06-21 18:25:39 -07004020 wtoken.reportedVisible = ttoken.reportedVisible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004021 ttoken.startingData = null;
4022 ttoken.startingView = null;
4023 ttoken.startingWindow = null;
4024 ttoken.startingMoved = true;
4025 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07004026 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004027 startingWindow.mAppToken = wtoken;
Craig Mautner8863cca2012-09-18 15:04:34 -07004028 startingWindow.mWinAnimator.mAppAnimator = wtoken.mAppAnimator;
4029
Craig Mautner6fbda632012-07-03 09:26:39 -07004030 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) {
4031 Slog.v(TAG, "Removing starting window: " + startingWindow);
4032 }
Craig Mautner68cc2412013-10-01 10:39:43 -07004033 removeStartingWindowTimeout(ttoken);
Craig Mautner59c00972012-07-30 12:10:24 -07004034 startingWindow.getWindowList().remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004035 mWindowsChanged = true;
Craig Mautner6fbda632012-07-03 09:26:39 -07004036 if (DEBUG_ADD_REMOVE) Slog.v(TAG,
4037 "Removing starting " + startingWindow + " from " + ttoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004038 ttoken.windows.remove(startingWindow);
4039 ttoken.allAppWindows.remove(startingWindow);
4040 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07004041
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004042 // Propagate other interesting state between the
4043 // tokens. If the old token is displayed, we should
4044 // immediately force the new one to be displayed. If
4045 // it is animating, we need to move that animation to
4046 // the new one.
4047 if (ttoken.allDrawn) {
4048 wtoken.allDrawn = true;
Craig Mautner7636dfb2012-11-16 15:24:11 -08004049 wtoken.deferClearAllDrawn = ttoken.deferClearAllDrawn;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004050 }
4051 if (ttoken.firstWindowDrawn) {
4052 wtoken.firstWindowDrawn = true;
4053 }
4054 if (!ttoken.hidden) {
4055 wtoken.hidden = false;
4056 wtoken.hiddenRequested = false;
4057 wtoken.willBeHidden = false;
4058 }
4059 if (wtoken.clientHidden != ttoken.clientHidden) {
4060 wtoken.clientHidden = ttoken.clientHidden;
4061 wtoken.sendAppVisibilityToClients();
4062 }
Craig Mautner59431632012-04-04 11:56:44 -07004063 final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
4064 final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
4065 if (tAppAnimator.animation != null) {
4066 wAppAnimator.animation = tAppAnimator.animation;
4067 wAppAnimator.animating = tAppAnimator.animating;
4068 wAppAnimator.animLayerAdjustment = tAppAnimator.animLayerAdjustment;
4069 tAppAnimator.animation = null;
4070 tAppAnimator.animLayerAdjustment = 0;
4071 wAppAnimator.updateLayers();
4072 tAppAnimator.updateLayers();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004073 }
Romain Guy06882f82009-06-10 13:36:04 -07004074
Jeff Brown3a22cd92011-01-21 13:59:04 -08004075 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4076 true /*updateInputWindows*/);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07004077 getDefaultDisplayContentLocked().layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004078 performLayoutAndPlaceSurfacesLocked();
4079 Binder.restoreCallingIdentity(origId);
4080 return;
4081 } else if (ttoken.startingData != null) {
4082 // The previous app was getting ready to show a
4083 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004084 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004085 "Moving pending starting from " + ttoken
4086 + " to " + wtoken);
4087 wtoken.startingData = ttoken.startingData;
4088 ttoken.startingData = null;
4089 ttoken.startingMoved = true;
4090 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
4091 // Note: we really want to do sendMessageAtFrontOfQueue() because we
4092 // want to process the message ASAP, before any other queued
4093 // messages.
4094 mH.sendMessageAtFrontOfQueue(m);
4095 return;
4096 }
Craig Mautner59431632012-04-04 11:56:44 -07004097 final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
4098 final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
4099 if (tAppAnimator.thumbnail != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004100 // The old token is animating with a thumbnail, transfer
4101 // that to the new token.
Craig Mautner59431632012-04-04 11:56:44 -07004102 if (wAppAnimator.thumbnail != null) {
4103 wAppAnimator.thumbnail.destroy();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004104 }
Craig Mautner59431632012-04-04 11:56:44 -07004105 wAppAnimator.thumbnail = tAppAnimator.thumbnail;
4106 wAppAnimator.thumbnailX = tAppAnimator.thumbnailX;
4107 wAppAnimator.thumbnailY = tAppAnimator.thumbnailY;
4108 wAppAnimator.thumbnailLayer = tAppAnimator.thumbnailLayer;
4109 wAppAnimator.thumbnailAnimation = tAppAnimator.thumbnailAnimation;
4110 tAppAnimator.thumbnail = null;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004111 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004112 }
4113 }
4114
4115 // There is no existing starting window, and the caller doesn't
4116 // want us to create one, so that's it!
4117 if (!createIfNeeded) {
4118 return;
4119 }
Romain Guy06882f82009-06-10 13:36:04 -07004120
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08004121 // If this is a translucent window, then don't
Dianne Hackborn284ac932009-08-28 10:34:25 -07004122 // show a starting window -- the current effect (a full-screen
4123 // opaque starting window that fades away to the real contents
4124 // when it is ready) does not work for this.
Craig Mautner6fbda632012-07-03 09:26:39 -07004125 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Checking theme of starting window: 0x"
4126 + Integer.toHexString(theme));
Dianne Hackborn284ac932009-08-28 10:34:25 -07004127 if (theme != 0) {
4128 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
Amith Yamasani4befbec2013-07-10 16:18:01 -07004129 com.android.internal.R.styleable.Window, mCurrentUserId);
Dianne Hackborn0b800192012-06-21 15:29:36 -07004130 if (ent == null) {
4131 // Whoops! App doesn't exist. Um. Okay. We'll just
4132 // pretend like we didn't see that.
4133 return;
4134 }
Craig Mautner6fbda632012-07-03 09:26:39 -07004135 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Translucent="
4136 + ent.array.getBoolean(
4137 com.android.internal.R.styleable.Window_windowIsTranslucent, false)
4138 + " Floating="
4139 + ent.array.getBoolean(
4140 com.android.internal.R.styleable.Window_windowIsFloating, false)
4141 + " ShowWallpaper="
4142 + ent.array.getBoolean(
4143 com.android.internal.R.styleable.Window_windowShowWallpaper, false));
Dianne Hackborn284ac932009-08-28 10:34:25 -07004144 if (ent.array.getBoolean(
4145 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
4146 return;
4147 }
4148 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07004149 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
4150 return;
4151 }
4152 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07004153 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08004154 if (mWallpaperTarget == null) {
4155 // If this theme is requesting a wallpaper, and the wallpaper
4156 // is not curently visible, then this effectively serves as
4157 // an opaque window and our starting window transition animation
4158 // can still work. We just need to make sure the starting window
4159 // is also showing the wallpaper.
Craig Mautner65d11b32012-10-01 13:59:52 -07004160 windowFlags |= FLAG_SHOW_WALLPAPER;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08004161 } else {
4162 return;
4163 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07004164 }
4165 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004166
Craig Mautner6fbda632012-07-03 09:26:39 -07004167 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Creating StartingData");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004168 mStartingIconInTransition = true;
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07004169 wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
Adam Powell04fe6eb2013-05-31 14:39:48 -07004170 labelRes, icon, logo, windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004171 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
4172 // Note: we really want to do sendMessageAtFrontOfQueue() because we
4173 // want to process the message ASAP, before any other queued
4174 // messages.
Craig Mautner6fbda632012-07-03 09:26:39 -07004175 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Enqueueing ADD_STARTING");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004176 mH.sendMessageAtFrontOfQueue(m);
4177 }
4178 }
4179
Craig Mautner312eac42012-11-13 10:56:22 -08004180 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004181 public void setAppWillBeHidden(IBinder token) {
4182 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4183 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004184 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004185 }
4186
4187 AppWindowToken wtoken;
4188
4189 synchronized(mWindowMap) {
4190 wtoken = findAppWindowToken(token);
4191 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004192 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 -08004193 return;
4194 }
4195 wtoken.willBeHidden = true;
4196 }
4197 }
Romain Guy06882f82009-06-10 13:36:04 -07004198
Craig Mautner5eda9b32013-07-02 11:58:16 -07004199 public void setAppFullscreen(IBinder token, boolean toOpaque) {
Craig Mautner4addfc52013-06-25 08:05:45 -07004200 AppWindowToken atoken = findAppWindowToken(token);
4201 if (atoken != null) {
Craig Mautner5eda9b32013-07-02 11:58:16 -07004202 atoken.appFullscreen = toOpaque;
4203 requestTraversal();
Craig Mautner4addfc52013-06-25 08:05:45 -07004204 }
4205 }
4206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004207 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004208 boolean visible, int transit, boolean performLayout) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004209 boolean delayed = false;
4210
4211 if (wtoken.clientHidden == visible) {
4212 wtoken.clientHidden = !visible;
4213 wtoken.sendAppVisibilityToClients();
4214 }
Romain Guy06882f82009-06-10 13:36:04 -07004215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004216 wtoken.willBeHidden = false;
4217 if (wtoken.hidden == visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004218 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004219 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004220 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
4221 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07004222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004223 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07004224
Craig Mautner4b71aa12012-12-27 17:20:01 -08004225 if (transit != AppTransition.TRANSIT_UNSET) {
Craig Mautnerfbf378c2012-04-23 17:24:21 -07004226 if (wtoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) {
Craig Mautner59431632012-04-04 11:56:44 -07004227 wtoken.mAppAnimator.animation = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004228 }
Craig Mautnerf20588f2012-04-11 17:06:21 -07004229 if (applyAnimationLocked(wtoken, lp, transit, visible)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004230 delayed = runningAppAnimation = true;
4231 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07004232 WindowState window = wtoken.findMainWindow();
Svetoslav Ganov545252f2012-12-10 18:29:24 -08004233 //TODO (multidisplay): Magnification is supported only for the default display.
4234 if (window != null && mDisplayMagnifier != null
4235 && window.getDisplayId() == Display.DEFAULT_DISPLAY) {
Craig Mautner4b71aa12012-12-27 17:20:01 -08004236 mDisplayMagnifier.onAppWindowTransitionLocked(window, transit);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07004237 }
Craig Mautnerf20588f2012-04-11 17:06:21 -07004238 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004239 }
Romain Guy06882f82009-06-10 13:36:04 -07004240
Craig Mautnerf20588f2012-04-11 17:06:21 -07004241 final int N = wtoken.allAppWindows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004242 for (int i=0; i<N; i++) {
4243 WindowState win = wtoken.allAppWindows.get(i);
4244 if (win == wtoken.startingWindow) {
4245 continue;
4246 }
4247
Joe Onorato8a9b2202010-02-26 18:56:32 -08004248 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004249 //win.dump(" ");
4250 if (visible) {
4251 if (!win.isVisibleNow()) {
4252 if (!runningAppAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07004253 win.mWinAnimator.applyAnimationLocked(
4254 WindowManagerPolicy.TRANSIT_ENTER, true);
Svetoslav Ganov545252f2012-12-10 18:29:24 -08004255 //TODO (multidisplay): Magnification is supported only for the default
4256 if (mDisplayMagnifier != null
4257 && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
4258 mDisplayMagnifier.onWindowTransitionLocked(win,
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07004259 WindowManagerPolicy.TRANSIT_ENTER);
4260 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004261 }
4262 changed = true;
Craig Mautnerdf88d732014-01-27 09:21:32 -08004263 final DisplayContent displayContent = win.getDisplayContent();
4264 if (displayContent != null) {
4265 displayContent.layoutNeeded = true;
4266 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004267 }
4268 } else if (win.isVisibleNow()) {
4269 if (!runningAppAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07004270 win.mWinAnimator.applyAnimationLocked(
4271 WindowManagerPolicy.TRANSIT_EXIT, false);
Svetoslav Ganov545252f2012-12-10 18:29:24 -08004272 //TODO (multidisplay): Magnification is supported only for the default
4273 if (mDisplayMagnifier != null
4274 && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
4275 mDisplayMagnifier.onWindowTransitionLocked(win,
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07004276 WindowManagerPolicy.TRANSIT_EXIT);
4277 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004278 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004279 changed = true;
Craig Mautnerdf88d732014-01-27 09:21:32 -08004280 final DisplayContent displayContent = win.getDisplayContent();
4281 if (displayContent != null) {
4282 displayContent.layoutNeeded = true;
4283 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004284 }
4285 }
4286
4287 wtoken.hidden = wtoken.hiddenRequested = !visible;
4288 if (!visible) {
4289 unsetAppFreezingScreenLocked(wtoken, true, true);
4290 } else {
4291 // If we are being set visible, and the starting window is
4292 // not yet displayed, then make sure it doesn't get displayed.
4293 WindowState swin = wtoken.startingWindow;
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07004294 if (swin != null && !swin.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004295 swin.mPolicyVisibility = false;
4296 swin.mPolicyVisibilityAfterAnim = false;
4297 }
4298 }
Romain Guy06882f82009-06-10 13:36:04 -07004299
Joe Onorato8a9b2202010-02-26 18:56:32 -08004300 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004301 + ": hidden=" + wtoken.hidden + " hiddenRequested="
4302 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07004303
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004304 if (changed) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08004305 mInputMonitor.setUpdateInputWindowsNeededLw();
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004306 if (performLayout) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08004307 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4308 false /*updateInputWindows*/);
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004309 performLayoutAndPlaceSurfacesLocked();
4310 }
Jeff Brown2e44b072011-01-24 15:21:56 -08004311 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004312 }
4313 }
4314
Craig Mautner59431632012-04-04 11:56:44 -07004315 if (wtoken.mAppAnimator.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004316 delayed = true;
4317 }
Romain Guy06882f82009-06-10 13:36:04 -07004318
Craig Mautnerf20588f2012-04-11 17:06:21 -07004319 for (int i = wtoken.allAppWindows.size() - 1; i >= 0 && !delayed; i--) {
4320 if (wtoken.allAppWindows.get(i).mWinAnimator.isWindowAnimating()) {
4321 delayed = true;
4322 }
4323 }
4324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004325 return delayed;
4326 }
4327
Craig Mautner312eac42012-11-13 10:56:22 -08004328 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004329 public void setAppVisibility(IBinder token, boolean visible) {
4330 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4331 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004332 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004333 }
4334
4335 AppWindowToken wtoken;
4336
4337 synchronized(mWindowMap) {
4338 wtoken = findAppWindowToken(token);
4339 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004340 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004341 return;
4342 }
4343
4344 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004345 RuntimeException e = null;
4346 if (!HIDE_STACK_CRAWLS) {
4347 e = new RuntimeException();
4348 e.fillInStackTrace();
4349 }
Craig Mautner0afddcb2012-05-08 15:38:00 -07004350 Slog.v(TAG, "setAppVisibility(" + token + ", visible=" + visible
Craig Mautner164d4bb2012-11-26 13:51:23 -08004351 + "): " + mAppTransition
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004352 + " hidden=" + wtoken.hidden
4353 + " hiddenRequested=" + wtoken.hiddenRequested, e);
4354 }
Romain Guy06882f82009-06-10 13:36:04 -07004355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004356 // If we are preparing an app transition, then delay changing
4357 // the visibility of this token until we execute that transition.
Craig Mautner164d4bb2012-11-26 13:51:23 -08004358 if (okToDisplay() && mAppTransition.isTransitionSet()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004359 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07004360
Craig Mautnerf4120952012-06-21 18:25:39 -07004361 if (!wtoken.startingDisplayed) {
Craig Mautner8863cca2012-09-18 15:04:34 -07004362 if (DEBUG_APP_TRANSITIONS) Slog.v(
4363 TAG, "Setting dummy animation on: " + wtoken);
Craig Mautnerf4120952012-06-21 18:25:39 -07004364 wtoken.mAppAnimator.setDummyAnimation();
4365 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004366 mOpeningApps.remove(wtoken);
4367 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004368 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004369 wtoken.inPendingTransaction = true;
4370 if (visible) {
4371 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004372 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004373
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004374 // If the token is currently hidden (should be the
4375 // common case), then we need to set up to wait for
4376 // its windows to be ready.
4377 if (wtoken.hidden) {
4378 wtoken.allDrawn = false;
Craig Mautner7636dfb2012-11-16 15:24:11 -08004379 wtoken.deferClearAllDrawn = false;
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004380 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004381
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004382 if (wtoken.clientHidden) {
4383 // In the case where we are making an app visible
4384 // but holding off for a transition, we still need
4385 // to tell the client to make its windows visible so
4386 // they get drawn. Otherwise, we will wait on
4387 // performing the transition until all windows have
4388 // been drawn, they never will be, and we are sad.
4389 wtoken.clientHidden = false;
4390 wtoken.sendAppVisibilityToClients();
4391 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004392 }
4393 } else {
4394 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004395
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004396 // If the token is currently visible (should be the
4397 // common case), then set up to wait for it to be hidden.
4398 if (!wtoken.hidden) {
4399 wtoken.waitingToHide = true;
4400 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004401 }
4402 return;
4403 }
Romain Guy06882f82009-06-10 13:36:04 -07004404
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004405 final long origId = Binder.clearCallingIdentity();
Craig Mautner4b71aa12012-12-27 17:20:01 -08004406 setTokenVisibilityLocked(wtoken, null, visible, AppTransition.TRANSIT_UNSET,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004407 true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004408 wtoken.updateReportedVisibilityLocked();
4409 Binder.restoreCallingIdentity(origId);
4410 }
4411 }
4412
4413 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
4414 boolean unfreezeSurfaceNow, boolean force) {
Craig Mautner59431632012-04-04 11:56:44 -07004415 if (wtoken.mAppAnimator.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004416 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004417 + " force=" + force);
4418 final int N = wtoken.allAppWindows.size();
4419 boolean unfrozeWindows = false;
4420 for (int i=0; i<N; i++) {
4421 WindowState w = wtoken.allAppWindows.get(i);
4422 if (w.mAppFreezing) {
4423 w.mAppFreezing = false;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07004424 if (w.mHasSurface && !w.mOrientationChanging) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07004425 if (DEBUG_ORIENTATION) Slog.v(TAG, "set mOrientationChanging of " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004426 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07004427 mInnerFields.mOrientationChangeComplete = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004428 }
Dianne Hackborna57c6952013-03-29 14:46:40 -07004429 w.mLastFreezeDuration = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004430 unfrozeWindows = true;
Craig Mautnerdf88d732014-01-27 09:21:32 -08004431 final DisplayContent displayContent = w.getDisplayContent();
4432 if (displayContent != null) {
4433 displayContent.layoutNeeded = true;
4434 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004435 }
4436 }
4437 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004438 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
Craig Mautner59431632012-04-04 11:56:44 -07004439 wtoken.mAppAnimator.freezingScreen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07004440 wtoken.mAppAnimator.lastFreezeDuration = (int)(SystemClock.elapsedRealtime()
4441 - mDisplayFreezeTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004442 mAppsFreezingScreen--;
Dianne Hackborna57c6952013-03-29 14:46:40 -07004443 mLastFinishedFreezeSource = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004444 }
4445 if (unfreezeSurfaceNow) {
4446 if (unfrozeWindows) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004447 performLayoutAndPlaceSurfacesLocked();
4448 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004449 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004450 }
4451 }
4452 }
Romain Guy06882f82009-06-10 13:36:04 -07004453
Craig Mautner34b73df2014-01-12 21:11:08 -08004454 private void startAppFreezingScreenLocked(AppWindowToken wtoken) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004455 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004456 RuntimeException e = null;
4457 if (!HIDE_STACK_CRAWLS) {
4458 e = new RuntimeException();
4459 e.fillInStackTrace();
4460 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004461 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004462 + ": hidden=" + wtoken.hidden + " freezing="
Craig Mautner59431632012-04-04 11:56:44 -07004463 + wtoken.mAppAnimator.freezingScreen, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004464 }
4465 if (!wtoken.hiddenRequested) {
Craig Mautner59431632012-04-04 11:56:44 -07004466 if (!wtoken.mAppAnimator.freezingScreen) {
4467 wtoken.mAppAnimator.freezingScreen = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -07004468 wtoken.mAppAnimator.lastFreezeDuration = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004469 mAppsFreezingScreen++;
4470 if (mAppsFreezingScreen == 1) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07004471 startFreezingDisplayLocked(false, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004472 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
You Kimcb6291c2012-12-04 23:22:28 +09004473 mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 5000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004474 }
4475 }
4476 final int N = wtoken.allAppWindows.size();
4477 for (int i=0; i<N; i++) {
4478 WindowState w = wtoken.allAppWindows.get(i);
4479 w.mAppFreezing = true;
4480 }
4481 }
4482 }
Romain Guy06882f82009-06-10 13:36:04 -07004483
Craig Mautner312eac42012-11-13 10:56:22 -08004484 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004485 public void startAppFreezingScreen(IBinder token, int configChanges) {
4486 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4487 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004488 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004489 }
4490
4491 synchronized(mWindowMap) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07004492 if (configChanges == 0 && okToDisplay()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004493 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004494 return;
4495 }
Romain Guy06882f82009-06-10 13:36:04 -07004496
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004497 AppWindowToken wtoken = findAppWindowToken(token);
4498 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004499 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004500 return;
4501 }
4502 final long origId = Binder.clearCallingIdentity();
Craig Mautner34b73df2014-01-12 21:11:08 -08004503 startAppFreezingScreenLocked(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004504 Binder.restoreCallingIdentity(origId);
4505 }
4506 }
Romain Guy06882f82009-06-10 13:36:04 -07004507
Craig Mautner312eac42012-11-13 10:56:22 -08004508 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004509 public void stopAppFreezingScreen(IBinder token, boolean force) {
4510 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4511 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004512 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004513 }
4514
4515 synchronized(mWindowMap) {
4516 AppWindowToken wtoken = findAppWindowToken(token);
4517 if (wtoken == null || wtoken.appToken == null) {
4518 return;
4519 }
4520 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004521 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
Craig Mautner59431632012-04-04 11:56:44 -07004522 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.mAppAnimator.freezingScreen);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004523 unsetAppFreezingScreenLocked(wtoken, true, force);
4524 Binder.restoreCallingIdentity(origId);
4525 }
4526 }
Romain Guy06882f82009-06-10 13:36:04 -07004527
Craig Mautner9ef471f2014-02-07 13:11:47 -08004528 void removeAppFromTaskLocked(AppWindowToken wtoken) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08004529 final Task task = mTaskIdToTask.get(wtoken.groupId);
Craig Mautner9ef471f2014-02-07 13:11:47 -08004530 if (!wtoken.mDeferRemoval && task != null && task.removeAppToken(wtoken)) {
4531 removeTaskLocked(task);
Craig Mautnerdf88d732014-01-27 09:21:32 -08004532 }
4533 }
4534
Craig Mautnerae446592012-12-06 19:05:05 -08004535 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004536 public void removeAppToken(IBinder token) {
4537 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4538 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004539 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004540 }
4541
4542 AppWindowToken wtoken = null;
4543 AppWindowToken startingToken = null;
4544 boolean delayed = false;
4545
4546 final long origId = Binder.clearCallingIdentity();
4547 synchronized(mWindowMap) {
4548 WindowToken basewtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004549 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004550 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004551 delayed = setTokenVisibilityLocked(wtoken, null, false,
Craig Mautner4b71aa12012-12-27 17:20:01 -08004552 AppTransition.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004553 wtoken.inPendingTransaction = false;
4554 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004555 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004556 if (mClosingApps.contains(wtoken)) {
4557 delayed = true;
Craig Mautner164d4bb2012-11-26 13:51:23 -08004558 } else if (mAppTransition.isTransitionSet()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004559 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004560 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004561 delayed = true;
4562 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004563 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004564 TAG, "Removing app " + wtoken + " delayed=" + delayed
Craig Mautner59431632012-04-04 11:56:44 -07004565 + " animation=" + wtoken.mAppAnimator.animation
4566 + " animating=" + wtoken.mAppAnimator.animating);
Craig Mautnerdc548482014-02-05 13:35:24 -08004567 final TaskStack stack = mTaskIdToTask.get(wtoken.groupId).mStack;
4568 if (delayed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004569 // set the token aside because it has an active animation to be finished
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004570 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4571 "removeAppToken make exiting: " + wtoken);
Craig Mautnerdc548482014-02-05 13:35:24 -08004572 stack.mExitingAppTokens.add(wtoken);
Craig Mautner9ef471f2014-02-07 13:11:47 -08004573 wtoken.mDeferRemoval = true;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004574 } else {
4575 // Make sure there is no animation running on this token,
4576 // so any windows associated with it will be removed as
4577 // soon as their animations are complete
Craig Mautner59431632012-04-04 11:56:44 -07004578 wtoken.mAppAnimator.clearAnimation();
4579 wtoken.mAppAnimator.animating = false;
Craig Mautner9ef471f2014-02-07 13:11:47 -08004580 removeAppFromTaskLocked(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004581 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004582 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4583 "removeAppToken: " + wtoken);
Craig Mautnerc00204b2013-03-05 15:02:14 -08004584
Craig Mautnerdf88d732014-01-27 09:21:32 -08004585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004586 wtoken.removed = true;
4587 if (wtoken.startingData != null) {
4588 startingToken = wtoken;
4589 }
4590 unsetAppFreezingScreenLocked(wtoken, true, true);
4591 if (mFocusedApp == wtoken) {
Craig Mautner58458122013-09-14 14:59:50 -07004592 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004593 mFocusedApp = null;
Jeff Brown3a22cd92011-01-21 13:59:04 -08004594 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004595 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004596 }
4597 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004598 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004599 }
Romain Guy06882f82009-06-10 13:36:04 -07004600
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004601 if (!delayed && wtoken != null) {
4602 wtoken.updateReportedVisibilityLocked();
4603 }
4604 }
4605 Binder.restoreCallingIdentity(origId);
4606
Craig Mautner68cc2412013-10-01 10:39:43 -07004607 // Will only remove if startingToken non null.
4608 scheduleRemoveStartingWindow(startingToken);
4609 }
4610
4611 void removeStartingWindowTimeout(AppWindowToken wtoken) {
4612 if (wtoken != null) {
4613 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, Debug.getCallers(1) +
4614 ": Remove starting window timeout " + wtoken + (wtoken != null ?
4615 " startingWindow=" + wtoken.startingWindow : ""));
4616 mH.removeMessages(H.REMOVE_STARTING_TIMEOUT, wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004617 }
4618 }
4619
Craig Mautner68cc2412013-10-01 10:39:43 -07004620 void scheduleRemoveStartingWindow(AppWindowToken wtoken) {
4621 if (wtoken != null && wtoken.startingWindow != null) {
4622 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, Debug.getCallers(1) +
4623 ": Schedule remove starting " + wtoken + (wtoken != null ?
4624 " startingWindow=" + wtoken.startingWindow : ""));
4625 removeStartingWindowTimeout(wtoken);
4626 Message m = mH.obtainMessage(H.REMOVE_STARTING, wtoken);
4627 mH.sendMessage(m);
4628 }
4629 }
Craig Mautnerdf88d732014-01-27 09:21:32 -08004630
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004631 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08004632 WindowList windows = token.windows;
4633 final int NW = windows.size();
Craig Mautneref25d7a2012-05-15 23:01:47 -07004634 if (NW > 0) {
4635 mWindowsChanged = true;
4636 }
Craig Mautnerdf88d732014-01-27 09:21:32 -08004637 for (int i = 0; i < NW; i++) {
4638 WindowState win = windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004639 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
Craig Mautner59c00972012-07-30 12:10:24 -07004640 win.getWindowList().remove(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004641 int j = win.mChildWindows.size();
4642 while (j > 0) {
4643 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004644 WindowState cwin = win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004645 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004646 "Tmp removing child window " + cwin);
Craig Mautner59c00972012-07-30 12:10:24 -07004647 cwin.getWindowList().remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004648 }
4649 }
4650 return NW > 0;
4651 }
4652
4653 void dumpAppTokensLocked() {
Craig Mautnerdc548482014-02-05 13:35:24 -08004654 final int numStacks = mStackIdToStack.size();
4655 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
4656 final TaskStack stack = mStackIdToStack.valueAt(stackNdx);
4657 Slog.v(TAG, " Stack #" + stack.mStackId + " tasks from bottom to top:");
4658 final ArrayList<Task> tasks = stack.getTasks();
4659 final int numTasks = tasks.size();
4660 for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
4661 final Task task = tasks.get(taskNdx);
4662 Slog.v(TAG, " Task #" + task.taskId + " activities from bottom to top:");
4663 AppTokenList tokens = task.mAppTokens;
4664 final int numTokens = tokens.size();
4665 for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
4666 Slog.v(TAG, " activity #" + tokenNdx + ": " + tokens.get(tokenNdx).token);
Craig Mautnerf81b90872013-02-26 13:02:43 -08004667 }
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08004668 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004669 }
4670 }
Romain Guy06882f82009-06-10 13:36:04 -07004671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004672 void dumpWindowsLocked() {
Craig Mautnerf8924152013-07-16 09:10:55 -07004673 final int numDisplays = mDisplayContents.size();
4674 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08004675 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
4676 Slog.v(TAG, " Display #" + displayContent.getDisplayId());
4677 final WindowList windows = displayContent.getWindowList();
Craig Mautnerf8924152013-07-16 09:10:55 -07004678 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08004679 Slog.v(TAG, " #" + winNdx + ": " + windows.get(winNdx));
Craig Mautnerf8924152013-07-16 09:10:55 -07004680 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004681 }
4682 }
Romain Guy06882f82009-06-10 13:36:04 -07004683
Craig Mautner926f3832013-02-13 11:56:07 -08004684 private int findAppWindowInsertionPointLocked(AppWindowToken target) {
4685 final int taskId = target.groupId;
Craig Mautnerc00204b2013-03-05 15:02:14 -08004686 Task targetTask = mTaskIdToTask.get(taskId);
4687 if (targetTask == null) {
4688 Slog.w(TAG, "findAppWindowInsertionPointLocked: no Task for " + target + " taskId="
4689 + taskId);
4690 return 0;
4691 }
4692 DisplayContent displayContent = targetTask.getDisplayContent();
Craig Mautner926f3832013-02-13 11:56:07 -08004693 if (displayContent == null) {
Craig Mautnerc00204b2013-03-05 15:02:14 -08004694 Slog.w(TAG, "findAppWindowInsertionPointLocked: no DisplayContent for " + target);
Craig Mautner926f3832013-02-13 11:56:07 -08004695 return 0;
4696 }
4697 final WindowList windows = displayContent.getWindowList();
4698 final int NW = windows.size();
4699
Craig Mautnerf81b90872013-02-26 13:02:43 -08004700 boolean found = false;
Craig Mautnerc00204b2013-03-05 15:02:14 -08004701 final ArrayList<Task> tasks = displayContent.getTasks();
Craig Mautnerf81b90872013-02-26 13:02:43 -08004702 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
Craig Mautnerc00204b2013-03-05 15:02:14 -08004703 final Task task = tasks.get(taskNdx);
Craig Mautnerf81b90872013-02-26 13:02:43 -08004704 if (!found && task.taskId != taskId) {
Craig Mautner926f3832013-02-13 11:56:07 -08004705 continue;
4706 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08004707 AppTokenList tokens = task.mAppTokens;
4708 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
4709 final AppWindowToken wtoken = tokens.get(tokenNdx);
4710 if (!found && wtoken == target) {
4711 found = true;
4712 }
4713 if (found) {
4714 // Find the first app token below the new position that has
4715 // a window displayed.
4716 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows in " + wtoken.token);
4717 if (wtoken.sendingToBottom) {
4718 if (DEBUG_REORDER) Slog.v(TAG, "Skipping token -- currently sending to bottom");
4719 continue;
4720 }
4721 for (int i = wtoken.windows.size() - 1; i >= 0; --i) {
4722 WindowState win = wtoken.windows.get(i);
4723 for (int j = win.mChildWindows.size() - 1; j >= 0; --j) {
4724 WindowState cwin = win.mChildWindows.get(j);
4725 if (cwin.mSubLayer >= 0) {
4726 for (int pos = NW - 1; pos >= 0; pos--) {
4727 if (windows.get(pos) == cwin) {
4728 if (DEBUG_REORDER) Slog.v(TAG,
4729 "Found child win @" + (pos + 1));
4730 return pos + 1;
4731 }
4732 }
4733 }
4734 }
Craig Mautner926f3832013-02-13 11:56:07 -08004735 for (int pos = NW - 1; pos >= 0; pos--) {
Craig Mautnerf81b90872013-02-26 13:02:43 -08004736 if (windows.get(pos) == win) {
4737 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos + 1));
Craig Mautner926f3832013-02-13 11:56:07 -08004738 return pos + 1;
4739 }
4740 }
4741 }
4742 }
Craig Mautner926f3832013-02-13 11:56:07 -08004743 }
4744 }
Craig Mautner7c495cb2013-10-13 23:19:45 +00004745 // Never put an app window underneath wallpaper.
4746 for (int pos = NW - 1; pos >= 0; pos--) {
4747 if (windows.get(pos).mIsWallpaper) {
4748 if (DEBUG_REORDER) Slog.v(TAG, "Found wallpaper @" + pos);
4749 return pos + 1;
4750 }
4751 }
Craig Mautner926f3832013-02-13 11:56:07 -08004752 return 0;
4753 }
4754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004755 private final int reAddWindowLocked(int index, WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -07004756 final WindowList windows = win.getWindowList();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004757 final int NCW = win.mChildWindows.size();
4758 boolean added = false;
4759 for (int j=0; j<NCW; j++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004760 WindowState cwin = win.mChildWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004761 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004762 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004763 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004764 win.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004765 windows.add(index, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004766 index++;
4767 added = true;
4768 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004769 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004770 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004771 cwin.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004772 windows.add(index, cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004773 index++;
4774 }
4775 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004776 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004777 + index + ": " + win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004778 win.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004779 windows.add(index, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004780 index++;
4781 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004782 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004783 return index;
4784 }
Romain Guy06882f82009-06-10 13:36:04 -07004785
Craig Mautner59c00972012-07-30 12:10:24 -07004786 private final int reAddAppWindowsLocked(final DisplayContent displayContent, int index,
4787 WindowToken token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004788 final int NW = token.windows.size();
4789 for (int i=0; i<NW; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07004790 final WindowState win = token.windows.get(i);
Craig Mautnerdf88d732014-01-27 09:21:32 -08004791 final DisplayContent winDisplayContent = win.getDisplayContent();
4792 if (winDisplayContent == displayContent || winDisplayContent == null) {
4793 win.mDisplayContent = displayContent;
Craig Mautner69b08182012-09-05 13:07:13 -07004794 index = reAddWindowLocked(index, win);
Craig Mautner59c00972012-07-30 12:10:24 -07004795 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004796 }
4797 return index;
4798 }
4799
Craig Mautnerdf88d732014-01-27 09:21:32 -08004800 void tmpRemoveTaskWindowsLocked(Task task) {
4801 AppTokenList tokens = task.mAppTokens;
4802 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
4803 tmpRemoveAppWindowsLocked(tokens.get(tokenNdx));
4804 }
4805 }
4806
Craig Mautner77df2ee2013-10-24 12:47:07 -07004807 void moveStackWindowsLocked(DisplayContent displayContent) {
Craig Mautner926f3832013-02-13 11:56:07 -08004808 // First remove all of the windows from the list.
Craig Mautner77df2ee2013-10-24 12:47:07 -07004809 final ArrayList<Task> tasks = displayContent.getTasks();
Craig Mautner5457e612013-05-10 16:25:02 -07004810 final int numTasks = tasks.size();
4811 for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08004812 tmpRemoveTaskWindowsLocked(tasks.get(taskNdx));
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004813 }
Craig Mautner926f3832013-02-13 11:56:07 -08004814
4815 // And now add them back at the correct place.
4816 // Where to start adding?
Craig Mautner5457e612013-05-10 16:25:02 -07004817 for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
4818 AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
4819 int pos = findAppWindowInsertionPointLocked(tokens.get(0));
4820 final int numTokens = tokens.size();
4821 for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
4822 final AppWindowToken wtoken = tokens.get(tokenNdx);
4823 if (wtoken != null) {
4824 final int newPos = reAddAppWindowsLocked(displayContent, pos, wtoken);
4825 if (newPos != pos) {
4826 displayContent.layoutNeeded = true;
4827 }
4828 pos = newPos;
Craig Mautner926f3832013-02-13 11:56:07 -08004829 }
Craig Mautner926f3832013-02-13 11:56:07 -08004830 }
4831 }
Craig Mautner5457e612013-05-10 16:25:02 -07004832
Craig Mautner926f3832013-02-13 11:56:07 -08004833 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
Craig Mautnercf910b02013-04-23 11:23:27 -07004834 false /*updateInputWindows*/)) {
Craig Mautner926f3832013-02-13 11:56:07 -08004835 assignLayersLocked(displayContent.getWindowList());
4836 }
4837
Craig Mautner926f3832013-02-13 11:56:07 -08004838 mInputMonitor.setUpdateInputWindowsNeededLw();
4839 performLayoutAndPlaceSurfacesLocked();
4840 mInputMonitor.updateInputWindowsLw(false /*force*/);
4841
4842 //dump();
4843 }
4844
4845 public void moveTaskToTop(int taskId) {
4846 final long origId = Binder.clearCallingIdentity();
4847 try {
4848 synchronized(mWindowMap) {
Craig Mautnerc00204b2013-03-05 15:02:14 -08004849 Task task = mTaskIdToTask.get(taskId);
4850 if (task == null) {
Craig Mautner31482a72013-10-02 10:04:13 -07004851 // Normal behavior, addAppToken will be called next and task will be created.
Craig Mautnerc00204b2013-03-05 15:02:14 -08004852 return;
4853 }
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -07004854 final TaskStack stack = task.mStack;
4855 final DisplayContent displayContent = task.getDisplayContent();
Craig Mautnerbdc748af2013-12-02 14:08:25 -08004856 displayContent.moveStack(stack, true);
Craig Mautnere0a38842013-12-16 16:14:02 -08004857 if (displayContent.isDefaultDisplay) {
4858 final TaskStack homeStack = displayContent.getHomeStack();
4859 if (homeStack != stack) {
4860 // When a non-home stack moves to the top, the home stack moves to the
4861 // bottom.
4862 displayContent.moveStack(homeStack, false);
4863 }
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -07004864 }
4865 stack.moveTaskToTop(task);
Craig Mautner926f3832013-02-13 11:56:07 -08004866 }
4867 } finally {
4868 Binder.restoreCallingIdentity(origId);
4869 }
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004870 }
4871
4872 public void moveTaskToBottom(int taskId) {
Craig Mautner926f3832013-02-13 11:56:07 -08004873 final long origId = Binder.clearCallingIdentity();
4874 try {
4875 synchronized(mWindowMap) {
Craig Mautnerc00204b2013-03-05 15:02:14 -08004876 Task task = mTaskIdToTask.get(taskId);
4877 if (task == null) {
Craig Mautner926f3832013-02-13 11:56:07 -08004878 Slog.e(TAG, "moveTaskToBottom: taskId=" + taskId
Craig Mautnerc00204b2013-03-05 15:02:14 -08004879 + " not found in mTaskIdToTask");
Craig Mautner926f3832013-02-13 11:56:07 -08004880 return;
4881 }
Craig Mautner5457e612013-05-10 16:25:02 -07004882 final TaskStack stack = task.mStack;
4883 stack.moveTaskToBottom(task);
Craig Mautner77df2ee2013-10-24 12:47:07 -07004884 moveStackWindowsLocked(stack.getDisplayContent());
Craig Mautner926f3832013-02-13 11:56:07 -08004885 }
4886 } finally {
4887 Binder.restoreCallingIdentity(origId);
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004888 }
Craig Mautner05d6272ba2013-02-11 09:39:27 -08004889 }
4890
Craig Mautnerc00204b2013-03-05 15:02:14 -08004891 /**
Craig Mautnerad25fa32014-01-12 21:19:06 -08004892 * Create a new TaskStack and place it on a DisplayContent.
Craig Mautnerc00204b2013-03-05 15:02:14 -08004893 * @param stackId The unique identifier of the new stack.
Craig Mautnerad25fa32014-01-12 21:19:06 -08004894 * @param displayId The unique identifier of the DisplayContent.
Craig Mautnerc00204b2013-03-05 15:02:14 -08004895 */
Craig Mautnerdf88d732014-01-27 09:21:32 -08004896 public void attachStack(int stackId, int displayId) {
Craig Mautner4504de52013-12-20 09:06:56 -08004897 final long origId = Binder.clearCallingIdentity();
4898 try {
4899 synchronized (mWindowMap) {
Craig Mautnerad25fa32014-01-12 21:19:06 -08004900 final DisplayContent displayContent = mDisplayContents.get(displayId);
4901 if (displayContent != null) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08004902 TaskStack stack = mStackIdToStack.get(stackId);
4903 if (stack == null) {
4904 if (DEBUG_STACK) Slog.d(TAG, "attachStack: stackId=" + stackId);
4905 stack = new TaskStack(this, stackId);
4906 mStackIdToStack.put(stackId, stack);
4907 }
4908 stack.attachDisplayContent(displayContent);
4909 displayContent.attachStack(stack);
4910 moveStackWindowsLocked(displayContent);
4911 final WindowList windows = displayContent.getWindowList();
4912 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
4913 windows.get(winNdx).reportResized();
4914 }
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07004915 }
Craig Mautner967212c2013-04-13 21:10:58 -07004916 }
Craig Mautner4504de52013-12-20 09:06:56 -08004917 } finally {
4918 Binder.restoreCallingIdentity(origId);
Craig Mautnerc00204b2013-03-05 15:02:14 -08004919 }
4920 }
4921
Craig Mautnerdf88d732014-01-27 09:21:32 -08004922 public void detachStack(int stackId) {
4923 synchronized (mWindowMap) {
4924 TaskStack stack = mStackIdToStack.get(stackId);
4925 if (stack != null) {
4926 final DisplayContent displayContent = stack.getDisplayContent();
4927 if (displayContent != null) {
Craig Mautner1bf2b872014-02-05 15:37:40 -08004928 if (stack.isAnimating()) {
4929 displayContent.mDeferredActions |= DisplayContent.DEFER_DETACH;
4930 return;
4931 }
Craig Mautnerdf88d732014-01-27 09:21:32 -08004932 displayContent.detachStack(stack);
Craig Mautnerdc548482014-02-05 13:35:24 -08004933 stack.detachDisplay();
Craig Mautnerdf88d732014-01-27 09:21:32 -08004934 }
4935 }
4936 }
4937 }
4938
Craig Mautner9ef471f2014-02-07 13:11:47 -08004939 void removeTaskLocked(Task task) {
4940 final int taskId = task.taskId;
4941 final TaskStack stack = task.mStack;
4942 if (stack.isAnimating()) {
4943 if (DEBUG_STACK) Slog.i(TAG, "removeTask: deferring removing taskId=" + taskId);
4944 task.mDeferRemoval = true;
4945 return;
4946 }
4947 if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing taskId=" + taskId);
4948 EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, taskId, "removeTask");
4949 task.mDeferRemoval = false;
4950 task.mStack.removeTask(task);
4951 mTaskIdToTask.delete(task.taskId);
4952 }
4953
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07004954 public void removeTask(int taskId) {
Craig Mautnerc00204b2013-03-05 15:02:14 -08004955 synchronized (mWindowMap) {
4956 Task task = mTaskIdToTask.get(taskId);
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07004957 if (task == null) {
Craig Mautner1d001b62013-06-18 16:52:43 -07004958 if (DEBUG_STACK) Slog.i(TAG, "removeTask: could not find taskId=" + taskId);
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07004959 return;
4960 }
Craig Mautner9ef471f2014-02-07 13:11:47 -08004961 removeTaskLocked(task);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07004962 }
4963 }
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07004964
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07004965 public void addTask(int taskId, int stackId, boolean toTop) {
4966 synchronized (mWindowMap) {
Craig Mautner9ef471f2014-02-07 13:11:47 -08004967 if (DEBUG_STACK) Slog.i(TAG, "addTask: adding taskId=" + taskId
4968 + " to " + (toTop ? "top" : "bottom"));
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07004969 Task task = mTaskIdToTask.get(taskId);
4970 if (task == null) {
4971 return;
4972 }
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07004973 TaskStack stack = mStackIdToStack.get(stackId);
4974 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07004975 final DisplayContent displayContent = stack.getDisplayContent();
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07004976 displayContent.layoutNeeded = true;
Craig Mautnerc00204b2013-03-05 15:02:14 -08004977 performLayoutAndPlaceSurfacesLocked();
4978 }
4979 }
4980
Craig Mautnerbdc748af2013-12-02 14:08:25 -08004981 public void resizeStack(int stackId, Rect bounds) {
Craig Mautnerc00204b2013-03-05 15:02:14 -08004982 synchronized (mWindowMap) {
Craig Mautnerbdc748af2013-12-02 14:08:25 -08004983 final TaskStack stack = mStackIdToStack.get(stackId);
4984 if (stack == null) {
4985 throw new IllegalArgumentException("resizeStack: stackId " + stackId
4986 + " not found.");
Craig Mautnerc00204b2013-03-05 15:02:14 -08004987 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08004988 if (stack.setBounds(bounds)) {
4989 stack.getDisplayContent().layoutNeeded = true;
4990 performLayoutAndPlaceSurfacesLocked();
4991 }
Craig Mautner5ff12102013-05-24 12:50:15 -07004992 }
4993 }
4994
Craig Mautnerbdc748af2013-12-02 14:08:25 -08004995 public void getStackBounds(int stackId, Rect bounds) {
4996 final TaskStack stack = mStackIdToStack.get(stackId);
4997 if (stack != null) {
4998 stack.getBounds(bounds);
4999 return;
Craig Mautner967212c2013-04-13 21:10:58 -07005000 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08005001 bounds.setEmpty();
Craig Mautner967212c2013-04-13 21:10:58 -07005002 }
5003
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005004 // -------------------------------------------------------------
5005 // Misc IWindowSession methods
5006 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07005007
Craig Mautner5642a482012-08-23 12:16:53 -07005008 @Override
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07005009 public void startFreezingScreen(int exitAnim, int enterAnim) {
5010 if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
5011 "startFreezingScreen()")) {
5012 throw new SecurityException("Requires FREEZE_SCREEN permission");
5013 }
5014
5015 synchronized(mWindowMap) {
5016 if (!mClientFreezingScreen) {
5017 mClientFreezingScreen = true;
5018 final long origId = Binder.clearCallingIdentity();
5019 try {
5020 startFreezingDisplayLocked(false, exitAnim, enterAnim);
5021 mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
You Kimcb6291c2012-12-04 23:22:28 +09005022 mH.sendEmptyMessageDelayed(H.CLIENT_FREEZE_TIMEOUT, 5000);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07005023 } finally {
5024 Binder.restoreCallingIdentity(origId);
5025 }
5026 }
5027 }
5028 }
5029
5030 @Override
5031 public void stopFreezingScreen() {
5032 if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
5033 "stopFreezingScreen()")) {
5034 throw new SecurityException("Requires FREEZE_SCREEN permission");
5035 }
5036
5037 synchronized(mWindowMap) {
5038 if (mClientFreezingScreen) {
5039 mClientFreezingScreen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07005040 mLastFinishedFreezeSource = "client";
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07005041 final long origId = Binder.clearCallingIdentity();
5042 try {
5043 stopFreezingDisplayLocked();
5044 } finally {
5045 Binder.restoreCallingIdentity(origId);
5046 }
5047 }
5048 }
5049 }
5050
5051 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005052 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04005053 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005054 != PackageManager.PERMISSION_GRANTED) {
5055 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5056 }
Jim Millerd6b57052010-06-07 17:52:42 -07005057
Craig Mautner5642a482012-08-23 12:16:53 -07005058 mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage(
5059 KeyguardDisableHandler.KEYGUARD_DISABLE, new Pair<IBinder, String>(token, tag)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005060 }
5061
Craig Mautner5642a482012-08-23 12:16:53 -07005062 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005063 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04005064 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005065 != PackageManager.PERMISSION_GRANTED) {
5066 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5067 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005068
Craig Mautner5642a482012-08-23 12:16:53 -07005069 mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage(
5070 KeyguardDisableHandler.KEYGUARD_REENABLE, token));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005071 }
5072
5073 /**
5074 * @see android.app.KeyguardManager#exitKeyguardSecurely
5075 */
Craig Mautner2268e7e2012-12-13 15:40:00 -08005076 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005077 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04005078 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005079 != PackageManager.PERMISSION_GRANTED) {
5080 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5081 }
5082 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
Craig Mautner2268e7e2012-12-13 15:40:00 -08005083 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005084 public void onKeyguardExitResult(boolean success) {
5085 try {
5086 callback.onKeyguardExitResult(success);
5087 } catch (RemoteException e) {
5088 // Client has died, we don't care.
5089 }
5090 }
5091 });
5092 }
5093
Craig Mautner2268e7e2012-12-13 15:40:00 -08005094 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005095 public boolean inKeyguardRestrictedInputMode() {
5096 return mPolicy.inKeyguardRestrictedKeyInputMode();
5097 }
Romain Guy06882f82009-06-10 13:36:04 -07005098
Craig Mautner2268e7e2012-12-13 15:40:00 -08005099 @Override
Mike Lockwood520d8bc2011-02-18 13:23:13 -05005100 public boolean isKeyguardLocked() {
5101 return mPolicy.isKeyguardLocked();
5102 }
5103
Craig Mautner2268e7e2012-12-13 15:40:00 -08005104 @Override
Mike Lockwood520d8bc2011-02-18 13:23:13 -05005105 public boolean isKeyguardSecure() {
5106 return mPolicy.isKeyguardSecure();
5107 }
5108
Craig Mautner2268e7e2012-12-13 15:40:00 -08005109 @Override
Dianne Hackborn90c52de2011-09-23 12:57:44 -07005110 public void dismissKeyguard() {
5111 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
5112 != PackageManager.PERMISSION_GRANTED) {
5113 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5114 }
5115 synchronized(mWindowMap) {
5116 mPolicy.dismissKeyguardLw();
5117 }
5118 }
5119
Craig Mautner0bf6ec92012-12-18 08:33:27 -08005120 @Override
Dianne Hackbornffa42482009-09-23 22:20:11 -07005121 public void closeSystemDialogs(String reason) {
5122 synchronized(mWindowMap) {
Craig Mautnerf8924152013-07-16 09:10:55 -07005123 final int numDisplays = mDisplayContents.size();
5124 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
5125 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
5126 final int numWindows = windows.size();
5127 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
5128 final WindowState w = windows.get(winNdx);
5129 if (w.mHasSurface) {
5130 try {
5131 w.mClient.closeSystemDialogs(reason);
5132 } catch (RemoteException e) {
5133 }
Dianne Hackbornffa42482009-09-23 22:20:11 -07005134 }
5135 }
5136 }
5137 }
5138 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005139
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005140 static float fixScale(float scale) {
5141 if (scale < 0) scale = 0;
5142 else if (scale > 20) scale = 20;
5143 return Math.abs(scale);
5144 }
Romain Guy06882f82009-06-10 13:36:04 -07005145
Craig Mautner0bf6ec92012-12-18 08:33:27 -08005146 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005147 public void setAnimationScale(int which, float scale) {
5148 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
5149 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005150 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005151 }
5152
Cyril Mottier5f5882f2013-07-15 10:29:48 +02005153 scale = fixScale(scale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005154 switch (which) {
Cyril Mottier5f5882f2013-07-15 10:29:48 +02005155 case 0: mWindowAnimationScale = scale; break;
5156 case 1: mTransitionAnimationScale = scale; break;
5157 case 2: mAnimatorDurationScale = scale; break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005158 }
Romain Guy06882f82009-06-10 13:36:04 -07005159
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005160 // Persist setting
You Kimcb6291c2012-12-04 23:22:28 +09005161 mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005162 }
Romain Guy06882f82009-06-10 13:36:04 -07005163
Craig Mautner4b71aa12012-12-27 17:20:01 -08005164 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005165 public void setAnimationScales(float[] scales) {
5166 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
5167 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005168 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005169 }
5170
5171 if (scales != null) {
5172 if (scales.length >= 1) {
5173 mWindowAnimationScale = fixScale(scales[0]);
5174 }
5175 if (scales.length >= 2) {
5176 mTransitionAnimationScale = fixScale(scales[1]);
5177 }
Chet Haasec38fa1f2012-02-01 16:37:46 -08005178 if (scales.length >= 3) {
Jeff Brownff7e6ef2012-08-15 02:05:18 -07005179 setAnimatorDurationScale(fixScale(scales[2]));
Chet Haasec38fa1f2012-02-01 16:37:46 -08005180 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005181 }
Romain Guy06882f82009-06-10 13:36:04 -07005182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005183 // Persist setting
You Kimcb6291c2012-12-04 23:22:28 +09005184 mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005185 }
Romain Guy06882f82009-06-10 13:36:04 -07005186
Jeff Brownff7e6ef2012-08-15 02:05:18 -07005187 private void setAnimatorDurationScale(float scale) {
5188 mAnimatorDurationScale = scale;
5189 ValueAnimator.setDurationScale(scale);
5190 }
5191
Craig Mautner4b71aa12012-12-27 17:20:01 -08005192 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005193 public float getAnimationScale(int which) {
5194 switch (which) {
5195 case 0: return mWindowAnimationScale;
5196 case 1: return mTransitionAnimationScale;
Chet Haasec38fa1f2012-02-01 16:37:46 -08005197 case 2: return mAnimatorDurationScale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005198 }
5199 return 0;
5200 }
Romain Guy06882f82009-06-10 13:36:04 -07005201
Craig Mautner4b71aa12012-12-27 17:20:01 -08005202 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005203 public float[] getAnimationScales() {
Chet Haasec38fa1f2012-02-01 16:37:46 -08005204 return new float[] { mWindowAnimationScale, mTransitionAnimationScale,
5205 mAnimatorDurationScale };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005206 }
Romain Guy06882f82009-06-10 13:36:04 -07005207
Craig Mautner037aa8d2013-06-07 10:35:44 -07005208 @Override
5209 public void registerPointerEventListener(PointerEventListener listener) {
5210 mPointerEventDispatcher.registerInputEventListener(listener);
5211 }
5212
5213 @Override
5214 public void unregisterPointerEventListener(PointerEventListener listener) {
5215 mPointerEventDispatcher.unregisterInputEventListener(listener);
5216 }
5217
Jeff Brownac143512012-04-05 18:57:33 -07005218 // Called by window manager policy. Not exposed externally.
5219 @Override
5220 public int getLidState() {
Jeff Brownc458ce92012-04-30 14:58:40 -07005221 int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY,
5222 InputManagerService.SW_LID);
Jeff Brownac143512012-04-05 18:57:33 -07005223 if (sw > 0) {
Jeff Brown27fd3422012-04-09 11:05:16 -07005224 // Switch state: AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL.
Jeff Brownac143512012-04-05 18:57:33 -07005225 return LID_CLOSED;
Jeff Brown27fd3422012-04-09 11:05:16 -07005226 } else if (sw == 0) {
5227 // Switch state: AKEY_STATE_UP.
5228 return LID_OPEN;
Jeff Brownac143512012-04-05 18:57:33 -07005229 } else {
Jeff Brown27fd3422012-04-09 11:05:16 -07005230 // Switch state: AKEY_STATE_UNKNOWN.
Jeff Brownac143512012-04-05 18:57:33 -07005231 return LID_ABSENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005232 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005233 }
Romain Guy06882f82009-06-10 13:36:04 -07005234
Jeff Brownac143512012-04-05 18:57:33 -07005235 // Called by window manager policy. Not exposed externally.
5236 @Override
Jeff Browncf39bdf2012-05-18 14:41:19 -07005237 public void switchKeyboardLayout(int deviceId, int direction) {
5238 mInputManager.switchKeyboardLayout(deviceId, direction);
5239 }
5240
5241 // Called by window manager policy. Not exposed externally.
5242 @Override
Jeff Brown9a538ee2012-08-20 14:56:57 -07005243 public void shutdown(boolean confirm) {
5244 ShutdownThread.shutdown(mContext, confirm);
Jeff Brown7304c342012-05-11 18:42:42 -07005245 }
5246
5247 // Called by window manager policy. Not exposed externally.
5248 @Override
Jeff Brown9a538ee2012-08-20 14:56:57 -07005249 public void rebootSafeMode(boolean confirm) {
5250 ShutdownThread.rebootSafeMode(mContext, confirm);
Jeff Brown7304c342012-05-11 18:42:42 -07005251 }
5252
Craig Mautner6cfa7292013-01-15 09:05:42 -08005253 @Override
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07005254 public void setInputFilter(IInputFilter filter) {
5255 if (!checkCallingPermission(android.Manifest.permission.FILTER_EVENTS, "setInputFilter()")) {
5256 throw new SecurityException("Requires FILTER_EVENTS permission");
5257 }
Jeff Brown0029c662011-03-30 02:25:18 -07005258 mInputManager.setInputFilter(filter);
5259 }
5260
Alan Viverette5a0f4ec2013-10-07 15:10:29 -07005261 @Override
5262 public void setTouchExplorationEnabled(boolean enabled) {
5263 mPolicy.setTouchExplorationEnabled(enabled);
5264 }
5265
Craig Mautnerf1b67412012-09-19 13:18:29 -07005266 public void setCurrentUser(final int newUserId) {
5267 synchronized (mWindowMap) {
Craig Mautner858d8a62013-04-23 17:08:34 -07005268 int oldUserId = mCurrentUserId;
Craig Mautnerf1b67412012-09-19 13:18:29 -07005269 mCurrentUserId = newUserId;
Amith Yamasani4befbec2013-07-10 16:18:01 -07005270 mAppTransition.setCurrentUser(newUserId);
Craig Mautnerf1b67412012-09-19 13:18:29 -07005271 mPolicy.setCurrentUserLw(newUserId);
Craig Mautner88400d32012-09-30 12:35:45 -07005272
5273 // Hide windows that should not be seen by the new user.
Craig Mautnerf8924152013-07-16 09:10:55 -07005274 final int numDisplays = mDisplayContents.size();
5275 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
5276 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautnerdc548482014-02-05 13:35:24 -08005277 displayContent.switchUserStacks(newUserId);
Craig Mautner858d8a62013-04-23 17:08:34 -07005278 rebuildAppWindowListLocked(displayContent);
Craig Mautner88400d32012-09-30 12:35:45 -07005279 }
5280 performLayoutAndPlaceSurfacesLocked();
Craig Mautnerf1b67412012-09-19 13:18:29 -07005281 }
5282 }
5283
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005284 public void enableScreenAfterBoot() {
5285 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005286 if (DEBUG_BOOT) {
5287 RuntimeException here = new RuntimeException("here");
5288 here.fillInStackTrace();
5289 Slog.i(TAG, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled
5290 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5291 + " mShowingBootMessages=" + mShowingBootMessages
5292 + " mSystemBooted=" + mSystemBooted, here);
5293 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005294 if (mSystemBooted) {
5295 return;
5296 }
5297 mSystemBooted = true;
Dianne Hackborn661cd522011-08-22 00:26:20 -07005298 hideBootMessagesLocked();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005299 // If the screen still doesn't come up after 30 seconds, give
5300 // up and turn it on.
You Kimcb6291c2012-12-04 23:22:28 +09005301 mH.sendEmptyMessageDelayed(H.BOOT_TIMEOUT, 30*1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005302 }
Romain Guy06882f82009-06-10 13:36:04 -07005303
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07005304 mPolicy.systemBooted();
5305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005306 performEnableScreen();
5307 }
Romain Guy06882f82009-06-10 13:36:04 -07005308
Dianne Hackborn661cd522011-08-22 00:26:20 -07005309 void enableScreenIfNeededLocked() {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005310 if (DEBUG_BOOT) {
5311 RuntimeException here = new RuntimeException("here");
5312 here.fillInStackTrace();
5313 Slog.i(TAG, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled
5314 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5315 + " mShowingBootMessages=" + mShowingBootMessages
5316 + " mSystemBooted=" + mSystemBooted, here);
5317 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005318 if (mDisplayEnabled) {
5319 return;
5320 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005321 if (!mSystemBooted && !mShowingBootMessages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005322 return;
5323 }
You Kimcb6291c2012-12-04 23:22:28 +09005324 mH.sendEmptyMessage(H.ENABLE_SCREEN);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005325 }
Romain Guy06882f82009-06-10 13:36:04 -07005326
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005327 public void performBootTimeout() {
5328 synchronized(mWindowMap) {
Mike Lockwoode63f6f72013-11-15 11:01:47 -08005329 if (mDisplayEnabled) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005330 return;
5331 }
5332 Slog.w(TAG, "***** BOOT TIMEOUT: forcing display enabled");
5333 mForceDisplayEnabled = true;
5334 }
5335 performEnableScreen();
5336 }
5337
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005338 public void performEnableScreen() {
5339 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005340 if (DEBUG_BOOT) {
5341 RuntimeException here = new RuntimeException("here");
5342 here.fillInStackTrace();
5343 Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
5344 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5345 + " mShowingBootMessages=" + mShowingBootMessages
Jeff Brown780c46f2012-06-24 12:15:38 -07005346 + " mSystemBooted=" + mSystemBooted
5347 + " mOnlyCore=" + mOnlyCore, here);
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005348 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005349 if (mDisplayEnabled) {
5350 return;
5351 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005352 if (!mSystemBooted && !mShowingBootMessages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005353 return;
5354 }
Romain Guy06882f82009-06-10 13:36:04 -07005355
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005356 if (!mForceDisplayEnabled) {
5357 // Don't enable the screen until all existing windows
5358 // have been drawn.
5359 boolean haveBootMsg = false;
5360 boolean haveApp = false;
Justin Mattson4233f262012-04-09 18:23:16 -07005361 // if the wallpaper service is disabled on the device, we're never going to have
5362 // wallpaper, don't bother waiting for it
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005363 boolean haveWallpaper = false;
Justin Mattson4233f262012-04-09 18:23:16 -07005364 boolean wallpaperEnabled = mContext.getResources().getBoolean(
Jeff Brown780c46f2012-06-24 12:15:38 -07005365 com.android.internal.R.bool.config_enableWallpaperService)
5366 && !mOnlyCore;
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005367 boolean haveKeyguard = true;
Craig Mautner59c00972012-07-30 12:10:24 -07005368 // TODO(multidisplay): Expand to all displays?
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005369 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07005370 final int N = windows.size();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005371 for (int i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07005372 WindowState w = windows.get(i);
Craig Mautner65d11b32012-10-01 13:59:52 -07005373 if (w.mAttrs.type == TYPE_KEYGUARD) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005374 // Only if there is a keyguard attached to the window manager
5375 // will we consider ourselves as having a keyguard. If it
5376 // isn't attached, we don't know if it wants to be shown or
5377 // hidden. If it is attached, we will say we have a keyguard
5378 // if the window doesn't want to be visible, because in that
5379 // case it explicitly doesn't want to be shown so we should
5380 // not delay turning the screen on for it.
5381 boolean vis = w.mViewVisibility == View.VISIBLE
5382 && w.mPolicyVisibility;
5383 haveKeyguard = !vis;
5384 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005385 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
5386 return;
5387 }
5388 if (w.isDrawnLw()) {
Craig Mautner65d11b32012-10-01 13:59:52 -07005389 if (w.mAttrs.type == TYPE_BOOT_PROGRESS) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005390 haveBootMsg = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005391 } else if (w.mAttrs.type == TYPE_APPLICATION) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005392 haveApp = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005393 } else if (w.mAttrs.type == TYPE_WALLPAPER) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005394 haveWallpaper = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005395 } else if (w.mAttrs.type == TYPE_KEYGUARD) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005396 haveKeyguard = true;
5397 }
5398 }
5399 }
5400
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005401 if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005402 Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
5403 + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
Justin Mattson4233f262012-04-09 18:23:16 -07005404 + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled
5405 + " haveKeyguard=" + haveKeyguard);
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005406 }
5407
5408 // If we are turning on the screen to show the boot message,
5409 // don't do it until the boot message is actually displayed.
5410 if (!mSystemBooted && !haveBootMsg) {
5411 return;
5412 }
Craig Mautner312eac42012-11-13 10:56:22 -08005413
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005414 // If we are turning on the screen after the boot is completed
5415 // normally, don't do so until we have the application and
5416 // wallpaper.
Justin Mattson4233f262012-04-09 18:23:16 -07005417 if (mSystemBooted && ((!haveApp && !haveKeyguard) ||
5418 (wallpaperEnabled && !haveWallpaper))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005419 return;
5420 }
5421 }
Romain Guy06882f82009-06-10 13:36:04 -07005422
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005423 mDisplayEnabled = true;
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005424 if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005425 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005426 StringWriter sw = new StringWriter();
Dianne Hackborn8c841092013-06-24 13:46:13 -07005427 PrintWriter pw = new FastPrintWriter(sw, false, 1024);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005428 this.dump(null, pw, null);
Dianne Hackborn8c841092013-06-24 13:46:13 -07005429 pw.flush();
Joe Onorato8a9b2202010-02-26 18:56:32 -08005430 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005431 }
5432 try {
5433 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
5434 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005435 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005436 Parcel data = Parcel.obtain();
5437 data.writeInterfaceToken("android.ui.ISurfaceComposer");
Jeff Brownc042ee22012-05-08 13:03:42 -07005438 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005439 data, null, 0);
5440 data.recycle();
5441 }
5442 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005443 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005444 }
Jeff Brown08a746a2012-06-24 12:14:49 -07005445
5446 // Enable input dispatch.
5447 mInputMonitor.setEventDispatchingLw(mEventDispatchingEnabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005448 }
Romain Guy06882f82009-06-10 13:36:04 -07005449
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005450 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07005451
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005452 // Make sure the last requested orientation has been applied.
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005453 updateRotationUnchecked(false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005454 }
Romain Guy06882f82009-06-10 13:36:04 -07005455
Dianne Hackborn661cd522011-08-22 00:26:20 -07005456 public void showBootMessage(final CharSequence msg, final boolean always) {
5457 boolean first = false;
5458 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005459 if (DEBUG_BOOT) {
5460 RuntimeException here = new RuntimeException("here");
5461 here.fillInStackTrace();
5462 Slog.i(TAG, "showBootMessage: msg=" + msg + " always=" + always
5463 + " mAllowBootMessages=" + mAllowBootMessages
5464 + " mShowingBootMessages=" + mShowingBootMessages
5465 + " mSystemBooted=" + mSystemBooted, here);
5466 }
Dianne Hackborn58f42a52011-10-10 13:46:34 -07005467 if (!mAllowBootMessages) {
5468 return;
5469 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005470 if (!mShowingBootMessages) {
5471 if (!always) {
5472 return;
5473 }
5474 first = true;
5475 }
5476 if (mSystemBooted) {
5477 return;
5478 }
5479 mShowingBootMessages = true;
5480 mPolicy.showBootMessage(msg, always);
5481 }
5482 if (first) {
5483 performEnableScreen();
5484 }
5485 }
5486
5487 public void hideBootMessagesLocked() {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005488 if (DEBUG_BOOT) {
5489 RuntimeException here = new RuntimeException("here");
5490 here.fillInStackTrace();
5491 Slog.i(TAG, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled
5492 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5493 + " mShowingBootMessages=" + mShowingBootMessages
5494 + " mSystemBooted=" + mSystemBooted, here);
5495 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005496 if (mShowingBootMessages) {
5497 mShowingBootMessages = false;
5498 mPolicy.hideBootMessages();
5499 }
5500 }
5501
Craig Mautner6cfa7292013-01-15 09:05:42 -08005502 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005503 public void setInTouchMode(boolean mode) {
5504 synchronized(mWindowMap) {
5505 mInTouchMode = mode;
5506 }
5507 }
5508
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005509 // TODO: more accounting of which pid(s) turned it on, keep count,
5510 // only allow disables from pids which have count on, etc.
Craig Mautner0447a812012-05-22 16:01:31 -07005511 @Override
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005512 public void showStrictModeViolation(boolean on) {
Chris Craik3198ef32012-10-10 14:52:30 -07005513 int pid = Binder.getCallingPid();
5514 mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, on ? 1 : 0, pid));
Craig Mautner0447a812012-05-22 16:01:31 -07005515 }
Mike Lockwood3a74bd32011-08-12 13:55:22 -07005516
Chris Craik3198ef32012-10-10 14:52:30 -07005517 private void showStrictModeViolation(int arg, int pid) {
Craig Mautner0447a812012-05-22 16:01:31 -07005518 final boolean on = arg != 0;
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005519 synchronized(mWindowMap) {
5520 // Ignoring requests to enable the red border from clients
5521 // which aren't on screen. (e.g. Broadcast Receivers in
5522 // the background..)
5523 if (on) {
5524 boolean isVisible = false;
Craig Mautnerf8924152013-07-16 09:10:55 -07005525 final int numDisplays = mDisplayContents.size();
5526 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
5527 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
5528 final int numWindows = windows.size();
5529 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
5530 final WindowState ws = windows.get(winNdx);
5531 if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
5532 isVisible = true;
5533 break;
5534 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005535 }
5536 }
5537 if (!isVisible) {
5538 return;
5539 }
5540 }
5541
Dianne Hackborn36991742011-10-11 21:35:26 -07005542 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
5543 ">>> OPEN TRANSACTION showStrictModeViolation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -08005544 SurfaceControl.openTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005545 try {
Jeff Browne215f262012-09-10 16:01:14 -07005546 // TODO(multi-display): support multiple displays
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005547 if (mStrictModeFlash == null) {
Jeff Browne215f262012-09-10 16:01:14 -07005548 mStrictModeFlash = new StrictModeFlash(
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005549 getDefaultDisplayContentLocked().getDisplay(), mFxSession);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005550 }
5551 mStrictModeFlash.setVisibility(on);
5552 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -08005553 SurfaceControl.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -07005554 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
5555 "<<< CLOSE TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005556 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005557 }
5558 }
5559
Craig Mautner6cfa7292013-01-15 09:05:42 -08005560 @Override
Brad Fitzpatrickc1a968a2010-11-24 08:56:40 -08005561 public void setStrictModeVisualIndicatorPreference(String value) {
5562 SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
5563 }
5564
Jim Millere70d5062011-03-08 21:38:39 -08005565 /**
5566 * Takes a snapshot of the screen. In landscape mode this grabs the whole screen.
5567 * In portrait mode, it grabs the upper region of the screen based on the vertical dimension
5568 * of the target image.
Craig Mautner312eac42012-11-13 10:56:22 -08005569 *
Craig Mautner59c00972012-07-30 12:10:24 -07005570 * @param displayId the Display to take a screenshot of.
Jim Millere70d5062011-03-08 21:38:39 -08005571 * @param width the width of the target bitmap
5572 * @param height the height of the target bitmap
John Reck172e87c2013-10-02 16:55:16 -07005573 * @param force565 if true the returned bitmap will be RGB_565, otherwise it
5574 * will be the same config as the surface
Jim Millere70d5062011-03-08 21:38:39 -08005575 */
Craig Mautner2d5618c2012-10-18 13:55:47 -07005576 @Override
John Reck172e87c2013-10-02 16:55:16 -07005577 public Bitmap screenshotApplications(IBinder appToken, int displayId, int width,
5578 int height, boolean force565) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005579 if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5580 "screenshotApplications()")) {
5581 throw new SecurityException("Requires READ_FRAME_BUFFER permission");
5582 }
5583
Craig Mautner24d887472013-03-20 15:40:36 -07005584 Bitmap rawss = null;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005585
Dianne Hackbornd2835932010-12-13 16:28:46 -08005586 int maxLayer = 0;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005587 final Rect frame = new Rect();
5588
Craig Mautner24d887472013-03-20 15:40:36 -07005589 float scale = 0;
Jim Millere70d5062011-03-08 21:38:39 -08005590 int dw, dh;
Craig Mautner24d887472013-03-20 15:40:36 -07005591 int rot = Surface.ROTATION_0;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005592
Craig Mautner24d887472013-03-20 15:40:36 -07005593 boolean screenshotReady;
5594 int minLayer;
5595 if (appToken == null) {
5596 screenshotReady = true;
5597 minLayer = 0;
5598 } else {
5599 screenshotReady = false;
5600 minLayer = Integer.MAX_VALUE;
5601 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005602
Craig Mautner24d887472013-03-20 15:40:36 -07005603 int retryCount = 0;
5604 WindowState appWin = null;
5605
5606 do {
5607 if (retryCount++ > 0) {
5608 try {
5609 Thread.sleep(100);
5610 } catch (InterruptedException e) {
5611 }
Craig Mautner2d5618c2012-10-18 13:55:47 -07005612 }
Craig Mautner24d887472013-03-20 15:40:36 -07005613 synchronized(mWindowMap) {
5614 final DisplayContent displayContent = getDisplayContentLocked(displayId);
5615 if (displayContent == null) {
5616 return null;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005617 }
Craig Mautner24d887472013-03-20 15:40:36 -07005618 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
5619 dw = displayInfo.logicalWidth;
5620 dh = displayInfo.logicalHeight;
5621
5622 int aboveAppLayer = mPolicy.windowTypeToLayerLw(TYPE_APPLICATION)
5623 * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
5624 aboveAppLayer += TYPE_LAYER_MULTIPLIER;
5625
5626 boolean isImeTarget = mInputMethodTarget != null
5627 && mInputMethodTarget.mAppToken != null
5628 && mInputMethodTarget.mAppToken.appToken != null
5629 && mInputMethodTarget.mAppToken.appToken.asBinder() == appToken;
5630
5631 // Figure out the part of the screen that is actually the app.
5632 boolean including = false;
5633 appWin = null;
5634 final WindowList windows = displayContent.getWindowList();
Craig Mautner76ea2242013-05-15 11:40:05 -07005635 final Rect stackBounds = new Rect();
Craig Mautner24d887472013-03-20 15:40:36 -07005636 for (int i = windows.size() - 1; i >= 0; i--) {
5637 WindowState ws = windows.get(i);
5638 if (!ws.mHasSurface) {
5639 continue;
5640 }
5641 if (ws.mLayer >= aboveAppLayer) {
5642 continue;
5643 }
5644 // When we will skip windows: when we are not including
5645 // ones behind a window we didn't skip, and we are actually
5646 // taking a screenshot of a specific app.
5647 if (!including && appToken != null) {
5648 // Also, we can possibly skip this window if it is not
5649 // an IME target or the application for the screenshot
5650 // is not the current IME target.
5651 if (!ws.mIsImWindow || !isImeTarget) {
5652 // And finally, this window is of no interest if it
5653 // is not associated with the screenshot app.
5654 if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
5655 continue;
5656 }
5657 appWin = ws;
Craig Mautnerbdc748af2013-12-02 14:08:25 -08005658 ws.getStackBounds(stackBounds);
Craig Mautner24d887472013-03-20 15:40:36 -07005659 }
5660 }
5661
5662 // We keep on including windows until we go past a full-screen
5663 // window.
Sangkyu Lee7ccba972013-11-21 15:20:33 +09005664 including = !ws.mIsImWindow && !ws.isFullscreen(dw, dh);
Craig Mautner24d887472013-03-20 15:40:36 -07005665
5666 final WindowStateAnimator winAnim = ws.mWinAnimator;
5667 if (maxLayer < winAnim.mSurfaceLayer) {
5668 maxLayer = winAnim.mSurfaceLayer;
5669 }
Craig Mautner4238e3e2013-03-28 15:28:55 -07005670 if (minLayer > winAnim.mSurfaceLayer) {
5671 minLayer = winAnim.mSurfaceLayer;
5672 }
Craig Mautner24d887472013-03-20 15:40:36 -07005673
5674 // Don't include wallpaper in bounds calculation
5675 if (!ws.mIsWallpaper) {
5676 final Rect wf = ws.mFrame;
5677 final Rect cr = ws.mContentInsets;
5678 int left = wf.left + cr.left;
5679 int top = wf.top + cr.top;
5680 int right = wf.right - cr.right;
5681 int bottom = wf.bottom - cr.bottom;
5682 frame.union(left, top, right, bottom);
Craig Mautner76ea2242013-05-15 11:40:05 -07005683 frame.intersect(stackBounds);
Craig Mautner24d887472013-03-20 15:40:36 -07005684 }
5685
Craig Mautner4238e3e2013-03-28 15:28:55 -07005686 if (ws.mAppToken != null && ws.mAppToken.token == appToken &&
5687 ws.isDisplayedLw()) {
5688 screenshotReady = true;
5689 }
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005690 }
5691
Craig Mautner24d887472013-03-20 15:40:36 -07005692 if (appToken != null && appWin == null) {
5693 // Can't find a window to snapshot.
5694 if (DEBUG_SCREENSHOT) Slog.i(TAG,
5695 "Screenshot: Couldn't find a surface matching " + appToken);
5696 return null;
5697 }
5698 if (!screenshotReady) {
5699 // Delay and hope that window gets drawn.
5700 if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot: No image ready for " + appToken
5701 + ", " + appWin + " drawState=" + appWin.mWinAnimator.mDrawState);
5702 continue;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005703 }
Craig Mautner312eac42012-11-13 10:56:22 -08005704
Craig Mautner24d887472013-03-20 15:40:36 -07005705 // Constrain frame to the screen size.
5706 frame.intersect(0, 0, dw, dh);
5707
5708 if (frame.isEmpty() || maxLayer == 0) {
5709 if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot of " + appToken
5710 + ": returning null frame=" + frame.toShortString() + " maxLayer="
5711 + maxLayer);
5712 return null;
Jim Miller2aded182011-03-08 15:32:42 -08005713 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005714
Craig Mautner24d887472013-03-20 15:40:36 -07005715 // The screenshot API does not apply the current screen rotation.
5716 rot = getDefaultDisplayContentLocked().getDisplay().getRotation();
5717 int fw = frame.width();
5718 int fh = frame.height();
Jim Millere70d5062011-03-08 21:38:39 -08005719
Craig Mautner24d887472013-03-20 15:40:36 -07005720 // Constrain thumbnail to smaller of screen width or height. Assumes aspect
5721 // of thumbnail is the same as the screen (in landscape) or square.
Craig Mautner76ea2242013-05-15 11:40:05 -07005722 scale = Math.max(width / (float) fw, height / (float) fh);
5723 /*
Craig Mautner24d887472013-03-20 15:40:36 -07005724 float targetWidthScale = width / (float) fw;
5725 float targetHeightScale = height / (float) fh;
Craig Mautner76ea2242013-05-15 11:40:05 -07005726 if (fw <= fh) {
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005727 scale = targetWidthScale;
Craig Mautner24d887472013-03-20 15:40:36 -07005728 // If aspect of thumbnail is the same as the screen (in landscape),
5729 // select the slightly larger value so we fill the entire bitmap
5730 if (targetHeightScale > scale && (int) (targetHeightScale * fw) == width) {
5731 scale = targetHeightScale;
5732 }
5733 } else {
5734 scale = targetHeightScale;
5735 // If aspect of thumbnail is the same as the screen (in landscape),
5736 // select the slightly larger value so we fill the entire bitmap
5737 if (targetWidthScale > scale && (int) (targetWidthScale * fh) == height) {
5738 scale = targetWidthScale;
5739 }
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005740 }
Craig Mautner76ea2242013-05-15 11:40:05 -07005741 */
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005742
Craig Mautner24d887472013-03-20 15:40:36 -07005743 // The screen shot will contain the entire screen.
5744 dw = (int)(dw*scale);
5745 dh = (int)(dh*scale);
5746 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
5747 int tmp = dw;
5748 dw = dh;
5749 dh = tmp;
5750 rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -07005751 }
Craig Mautner24d887472013-03-20 15:40:36 -07005752 if (DEBUG_SCREENSHOT) {
5753 Slog.i(TAG, "Screenshot: " + dw + "x" + dh + " from " + minLayer + " to "
5754 + maxLayer + " appToken=" + appToken);
5755 for (int i = 0; i < windows.size(); i++) {
5756 WindowState win = windows.get(i);
5757 Slog.i(TAG, win + ": " + win.mLayer
5758 + " animLayer=" + win.mWinAnimator.mAnimLayer
5759 + " surfaceLayer=" + win.mWinAnimator.mSurfaceLayer);
5760 }
5761 }
5762 rawss = SurfaceControl.screenshot(dw, dh, minLayer, maxLayer);
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -07005763 }
Craig Mautner24d887472013-03-20 15:40:36 -07005764 } while (!screenshotReady && retryCount <= MAX_SCREENSHOT_RETRIES);
Craig Mautner4238e3e2013-03-28 15:28:55 -07005765 if (retryCount > MAX_SCREENSHOT_RETRIES) Slog.i(TAG, "Screenshot max retries " +
5766 retryCount + " of " + appToken + " appWin=" + (appWin == null ?
5767 "null" : (appWin + " drawState=" + appWin.mWinAnimator.mDrawState)));
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005768
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005769 if (rawss == null) {
Craig Mautner4238e3e2013-03-28 15:28:55 -07005770 Slog.w(TAG, "Screenshot failure taking screenshot for (" + dw + "x" + dh
Dianne Hackborn88b03bd2010-12-16 11:15:18 -08005771 + ") to layer " + maxLayer);
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005772 return null;
5773 }
Jim Millere70d5062011-03-08 21:38:39 -08005774
John Reck172e87c2013-10-02 16:55:16 -07005775 Bitmap bm = Bitmap.createBitmap(width, height, force565 ? Config.RGB_565 : rawss.getConfig());
Craig Mautner76ea2242013-05-15 11:40:05 -07005776 frame.scale(scale);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005777 Matrix matrix = new Matrix();
5778 ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07005779 // TODO: Test for RTL vs. LTR and use frame.right-width instead of -frame.left
Craig Mautner76ea2242013-05-15 11:40:05 -07005780 matrix.postTranslate(-FloatMath.ceil(frame.left), -FloatMath.ceil(frame.top));
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005781 Canvas canvas = new Canvas(bm);
Dianne Hackbornca46b872013-04-17 18:06:22 -07005782 canvas.drawColor(0xFF000000);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005783 canvas.drawBitmap(rawss, matrix, null);
Dianne Hackborn6311d0a2011-08-02 16:37:58 -07005784 canvas.setBitmap(null);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005785
Craig Mautner4697bea2013-10-24 09:13:14 -07005786 if (DEBUG_SCREENSHOT) {
Craig Mautner24d887472013-03-20 15:40:36 -07005787 // TEST IF IT's ALL BLACK
5788 int[] buffer = new int[bm.getWidth() * bm.getHeight()];
5789 bm.getPixels(buffer, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm.getHeight());
5790 boolean allBlack = true;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07005791 final int firstColor = buffer[0];
Craig Mautner24d887472013-03-20 15:40:36 -07005792 for (int i = 0; i < buffer.length; i++) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07005793 if (buffer[i] != firstColor) {
Craig Mautner24d887472013-03-20 15:40:36 -07005794 allBlack = false;
5795 break;
5796 }
5797 }
5798 if (allBlack) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07005799 Slog.i(TAG, "Screenshot " + appWin + " was monochrome(" +
5800 Integer.toHexString(firstColor) + ")! mSurfaceLayer=" +
Craig Mautner4238e3e2013-03-28 15:28:55 -07005801 (appWin != null ? appWin.mWinAnimator.mSurfaceLayer : "null") +
5802 " minLayer=" + minLayer + " maxLayer=" + maxLayer);
Craig Mautner24d887472013-03-20 15:40:36 -07005803 }
5804 }
5805
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005806 rawss.recycle();
5807 return bm;
5808 }
5809
Jeff Brown01a98dd2011-09-20 15:08:29 -07005810 /**
5811 * Freeze rotation changes. (Enable "rotation lock".)
5812 * Persists across reboots.
Jeff Brown4dfce202011-10-05 12:00:10 -07005813 * @param rotation The desired rotation to freeze to, or -1 to use the
5814 * current rotation.
Jeff Brown01a98dd2011-09-20 15:08:29 -07005815 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005816 @Override
Jeff Brown4dfce202011-10-05 12:00:10 -07005817 public void freezeRotation(int rotation) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005818 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005819 "freezeRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005820 throw new SecurityException("Requires SET_ORIENTATION permission");
5821 }
Jeff Brown4dfce202011-10-05 12:00:10 -07005822 if (rotation < -1 || rotation > Surface.ROTATION_270) {
5823 throw new IllegalArgumentException("Rotation argument must be -1 or a valid "
5824 + "rotation constant.");
5825 }
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005826
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005827 if (DEBUG_ORIENTATION) Slog.v(TAG, "freezeRotation: mRotation=" + mRotation);
5828
Daniel Sandler3de830b2013-02-20 15:23:52 -05005829 long origId = Binder.clearCallingIdentity();
5830 try {
5831 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED,
5832 rotation == -1 ? mRotation : rotation);
5833 } finally {
5834 Binder.restoreCallingIdentity(origId);
5835 }
5836
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005837 updateRotationUnchecked(false, false);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005838 }
5839
Jeff Brown01a98dd2011-09-20 15:08:29 -07005840 /**
5841 * Thaw rotation changes. (Disable "rotation lock".)
5842 * Persists across reboots.
5843 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005844 @Override
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005845 public void thawRotation() {
5846 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005847 "thawRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005848 throw new SecurityException("Requires SET_ORIENTATION permission");
5849 }
5850
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005851 if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation);
5852
Daniel Sandler3de830b2013-02-20 15:23:52 -05005853 long origId = Binder.clearCallingIdentity();
5854 try {
5855 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE,
5856 777); // rot not used
5857 } finally {
5858 Binder.restoreCallingIdentity(origId);
5859 }
5860
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005861 updateRotationUnchecked(false, false);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005862 }
5863
Jeff Brown01a98dd2011-09-20 15:08:29 -07005864 /**
5865 * Recalculate the current rotation.
5866 *
5867 * Called by the window manager policy whenever the state of the system changes
5868 * such that the current rotation might need to be updated, such as when the
5869 * device is docked or rotated into a new posture.
5870 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005871 @Override
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005872 public void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
5873 updateRotationUnchecked(alwaysSendConfiguration, forceRelayout);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005874 }
5875
5876 /**
5877 * Temporarily pauses rotation changes until resumed.
5878 *
5879 * This can be used to prevent rotation changes from occurring while the user is
5880 * performing certain operations, such as drag and drop.
5881 *
Craig Mautner6cfa7292013-01-15 09:05:42 -08005882 * This call nests and must be matched by an equal number of calls to
5883 * {@link #resumeRotationLocked}.
Jeff Brown01a98dd2011-09-20 15:08:29 -07005884 */
5885 void pauseRotationLocked() {
5886 mDeferredRotationPauseCount += 1;
5887 }
5888
5889 /**
5890 * Resumes normal rotation changes after being paused.
5891 */
5892 void resumeRotationLocked() {
5893 if (mDeferredRotationPauseCount > 0) {
5894 mDeferredRotationPauseCount -= 1;
5895 if (mDeferredRotationPauseCount == 0) {
5896 boolean changed = updateRotationUncheckedLocked(false);
5897 if (changed) {
5898 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
5899 }
5900 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005901 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005902 }
Romain Guy06882f82009-06-10 13:36:04 -07005903
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005904 public void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005905 if(DEBUG_ORIENTATION) Slog.v(TAG, "updateRotationUnchecked("
5906 + "alwaysSendConfiguration=" + alwaysSendConfiguration + ")");
Romain Guy06882f82009-06-10 13:36:04 -07005907
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005908 long origId = Binder.clearCallingIdentity();
5909 boolean changed;
5910 synchronized(mWindowMap) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005911 changed = updateRotationUncheckedLocked(false);
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005912 if (!changed || forceRelayout) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005913 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005914 performLayoutAndPlaceSurfacesLocked();
5915 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005916 }
Romain Guy06882f82009-06-10 13:36:04 -07005917
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005918 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005919 sendNewConfiguration();
5920 }
Romain Guy06882f82009-06-10 13:36:04 -07005921
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005922 Binder.restoreCallingIdentity(origId);
5923 }
Romain Guy06882f82009-06-10 13:36:04 -07005924
Craig Mautner59c00972012-07-30 12:10:24 -07005925 // TODO(multidisplay): Rotate any display?
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005926 /**
Jeff Brown01a98dd2011-09-20 15:08:29 -07005927 * Updates the current rotation.
5928 *
5929 * Returns true if the rotation has been changed. In this case YOU
5930 * MUST CALL sendNewConfiguration() TO UNFREEZE THE SCREEN.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005931 */
Jeff Brown01a98dd2011-09-20 15:08:29 -07005932 public boolean updateRotationUncheckedLocked(boolean inTransaction) {
5933 if (mDeferredRotationPauseCount > 0) {
5934 // Rotation updates have been paused temporarily. Defer the update until
5935 // updates have been resumed.
5936 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, rotation is paused.");
Christopher Tateccd24de2011-01-12 15:02:55 -08005937 return false;
5938 }
5939
Craig Mautnera91f9e22012-09-14 16:22:08 -07005940 ScreenRotationAnimation screenRotationAnimation =
5941 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
5942 if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005943 // Rotation updates cannot be performed while the previous rotation change
5944 // animation is still in progress. Skip this update. We will try updating
5945 // again after the animation is finished and the display is unfrozen.
5946 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, animation in progress.");
5947 return false;
5948 }
5949
5950 if (!mDisplayEnabled) {
5951 // No point choosing a rotation if the display is not enabled.
5952 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, display is not enabled.");
5953 return false;
5954 }
5955
5956 // TODO: Implement forced rotation changes.
5957 // Set mAltOrientation to indicate that the application is receiving
5958 // an orientation that has different metrics than it expected.
5959 // eg. Portrait instead of Landscape.
5960
5961 int rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, mRotation);
5962 boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
5963 mForcedAppOrientation, rotation);
5964
5965 if (DEBUG_ORIENTATION) {
5966 Slog.v(TAG, "Application requested orientation "
5967 + mForcedAppOrientation + ", got rotation " + rotation
5968 + " which has " + (altOrientation ? "incompatible" : "compatible")
5969 + " metrics");
5970 }
5971
5972 if (mRotation == rotation && mAltOrientation == altOrientation) {
5973 // No change.
5974 return false;
5975 }
5976
5977 if (DEBUG_ORIENTATION) {
5978 Slog.v(TAG,
5979 "Rotation changed to " + rotation + (altOrientation ? " (alt)" : "")
5980 + " from " + mRotation + (mAltOrientation ? " (alt)" : "")
5981 + ", forceApp=" + mForcedAppOrientation);
5982 }
5983
5984 mRotation = rotation;
5985 mAltOrientation = altOrientation;
Jeff Brownc0347aa2011-09-23 17:26:09 -07005986 mPolicy.setRotationLw(mRotation);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005987
5988 mWindowsFreezingScreen = true;
5989 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
Craig Mautner0bf6ec92012-12-18 08:33:27 -08005990 mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT, WINDOW_FREEZE_TIMEOUT_DURATION);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005991 mWaitingForConfig = true;
Craig Mautner05d29032013-05-03 13:40:13 -07005992 final DisplayContent displayContent = getDefaultDisplayContentLocked();
5993 displayContent.layoutNeeded = true;
Craig Mautner3c174372013-02-21 17:54:37 -08005994 final int[] anim = new int[2];
Craig Mautner05d29032013-05-03 13:40:13 -07005995 if (displayContent.isDimming()) {
Craig Mautner3c174372013-02-21 17:54:37 -08005996 anim[0] = anim[1] = 0;
5997 } else {
5998 mPolicy.selectRotationAnimationLw(anim);
5999 }
6000 startFreezingDisplayLocked(inTransaction, anim[0], anim[1]);
Craig Mautnera91f9e22012-09-14 16:22:08 -07006001 // startFreezingDisplayLocked can reset the ScreenRotationAnimation.
6002 screenRotationAnimation =
6003 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
Jeff Brown01a98dd2011-09-20 15:08:29 -07006004
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006005 // We need to update our screen size information to match the new
6006 // rotation. Note that this is redundant with the later call to
6007 // sendNewConfiguration() that must be called after this function
6008 // returns... however we need to do the screen size part of that
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006009 // before then so we have the correct size to use when initializing
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006010 // the rotation animation for the new rotation.
6011 computeScreenConfigurationLocked(null);
6012
Craig Mautner59c00972012-07-30 12:10:24 -07006013 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006014 if (!inTransaction) {
6015 if (SHOW_TRANSACTIONS) {
6016 Slog.i(TAG, ">>> OPEN TRANSACTION setRotationUnchecked");
6017 }
Mathias Agopian3866f0d2013-02-11 22:08:48 -08006018 SurfaceControl.openTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006019 }
Jamie Gennise2909e12011-10-10 15:48:06 -07006020 try {
6021 // NOTE: We disable the rotation in the emulator because
6022 // it doesn't support hardware OpenGL emulation yet.
Craig Mautnera91f9e22012-09-14 16:22:08 -07006023 if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
6024 && screenRotationAnimation.hasScreenshot()) {
6025 if (screenRotationAnimation.setRotationInTransaction(
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006026 rotation, mFxSession,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006027 MAX_ANIMATION_DURATION, mTransitionAnimationScale,
Craig Mautner59c00972012-07-30 12:10:24 -07006028 displayInfo.logicalWidth, displayInfo.logicalHeight)) {
Craig Mautner96868332012-12-04 14:29:11 -08006029 scheduleAnimationLocked();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006030 }
Jamie Gennise2909e12011-10-10 15:48:06 -07006031 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006032
Jeff Brown4ccb8232014-01-16 22:16:42 -08006033 mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
Jamie Gennise2909e12011-10-10 15:48:06 -07006034 } finally {
6035 if (!inTransaction) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -08006036 SurfaceControl.closeTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006037 if (SHOW_LIGHT_TRANSACTIONS) {
6038 Slog.i(TAG, "<<< CLOSE TRANSACTION setRotationUnchecked");
6039 }
Jamie Gennise2909e12011-10-10 15:48:06 -07006040 }
6041 }
6042
Craig Mautner59c00972012-07-30 12:10:24 -07006043 final WindowList windows = displayContent.getWindowList();
6044 for (int i = windows.size() - 1; i >= 0; i--) {
6045 WindowState w = windows.get(i);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07006046 if (w.mHasSurface) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07006047 if (DEBUG_ORIENTATION) Slog.v(TAG, "Set mOrientationChanging of " + w);
Jeff Brown01a98dd2011-09-20 15:08:29 -07006048 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07006049 mInnerFields.mOrientationChangeComplete = false;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006050 }
Dianne Hackborna57c6952013-03-29 14:46:40 -07006051 w.mLastFreezeDuration = 0;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006052 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006053
Jeff Brown01a98dd2011-09-20 15:08:29 -07006054 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
6055 try {
6056 mRotationWatchers.get(i).onRotationChanged(rotation);
6057 } catch (RemoteException e) {
6058 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006059 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006060
Svetoslav Ganov545252f2012-12-10 18:29:24 -08006061 //TODO (multidisplay): Magnification is supported only for the default display.
6062 if (mDisplayMagnifier != null
6063 && displayContent.getDisplayId() == Display.DEFAULT_DISPLAY) {
6064 mDisplayMagnifier.onRotationChangedLocked(getDefaultDisplayContentLocked(), rotation);
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07006065 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006066
Jeff Brown01a98dd2011-09-20 15:08:29 -07006067 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006068 }
Romain Guy06882f82009-06-10 13:36:04 -07006069
Craig Mautner0bf6ec92012-12-18 08:33:27 -08006070 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006071 public int getRotation() {
6072 return mRotation;
6073 }
6074
Craig Mautner0bf6ec92012-12-18 08:33:27 -08006075 @Override
Svetoslav Ganov80943d82013-01-02 10:25:37 -08006076 public boolean isRotationFrozen() {
6077 return mPolicy.getUserRotationMode() == WindowManagerPolicy.USER_ROTATION_LOCKED;
6078 }
6079
6080 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006081 public int watchRotation(IRotationWatcher watcher) {
6082 final IBinder watcherBinder = watcher.asBinder();
6083 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
Craig Mautner0bf6ec92012-12-18 08:33:27 -08006084 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006085 public void binderDied() {
6086 synchronized (mWindowMap) {
6087 for (int i=0; i<mRotationWatchers.size(); i++) {
6088 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07006089 IRotationWatcher removed = mRotationWatchers.remove(i);
6090 if (removed != null) {
6091 removed.asBinder().unlinkToDeath(this, 0);
6092 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006093 i--;
6094 }
6095 }
6096 }
6097 }
6098 };
Romain Guy06882f82009-06-10 13:36:04 -07006099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006100 synchronized (mWindowMap) {
6101 try {
6102 watcher.asBinder().linkToDeath(dr, 0);
6103 mRotationWatchers.add(watcher);
6104 } catch (RemoteException e) {
6105 // Client died, no cleanup needed.
6106 }
Romain Guy06882f82009-06-10 13:36:04 -07006107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006108 return mRotation;
6109 }
6110 }
6111
Brian Colonnab1b9a8a2013-03-29 11:52:42 -04006112 @Override
6113 public void removeRotationWatcher(IRotationWatcher watcher) {
6114 final IBinder watcherBinder = watcher.asBinder();
6115 synchronized (mWindowMap) {
6116 for (int i=0; i<mRotationWatchers.size(); i++) {
6117 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
6118 mRotationWatchers.remove(i);
6119 i--;
6120 }
6121 }
6122 }
6123 }
6124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006125 /**
Adam Powelldfee59a2011-08-05 20:48:30 -07006126 * Apps that use the compact menu panel (as controlled by the panelMenuIsCompact
6127 * theme attribute) on devices that feature a physical options menu key attempt to position
6128 * their menu panel window along the edge of the screen nearest the physical menu key.
6129 * This lowers the travel distance between invoking the menu panel and selecting
6130 * a menu option.
6131 *
6132 * This method helps control where that menu is placed. Its current implementation makes
6133 * assumptions about the menu key and its relationship to the screen based on whether
6134 * the device's natural orientation is portrait (width < height) or landscape.
6135 *
6136 * The menu key is assumed to be located along the bottom edge of natural-portrait
6137 * devices and along the right edge of natural-landscape devices. If these assumptions
6138 * do not hold for the target device, this method should be changed to reflect that.
6139 *
6140 * @return A {@link Gravity} value for placing the options menu window
6141 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08006142 @Override
Adam Powelldfee59a2011-08-05 20:48:30 -07006143 public int getPreferredOptionsPanelGravity() {
6144 synchronized (mWindowMap) {
6145 final int rotation = getRotation();
6146
Craig Mautner59c00972012-07-30 12:10:24 -07006147 // TODO(multidisplay): Assume that such devices physical keys are on the main screen.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006148 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07006149 if (displayContent.mInitialDisplayWidth < displayContent.mInitialDisplayHeight) {
Adam Powelldfee59a2011-08-05 20:48:30 -07006150 // On devices with a natural orientation of portrait
6151 switch (rotation) {
6152 default:
6153 case Surface.ROTATION_0:
6154 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
6155 case Surface.ROTATION_90:
Adam Powell67ed6c72011-08-28 13:21:56 -07006156 return Gravity.RIGHT | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006157 case Surface.ROTATION_180:
Adam Powell67ed6c72011-08-28 13:21:56 -07006158 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006159 case Surface.ROTATION_270:
Fabrice Di Meglioaac0d4e2012-07-19 19:21:26 -07006160 return Gravity.START | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006161 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08006162 }
6163
6164 // On devices with a natural orientation of landscape
6165 switch (rotation) {
6166 default:
6167 case Surface.ROTATION_0:
6168 return Gravity.RIGHT | Gravity.BOTTOM;
6169 case Surface.ROTATION_90:
6170 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
6171 case Surface.ROTATION_180:
6172 return Gravity.START | Gravity.BOTTOM;
6173 case Surface.ROTATION_270:
6174 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006175 }
6176 }
6177 }
6178
6179 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006180 * Starts the view server on the specified port.
6181 *
6182 * @param port The port to listener to.
6183 *
6184 * @return True if the server was successfully started, false otherwise.
6185 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08006186 * @see com.android.server.wm.ViewServer
6187 * @see com.android.server.wm.ViewServer#VIEW_SERVER_DEFAULT_PORT
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006188 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08006189 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006190 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07006191 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006192 return false;
6193 }
6194
6195 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
6196 return false;
6197 }
6198
6199 if (port < 1024) {
6200 return false;
6201 }
6202
6203 if (mViewServer != null) {
6204 if (!mViewServer.isRunning()) {
6205 try {
6206 return mViewServer.start();
6207 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006208 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006209 }
6210 }
6211 return false;
6212 }
6213
6214 try {
6215 mViewServer = new ViewServer(this, port);
6216 return mViewServer.start();
6217 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006218 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006219 }
6220 return false;
6221 }
6222
Romain Guy06882f82009-06-10 13:36:04 -07006223 private boolean isSystemSecure() {
6224 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
6225 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6226 }
6227
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006228 /**
6229 * Stops the view server if it exists.
6230 *
6231 * @return True if the server stopped, false if it wasn't started or
6232 * couldn't be stopped.
6233 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08006234 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006235 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08006236 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006237 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07006238 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006239 return false;
6240 }
6241
6242 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
6243 return false;
6244 }
6245
6246 if (mViewServer != null) {
6247 return mViewServer.stop();
6248 }
6249 return false;
6250 }
6251
6252 /**
6253 * Indicates whether the view server is running.
6254 *
6255 * @return True if the server is running, false otherwise.
6256 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08006257 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006258 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08006259 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006260 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07006261 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006262 return false;
6263 }
6264
6265 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
6266 return false;
6267 }
6268
6269 return mViewServer != null && mViewServer.isRunning();
6270 }
6271
6272 /**
6273 * Lists all availble windows in the system. The listing is written in the
6274 * specified Socket's output stream with the following syntax:
6275 * windowHashCodeInHexadecimal windowName
6276 * Each line of the ouput represents a different window.
6277 *
6278 * @param client The remote client to send the listing to.
6279 * @return False if an error occured, true otherwise.
6280 */
6281 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07006282 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006283 return false;
6284 }
6285
6286 boolean result = true;
6287
Craig Mautner59c00972012-07-30 12:10:24 -07006288 WindowList windows = new WindowList();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006289 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006290 //noinspection unchecked
Craig Mautnerf8924152013-07-16 09:10:55 -07006291 final int numDisplays = mDisplayContents.size();
6292 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
6293 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
6294 windows.addAll(displayContent.getWindowList());
Craig Mautner59c00972012-07-30 12:10:24 -07006295 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006296 }
6297
6298 BufferedWriter out = null;
6299
6300 // Any uncaught exception will crash the system process
6301 try {
6302 OutputStream clientStream = client.getOutputStream();
6303 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
6304
Craig Mautner59c00972012-07-30 12:10:24 -07006305 final int count = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006306 for (int i = 0; i < count; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07006307 final WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006308 out.write(Integer.toHexString(System.identityHashCode(w)));
6309 out.write(' ');
6310 out.append(w.mAttrs.getTitle());
6311 out.write('\n');
6312 }
6313
6314 out.write("DONE.\n");
6315 out.flush();
6316 } catch (Exception e) {
6317 result = false;
6318 } finally {
6319 if (out != null) {
6320 try {
6321 out.close();
6322 } catch (IOException e) {
6323 result = false;
6324 }
6325 }
6326 }
6327
6328 return result;
6329 }
6330
Craig Mautner59c00972012-07-30 12:10:24 -07006331 // TODO(multidisplay): Extend to multiple displays.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006332 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07006333 * Returns the focused window in the following format:
6334 * windowHashCodeInHexadecimal windowName
6335 *
6336 * @param client The remote client to send the listing to.
6337 * @return False if an error occurred, true otherwise.
6338 */
6339 boolean viewServerGetFocusedWindow(Socket client) {
6340 if (isSystemSecure()) {
6341 return false;
6342 }
6343
6344 boolean result = true;
6345
6346 WindowState focusedWindow = getFocusedWindow();
6347
6348 BufferedWriter out = null;
6349
6350 // Any uncaught exception will crash the system process
6351 try {
6352 OutputStream clientStream = client.getOutputStream();
6353 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
6354
6355 if(focusedWindow != null) {
6356 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
6357 out.write(' ');
6358 out.append(focusedWindow.mAttrs.getTitle());
6359 }
6360 out.write('\n');
6361 out.flush();
6362 } catch (Exception e) {
6363 result = false;
6364 } finally {
6365 if (out != null) {
6366 try {
6367 out.close();
6368 } catch (IOException e) {
6369 result = false;
6370 }
6371 }
6372 }
6373
6374 return result;
6375 }
6376
6377 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006378 * Sends a command to a target window. The result of the command, if any, will be
6379 * written in the output stream of the specified socket.
6380 *
6381 * The parameters must follow this syntax:
6382 * windowHashcode extra
6383 *
6384 * Where XX is the length in characeters of the windowTitle.
6385 *
6386 * The first parameter is the target window. The window with the specified hashcode
6387 * will be the target. If no target can be found, nothing happens. The extra parameters
6388 * will be delivered to the target window and as parameters to the command itself.
6389 *
6390 * @param client The remote client to sent the result, if any, to.
6391 * @param command The command to execute.
6392 * @param parameters The command parameters.
6393 *
6394 * @return True if the command was successfully delivered, false otherwise. This does
6395 * not indicate whether the command itself was successful.
6396 */
6397 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07006398 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006399 return false;
6400 }
6401
6402 boolean success = true;
6403 Parcel data = null;
6404 Parcel reply = null;
6405
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006406 BufferedWriter out = null;
6407
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006408 // Any uncaught exception will crash the system process
6409 try {
6410 // Find the hashcode of the window
6411 int index = parameters.indexOf(' ');
6412 if (index == -1) {
6413 index = parameters.length();
6414 }
6415 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08006416 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006417
6418 // Extract the command's parameter after the window description
6419 if (index < parameters.length()) {
6420 parameters = parameters.substring(index + 1);
6421 } else {
6422 parameters = "";
6423 }
6424
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006425 final WindowState window = findWindow(hashCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006426 if (window == null) {
6427 return false;
6428 }
6429
6430 data = Parcel.obtain();
6431 data.writeInterfaceToken("android.view.IWindow");
6432 data.writeString(command);
6433 data.writeString(parameters);
6434 data.writeInt(1);
6435 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
6436
6437 reply = Parcel.obtain();
6438
6439 final IBinder binder = window.mClient.asBinder();
6440 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
6441 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
6442
6443 reply.readException();
6444
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006445 if (!client.isOutputShutdown()) {
6446 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
6447 out.write("DONE\n");
6448 out.flush();
6449 }
6450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006451 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006452 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006453 success = false;
6454 } finally {
6455 if (data != null) {
6456 data.recycle();
6457 }
6458 if (reply != null) {
6459 reply.recycle();
6460 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006461 if (out != null) {
6462 try {
6463 out.close();
6464 } catch (IOException e) {
6465
6466 }
6467 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006468 }
6469
6470 return success;
6471 }
6472
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07006473 public void addWindowChangeListener(WindowChangeListener listener) {
6474 synchronized(mWindowMap) {
6475 mWindowChangeListeners.add(listener);
6476 }
6477 }
6478
6479 public void removeWindowChangeListener(WindowChangeListener listener) {
6480 synchronized(mWindowMap) {
6481 mWindowChangeListeners.remove(listener);
6482 }
6483 }
6484
6485 private void notifyWindowsChanged() {
6486 WindowChangeListener[] windowChangeListeners;
6487 synchronized(mWindowMap) {
6488 if(mWindowChangeListeners.isEmpty()) {
6489 return;
6490 }
6491 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
6492 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
6493 }
6494 int N = windowChangeListeners.length;
6495 for(int i = 0; i < N; i++) {
6496 windowChangeListeners[i].windowsChanged();
6497 }
6498 }
6499
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07006500 private void notifyFocusChanged() {
6501 WindowChangeListener[] windowChangeListeners;
6502 synchronized(mWindowMap) {
6503 if(mWindowChangeListeners.isEmpty()) {
6504 return;
6505 }
6506 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
6507 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
6508 }
6509 int N = windowChangeListeners.length;
6510 for(int i = 0; i < N; i++) {
6511 windowChangeListeners[i].focusChanged();
6512 }
6513 }
6514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006515 private WindowState findWindow(int hashCode) {
6516 if (hashCode == -1) {
Craig Mautner59c00972012-07-30 12:10:24 -07006517 // TODO(multidisplay): Extend to multiple displays.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006518 return getFocusedWindow();
6519 }
6520
6521 synchronized (mWindowMap) {
Craig Mautnerf8924152013-07-16 09:10:55 -07006522 final int numDisplays = mDisplayContents.size();
6523 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
6524 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
6525 final int numWindows = windows.size();
6526 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
6527 final WindowState w = windows.get(winNdx);
6528 if (System.identityHashCode(w) == hashCode) {
6529 return w;
6530 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006531 }
6532 }
6533 }
6534
6535 return null;
6536 }
6537
6538 /*
6539 * Instruct the Activity Manager to fetch the current configuration and broadcast
6540 * that to config-changed listeners if appropriate.
6541 */
6542 void sendNewConfiguration() {
6543 try {
6544 mActivityManager.updateConfiguration(null);
6545 } catch (RemoteException e) {
6546 }
6547 }
Romain Guy06882f82009-06-10 13:36:04 -07006548
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006549 public Configuration computeNewConfiguration() {
6550 synchronized (mWindowMap) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006551 Configuration config = computeNewConfigurationLocked();
6552 if (config == null && mWaitingForConfig) {
6553 // Nothing changed but we are waiting for something... stop that!
6554 mWaitingForConfig = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07006555 mLastFinishedFreezeSource = "new-config";
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006556 performLayoutAndPlaceSurfacesLocked();
6557 }
6558 return config;
Dianne Hackbornc485a602009-03-24 22:39:49 -07006559 }
6560 }
Romain Guy06882f82009-06-10 13:36:04 -07006561
Dianne Hackbornc485a602009-03-24 22:39:49 -07006562 Configuration computeNewConfigurationLocked() {
6563 Configuration config = new Configuration();
Dianne Hackborn09e5b9d2011-10-04 16:32:01 -07006564 config.fontScale = 0;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006565 if (!computeScreenConfigurationLocked(config)) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07006566 return null;
6567 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07006568 return config;
6569 }
Romain Guy06882f82009-06-10 13:36:04 -07006570
Craig Mautner59c00972012-07-30 12:10:24 -07006571 private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation, int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006572 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006573 final int width = mPolicy.getConfigDisplayWidth(dw, dh, rotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006574 if (width < displayInfo.smallestNominalAppWidth) {
6575 displayInfo.smallestNominalAppWidth = width;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006576 }
Craig Mautner59c00972012-07-30 12:10:24 -07006577 if (width > displayInfo.largestNominalAppWidth) {
6578 displayInfo.largestNominalAppWidth = width;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006579 }
6580 final int height = mPolicy.getConfigDisplayHeight(dw, dh, rotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006581 if (height < displayInfo.smallestNominalAppHeight) {
6582 displayInfo.smallestNominalAppHeight = height;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006583 }
Craig Mautner59c00972012-07-30 12:10:24 -07006584 if (height > displayInfo.largestNominalAppHeight) {
6585 displayInfo.largestNominalAppHeight = height;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006586 }
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006587 }
6588
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006589 private int reduceConfigLayout(int curLayout, int rotation, float density,
6590 int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006591 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006592 // Get the app screen size at this rotation.
6593 int w = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
6594 int h = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
6595
6596 // Compute the screen layout size class for this rotation.
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006597 int longSize = w;
6598 int shortSize = h;
6599 if (longSize < shortSize) {
6600 int tmp = longSize;
6601 longSize = shortSize;
6602 shortSize = tmp;
6603 }
6604 longSize = (int)(longSize/density);
6605 shortSize = (int)(shortSize/density);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006606 return Configuration.reduceScreenLayout(curLayout, longSize, shortSize);
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006607 }
6608
Craig Mautner59c00972012-07-30 12:10:24 -07006609 private void computeSizeRangesAndScreenLayout(DisplayInfo displayInfo, boolean rotated,
6610 int dw, int dh, float density, Configuration outConfig) {
Craig Mautner69b08182012-09-05 13:07:13 -07006611 // TODO: Multidisplay: for now only use with default display.
6612
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006613 // We need to determine the smallest width that will occur under normal
6614 // operation. To this, start with the base screen size and compute the
6615 // width under the different possible rotations. We need to un-rotate
6616 // the current screen dimensions before doing this.
6617 int unrotDw, unrotDh;
6618 if (rotated) {
6619 unrotDw = dh;
6620 unrotDh = dw;
6621 } else {
6622 unrotDw = dw;
6623 unrotDh = dh;
6624 }
Craig Mautner59c00972012-07-30 12:10:24 -07006625 displayInfo.smallestNominalAppWidth = 1<<30;
6626 displayInfo.smallestNominalAppHeight = 1<<30;
6627 displayInfo.largestNominalAppWidth = 0;
6628 displayInfo.largestNominalAppHeight = 0;
6629 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, unrotDw, unrotDh);
6630 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, unrotDh, unrotDw);
6631 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, unrotDw, unrotDh);
6632 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, unrotDh, unrotDw);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006633 int sl = Configuration.resetScreenLayout(outConfig.screenLayout);
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006634 sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh);
6635 sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw);
6636 sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh);
6637 sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw);
Craig Mautner59c00972012-07-30 12:10:24 -07006638 outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006639 outConfig.screenLayout = sl;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006640 }
6641
Dianne Hackborn48a76512011-06-08 21:51:44 -07006642 private int reduceCompatConfigWidthSize(int curSize, int rotation, DisplayMetrics dm,
6643 int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006644 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn1f903c32011-09-13 19:18:06 -07006645 dm.noncompatWidthPixels = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
6646 dm.noncompatHeightPixels = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006647 float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
Dianne Hackborn2b31d532011-06-23 11:58:50 -07006648 int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006649 if (curSize == 0 || size < curSize) {
6650 curSize = size;
6651 }
6652 return curSize;
6653 }
6654
6655 private int computeCompatSmallestWidth(boolean rotated, DisplayMetrics dm, int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006656 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn48a76512011-06-08 21:51:44 -07006657 mTmpDisplayMetrics.setTo(dm);
Craig Mautner69b08182012-09-05 13:07:13 -07006658 final DisplayMetrics tmpDm = mTmpDisplayMetrics;
6659 final int unrotDw, unrotDh;
Dianne Hackborn48a76512011-06-08 21:51:44 -07006660 if (rotated) {
6661 unrotDw = dh;
6662 unrotDh = dw;
6663 } else {
6664 unrotDw = dw;
6665 unrotDh = dh;
6666 }
Craig Mautner69b08182012-09-05 13:07:13 -07006667 int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, tmpDm, unrotDw, unrotDh);
6668 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, tmpDm, unrotDh, unrotDw);
6669 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, tmpDm, unrotDw, unrotDh);
6670 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, tmpDm, unrotDh, unrotDw);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006671 return sw;
6672 }
6673
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006674 boolean computeScreenConfigurationLocked(Configuration config) {
Jeff Browne215f262012-09-10 16:01:14 -07006675 if (!mDisplayReady) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07006676 return false;
6677 }
Christopher Tateb696aee2010-04-02 19:08:30 -07006678
Craig Mautner59c00972012-07-30 12:10:24 -07006679 // TODO(multidisplay): For now, apply Configuration to main screen only.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006680 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07006681
Christopher Tateb696aee2010-04-02 19:08:30 -07006682 // Use the effective "visual" dimensions based on current rotation
6683 final boolean rotated = (mRotation == Surface.ROTATION_90
6684 || mRotation == Surface.ROTATION_270);
Craig Mautner59c00972012-07-30 12:10:24 -07006685 final int realdw = rotated ?
6686 displayContent.mBaseDisplayHeight : displayContent.mBaseDisplayWidth;
6687 final int realdh = rotated ?
6688 displayContent.mBaseDisplayWidth : displayContent.mBaseDisplayHeight;
Jeff Brownfa25bf52012-07-23 19:26:30 -07006689 int dw = realdw;
6690 int dh = realdh;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006691
Jeff Brownfa25bf52012-07-23 19:26:30 -07006692 if (mAltOrientation) {
6693 if (realdw > realdh) {
6694 // Turn landscape into portrait.
6695 int maxw = (int)(realdh/1.3f);
6696 if (maxw < realdw) {
6697 dw = maxw;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006698 }
6699 } else {
Jeff Brownfa25bf52012-07-23 19:26:30 -07006700 // Turn portrait into landscape.
6701 int maxh = (int)(realdw/1.3f);
6702 if (maxh < realdh) {
6703 dh = maxh;
6704 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006705 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006706 }
6707
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006708 if (config != null) {
Jeff Browne215f262012-09-10 16:01:14 -07006709 config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
6710 Configuration.ORIENTATION_LANDSCAPE;
Dianne Hackbornc485a602009-03-24 22:39:49 -07006711 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006712
Jeff Brownbc68a592011-07-25 12:58:12 -07006713 // Update application display metrics.
Dianne Hackborn1fbee792011-11-30 11:29:58 -08006714 final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation);
6715 final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006716 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
6717 synchronized(displayContent.mDisplaySizeLock) {
6718 displayInfo.rotation = mRotation;
6719 displayInfo.logicalWidth = dw;
6720 displayInfo.logicalHeight = dh;
Dianne Hackborndde331c2012-08-03 14:01:57 -07006721 displayInfo.logicalDensityDpi = displayContent.mBaseDisplayDensity;
Craig Mautner59c00972012-07-30 12:10:24 -07006722 displayInfo.appWidth = appWidth;
6723 displayInfo.appHeight = appHeight;
Craig Mautner48d0d182013-06-11 07:53:06 -07006724 displayInfo.getLogicalMetrics(mRealDisplayMetrics,
6725 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
6726 displayInfo.getAppMetrics(mDisplayMetrics);
Jeff Brown4ccb8232014-01-16 22:16:42 -08006727 mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
Jeff Brownbd6e1502012-08-28 03:27:37 -07006728 displayContent.getDisplayId(), displayInfo);
Dianne Hackborn1fbee792011-11-30 11:29:58 -08006729 }
Dianne Hackborn36991742011-10-11 21:35:26 -07006730 if (false) {
Jeff Brownfa25bf52012-07-23 19:26:30 -07006731 Slog.i(TAG, "Set app display size: " + appWidth + " x " + appHeight);
Dianne Hackborn36991742011-10-11 21:35:26 -07006732 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006733
Jeff Brownfa25bf52012-07-23 19:26:30 -07006734 final DisplayMetrics dm = mDisplayMetrics;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006735 mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm,
6736 mCompatDisplayMetrics);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006737
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006738 if (config != null) {
6739 config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation)
6740 / dm.density);
6741 config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation)
6742 / dm.density);
Craig Mautner59c00972012-07-30 12:10:24 -07006743 computeSizeRangesAndScreenLayout(displayInfo, rotated, dw, dh, dm.density, config);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006744
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006745 config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
6746 config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
6747 config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dm, dw, dh);
Dianne Hackborndde331c2012-08-03 14:01:57 -07006748 config.densityDpi = displayContent.mBaseDisplayDensity;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006749
Jeff Browndaa37532012-05-01 15:54:03 -07006750 // Update the configuration based on available input devices, lid switch,
6751 // and platform configuration.
6752 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
6753 config.keyboard = Configuration.KEYBOARD_NOKEYS;
6754 config.navigation = Configuration.NAVIGATION_NONAV;
6755
6756 int keyboardPresence = 0;
6757 int navigationPresence = 0;
Craig Mautner1d961d42012-05-27 12:02:11 -07006758 final InputDevice[] devices = mInputManager.getInputDevices();
6759 final int len = devices.length;
6760 for (int i = 0; i < len; i++) {
6761 InputDevice device = devices[i];
Jeff Browndaa37532012-05-01 15:54:03 -07006762 if (!device.isVirtual()) {
6763 final int sources = device.getSources();
6764 final int presenceFlag = device.isExternal() ?
6765 WindowManagerPolicy.PRESENCE_EXTERNAL :
6766 WindowManagerPolicy.PRESENCE_INTERNAL;
6767
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -07006768 if (mIsTouchDevice) {
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006769 if ((sources & InputDevice.SOURCE_TOUCHSCREEN) ==
6770 InputDevice.SOURCE_TOUCHSCREEN) {
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -07006771 config.touchscreen = Configuration.TOUCHSCREEN_FINGER;
6772 }
6773 } else {
6774 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
Jeff Browndaa37532012-05-01 15:54:03 -07006775 }
6776
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006777 if ((sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) {
Jeff Browndaa37532012-05-01 15:54:03 -07006778 config.navigation = Configuration.NAVIGATION_TRACKBALL;
6779 navigationPresence |= presenceFlag;
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006780 } else if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD
Jeff Browndaa37532012-05-01 15:54:03 -07006781 && config.navigation == Configuration.NAVIGATION_NONAV) {
6782 config.navigation = Configuration.NAVIGATION_DPAD;
6783 navigationPresence |= presenceFlag;
6784 }
6785
6786 if (device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) {
6787 config.keyboard = Configuration.KEYBOARD_QWERTY;
6788 keyboardPresence |= presenceFlag;
6789 }
6790 }
6791 }
6792
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006793 // Determine whether a hard keyboard is available and enabled.
6794 boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
6795 if (hardKeyboardAvailable != mHardKeyboardAvailable) {
6796 mHardKeyboardAvailable = hardKeyboardAvailable;
6797 mHardKeyboardEnabled = hardKeyboardAvailable;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006798 mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
6799 mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
6800 }
6801 if (!mHardKeyboardEnabled) {
6802 config.keyboard = Configuration.KEYBOARD_NOKEYS;
6803 }
6804
Jeff Browndaa37532012-05-01 15:54:03 -07006805 // Let the policy update hidden states.
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006806 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
6807 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
6808 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO;
Jeff Browndaa37532012-05-01 15:54:03 -07006809 mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence);
Jeff Brown2992ea72011-01-28 22:04:14 -08006810 }
Jeff Brown597eec82011-01-31 17:12:25 -08006811
Dianne Hackbornc485a602009-03-24 22:39:49 -07006812 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006813 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006814
Jeff Brown2992ea72011-01-28 22:04:14 -08006815 public boolean isHardKeyboardAvailable() {
6816 synchronized (mWindowMap) {
6817 return mHardKeyboardAvailable;
6818 }
6819 }
6820
6821 public boolean isHardKeyboardEnabled() {
6822 synchronized (mWindowMap) {
6823 return mHardKeyboardEnabled;
6824 }
6825 }
6826
6827 public void setHardKeyboardEnabled(boolean enabled) {
6828 synchronized (mWindowMap) {
6829 if (mHardKeyboardEnabled != enabled) {
6830 mHardKeyboardEnabled = enabled;
6831 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
6832 }
6833 }
6834 }
6835
6836 public void setOnHardKeyboardStatusChangeListener(
6837 OnHardKeyboardStatusChangeListener listener) {
6838 synchronized (mWindowMap) {
6839 mHardKeyboardStatusChangeListener = listener;
6840 }
6841 }
6842
6843 void notifyHardKeyboardStatusChange() {
6844 final boolean available, enabled;
6845 final OnHardKeyboardStatusChangeListener listener;
6846 synchronized (mWindowMap) {
6847 listener = mHardKeyboardStatusChangeListener;
6848 available = mHardKeyboardAvailable;
6849 enabled = mHardKeyboardEnabled;
6850 }
6851 if (listener != null) {
6852 listener.onHardKeyboardStatusChange(available, enabled);
6853 }
6854 }
6855
Christopher Tatea53146c2010-09-07 11:57:52 -07006856 // -------------------------------------------------------------
6857 // Drag and drop
6858 // -------------------------------------------------------------
6859
6860 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006861 int flags, int width, int height, Surface outSurface) {
Christopher Tatea53146c2010-09-07 11:57:52 -07006862 if (DEBUG_DRAG) {
6863 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006864 + " flags=" + Integer.toHexString(flags) + " win=" + window
Christopher Tatea53146c2010-09-07 11:57:52 -07006865 + " asbinder=" + window.asBinder());
6866 }
6867
6868 final int callerPid = Binder.getCallingPid();
6869 final long origId = Binder.clearCallingIdentity();
6870 IBinder token = null;
6871
6872 try {
6873 synchronized (mWindowMap) {
6874 try {
Christopher Tatea53146c2010-09-07 11:57:52 -07006875 if (mDragState == null) {
Jeff Browne215f262012-09-10 16:01:14 -07006876 // TODO(multi-display): support other displays
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006877 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07006878 final Display display = displayContent.getDisplay();
Mathias Agopian3866f0d2013-02-11 22:08:48 -08006879 SurfaceControl surface = new SurfaceControl(session, "drag surface",
6880 width, height, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
Jeff Browne215f262012-09-10 16:01:14 -07006881 surface.setLayerStack(display.getLayerStack());
Dianne Hackbornac1471a2011-02-03 13:46:06 -08006882 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DRAG "
6883 + surface + ": CREATE");
Christopher Tatea53146c2010-09-07 11:57:52 -07006884 outSurface.copyFrom(surface);
Chris Tate7b362e42010-11-04 16:02:52 -07006885 final IBinder winBinder = window.asBinder();
Christopher Tatea53146c2010-09-07 11:57:52 -07006886 token = new Binder();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006887 mDragState = new DragState(this, token, surface, /*flags*/ 0, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07006888 token = mDragState.mToken = new Binder();
6889
6890 // 5 second timeout for this window to actually begin the drag
Chris Tate7b362e42010-11-04 16:02:52 -07006891 mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
6892 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07006893 mH.sendMessageDelayed(msg, 5000);
6894 } else {
6895 Slog.w(TAG, "Drag already in progress");
6896 }
Igor Murashkina86ab6402013-08-30 12:58:36 -07006897 } catch (OutOfResourcesException e) {
Christopher Tatea53146c2010-09-07 11:57:52 -07006898 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
6899 if (mDragState != null) {
6900 mDragState.reset();
6901 mDragState = null;
6902 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006903 }
6904 }
6905 } finally {
6906 Binder.restoreCallingIdentity(origId);
6907 }
6908
6909 return token;
6910 }
6911
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006912 // -------------------------------------------------------------
6913 // Input Events and Focus Management
6914 // -------------------------------------------------------------
Craig Mautner6cfa7292013-01-15 09:05:42 -08006915
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006916 final InputMonitor mInputMonitor = new InputMonitor(this);
Jeff Brown08a746a2012-06-24 12:14:49 -07006917 private boolean mEventDispatchingEnabled;
6918
Craig Mautner6cfa7292013-01-15 09:05:42 -08006919 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006920 public void pauseKeyDispatching(IBinder _token) {
6921 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6922 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006923 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006924 }
6925
6926 synchronized (mWindowMap) {
6927 WindowToken token = mTokenMap.get(_token);
6928 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006929 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006930 }
6931 }
6932 }
6933
Craig Mautner6cfa7292013-01-15 09:05:42 -08006934 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006935 public void resumeKeyDispatching(IBinder _token) {
6936 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6937 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006938 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006939 }
6940
6941 synchronized (mWindowMap) {
6942 WindowToken token = mTokenMap.get(_token);
6943 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006944 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006945 }
6946 }
6947 }
6948
Craig Mautner6cfa7292013-01-15 09:05:42 -08006949 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006950 public void setEventDispatching(boolean enabled) {
6951 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner3d7b7d52012-05-24 11:28:26 -07006952 "setEventDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006953 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006954 }
6955
6956 synchronized (mWindowMap) {
Jeff Brown08a746a2012-06-24 12:14:49 -07006957 mEventDispatchingEnabled = enabled;
6958 if (mDisplayEnabled) {
6959 mInputMonitor.setEventDispatchingLw(enabled);
6960 }
Craig Mautner3d7b7d52012-05-24 11:28:26 -07006961 sendScreenStatusToClientsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006962 }
6963 }
Romain Guy06882f82009-06-10 13:36:04 -07006964
Craig Mautner6cfa7292013-01-15 09:05:42 -08006965 @Override
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07006966 public IBinder getFocusedWindowToken() {
6967 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
6968 "getFocusedWindowToken()")) {
6969 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
6970 }
Svetoslav Ganove15ccb92012-05-16 15:48:55 -07006971 synchronized (mWindowMap) {
6972 WindowState windowState = getFocusedWindowLocked();
6973 if (windowState != null) {
6974 return windowState.mClient.asBinder();
6975 }
6976 return null;
6977 }
6978 }
6979
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006980 private WindowState getFocusedWindow() {
6981 synchronized (mWindowMap) {
6982 return getFocusedWindowLocked();
6983 }
6984 }
6985
6986 private WindowState getFocusedWindowLocked() {
6987 return mCurrentFocus;
6988 }
Romain Guy06882f82009-06-10 13:36:04 -07006989
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006990 public boolean detectSafeMode() {
Jeff Brownb09abc12011-01-13 21:08:27 -08006991 if (!mInputMonitor.waitForInputDevicesReady(
6992 INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
6993 Slog.w(TAG, "Devices still not ready after waiting "
Jeff Brownac143512012-04-05 18:57:33 -07006994 + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
6995 + " milliseconds before attempting to detect safe mode.");
Jeff Brownb09abc12011-01-13 21:08:27 -08006996 }
6997
Jeff Brownac143512012-04-05 18:57:33 -07006998 int menuState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
6999 KeyEvent.KEYCODE_MENU);
7000 int sState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, KeyEvent.KEYCODE_S);
7001 int dpadState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD,
7002 KeyEvent.KEYCODE_DPAD_CENTER);
7003 int trackballState = mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL,
Jeff Brownc458ce92012-04-30 14:58:40 -07007004 InputManagerService.BTN_MOUSE);
Jeff Brownac143512012-04-05 18:57:33 -07007005 int volumeDownState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
7006 KeyEvent.KEYCODE_VOLUME_DOWN);
7007 mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
7008 || volumeDownState > 0;
Dianne Hackborn19caadc2012-04-20 17:49:10 -07007009 try {
7010 if (SystemProperties.getInt(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, 0) != 0) {
7011 mSafeMode = true;
7012 SystemProperties.set(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, "");
7013 }
7014 } catch (IllegalArgumentException e) {
7015 }
Jeff Brownac143512012-04-05 18:57:33 -07007016 if (mSafeMode) {
7017 Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
7018 + " dpad=" + dpadState + " trackball=" + trackballState + ")");
7019 } else {
7020 Log.i(TAG, "SAFE MODE not enabled");
7021 }
7022 mPolicy.setSafeMode(mSafeMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007023 return mSafeMode;
7024 }
Romain Guy06882f82009-06-10 13:36:04 -07007025
Dianne Hackborn661cd522011-08-22 00:26:20 -07007026 public void displayReady() {
Jeff Browne215f262012-09-10 16:01:14 -07007027 displayReady(Display.DEFAULT_DISPLAY);
Craig Mautner4f67ba62012-08-02 11:23:00 -07007028
7029 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007030 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07007031 readForcedDisplaySizeAndDensityLocked(displayContent);
Jeff Browne215f262012-09-10 16:01:14 -07007032 mDisplayReady = true;
Craig Mautner67a60422013-07-24 09:19:44 -07007033 }
7034
7035 try {
7036 mActivityManager.updateConfiguration(null);
7037 } catch (RemoteException e) {
7038 }
7039
7040 synchronized(mWindowMap) {
Craig Mautner4f67ba62012-08-02 11:23:00 -07007041 mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
Jeff Browne215f262012-09-10 16:01:14 -07007042 PackageManager.FEATURE_TOUCHSCREEN);
Jeff Brownef981a42013-08-07 14:13:37 -07007043 configureDisplayPolicyLocked(getDefaultDisplayContentLocked());
Craig Mautner4f67ba62012-08-02 11:23:00 -07007044 }
Dianne Hackborn5a052a42012-08-15 18:49:23 -07007045
7046 try {
7047 mActivityManager.updateConfiguration(null);
7048 } catch (RemoteException e) {
7049 }
Craig Mautner59c00972012-07-30 12:10:24 -07007050 }
7051
Craig Mautner2d5618c2012-10-18 13:55:47 -07007052 private void displayReady(int displayId) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07007053 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007054 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007055 if (displayContent != null) {
7056 mAnimator.addDisplayLocked(displayId);
7057 synchronized(displayContent.mDisplaySizeLock) {
7058 // Bootstrap the default logical display from the display manager.
7059 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
Jeff Brown4ccb8232014-01-16 22:16:42 -08007060 DisplayInfo newDisplayInfo = mDisplayManagerInternal.getDisplayInfo(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007061 if (newDisplayInfo != null) {
7062 displayInfo.copyFrom(newDisplayInfo);
7063 }
7064 displayContent.mInitialDisplayWidth = displayInfo.logicalWidth;
7065 displayContent.mInitialDisplayHeight = displayInfo.logicalHeight;
7066 displayContent.mInitialDisplayDensity = displayInfo.logicalDensityDpi;
7067 displayContent.mBaseDisplayWidth = displayContent.mInitialDisplayWidth;
7068 displayContent.mBaseDisplayHeight = displayContent.mInitialDisplayHeight;
7069 displayContent.mBaseDisplayDensity = displayContent.mInitialDisplayDensity;
Craig Mautner6601b7b2013-04-29 10:29:11 -07007070 displayContent.mBaseDisplayRect.set(0, 0,
7071 displayContent.mBaseDisplayWidth, displayContent.mBaseDisplayHeight);
Jeff Brownbd6e1502012-08-28 03:27:37 -07007072 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007073 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07007074 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07007075 }
7076
Dianne Hackborn661cd522011-08-22 00:26:20 -07007077 public void systemReady() {
7078 mPolicy.systemReady();
7079 }
7080
Craig Mautner59c00972012-07-30 12:10:24 -07007081 // TODO(multidisplay): Call isScreenOn for each display.
Craig Mautner3d7b7d52012-05-24 11:28:26 -07007082 private void sendScreenStatusToClientsLocked() {
Craig Mautner59c00972012-07-30 12:10:24 -07007083 final boolean on = mPowerManager.isScreenOn();
Craig Mautnerf8924152013-07-16 09:10:55 -07007084 final int numDisplays = mDisplayContents.size();
7085 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
7086 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
7087 final int numWindows = windows.size();
7088 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
7089 try {
7090 windows.get(winNdx).mClient.dispatchScreenState(on);
7091 } catch (RemoteException e) {
7092 // Ignored
7093 }
Romain Guy7e4e5612012-03-05 14:37:29 -08007094 }
7095 }
7096 }
7097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007098 // -------------------------------------------------------------
7099 // Async Handler
7100 // -------------------------------------------------------------
7101
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08007102 final class H extends Handler {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007103 public static final int REPORT_FOCUS_CHANGE = 2;
7104 public static final int REPORT_LOSING_FOCUS = 3;
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08007105 public static final int DO_TRAVERSAL = 4;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007106 public static final int ADD_STARTING = 5;
7107 public static final int REMOVE_STARTING = 6;
7108 public static final int FINISHED_STARTING = 7;
7109 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07007110 public static final int REPORT_APPLICATION_TOKEN_DRAWN = 9;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007111 public static final int WINDOW_FREEZE_TIMEOUT = 11;
Craig Mautner259328c2012-08-21 19:30:58 -07007112
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007113 public static final int APP_TRANSITION_TIMEOUT = 13;
7114 public static final int PERSIST_ANIMATION_SCALE = 14;
7115 public static final int FORCE_GC = 15;
7116 public static final int ENABLE_SCREEN = 16;
7117 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007118 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07007119 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07007120 public static final int DRAG_START_TIMEOUT = 20;
Chris Tated4533f12010-10-19 15:15:08 -07007121 public static final int DRAG_END_TIMEOUT = 21;
Jeff Brown2992ea72011-01-28 22:04:14 -08007122 public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07007123 public static final int BOOT_TIMEOUT = 23;
Dianne Hackborn38e29a62011-09-18 14:43:08 -07007124 public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
Craig Mautner96868332012-12-04 14:29:11 -08007125 public static final int SHOW_STRICT_MODE_VIOLATION = 25;
7126 public static final int DO_ANIMATION_CALLBACK = 26;
Romain Guy06882f82009-06-10 13:36:04 -07007127
Craig Mautner96868332012-12-04 14:29:11 -08007128 public static final int DO_DISPLAY_ADDED = 27;
7129 public static final int DO_DISPLAY_REMOVED = 28;
7130 public static final int DO_DISPLAY_CHANGED = 29;
Craig Mautner722285e2012-09-07 13:55:58 -07007131
Craig Mautner96868332012-12-04 14:29:11 -08007132 public static final int CLIENT_FREEZE_TIMEOUT = 30;
Craig Mautnerd3c93382013-04-24 14:23:39 -07007133 public static final int TAP_OUTSIDE_STACK = 31;
Craig Mautner5eda9b32013-07-02 11:58:16 -07007134 public static final int NOTIFY_ACTIVITY_DRAWN = 32;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007135
Craig Mautner68cc2412013-10-01 10:39:43 -07007136 public static final int REMOVE_STARTING_TIMEOUT = 33;
7137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007138 @Override
7139 public void handleMessage(Message msg) {
Craig Mautner7d8df392012-04-06 15:26:23 -07007140 if (DEBUG_WINDOW_TRACE) {
7141 Slog.v(TAG, "handleMessage: entry what=" + msg.what);
7142 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007143 switch (msg.what) {
7144 case REPORT_FOCUS_CHANGE: {
7145 WindowState lastFocus;
7146 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07007147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007148 synchronized(mWindowMap) {
7149 lastFocus = mLastFocus;
7150 newFocus = mCurrentFocus;
7151 if (lastFocus == newFocus) {
7152 // Focus is not changing, so nothing to do.
7153 return;
7154 }
7155 mLastFocus = newFocus;
Craig Mautner58458122013-09-14 14:59:50 -07007156 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Focus moving from " + lastFocus +
7157 " to " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007158 if (newFocus != null && lastFocus != null
7159 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007160 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007161 mLosingFocus.add(lastFocus);
7162 lastFocus = null;
7163 }
7164 }
7165
Craig Mautnerb1885b852013-09-16 22:50:50 -07007166 //System.out.println("Changing focus from " + lastFocus
7167 // + " to " + newFocus);
7168 if (newFocus != null) {
7169 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Gaining focus: " + newFocus);
7170 newFocus.reportFocusChangedSerialized(true, mInTouchMode);
7171 notifyFocusChanged();
7172 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007173
Craig Mautnerb1885b852013-09-16 22:50:50 -07007174 if (lastFocus != null) {
7175 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Losing focus: " + lastFocus);
7176 lastFocus.reportFocusChangedSerialized(false, mInTouchMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007177 }
7178 } break;
7179
7180 case REPORT_LOSING_FOCUS: {
7181 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07007182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007183 synchronized(mWindowMap) {
7184 losers = mLosingFocus;
7185 mLosingFocus = new ArrayList<WindowState>();
7186 }
7187
7188 final int N = losers.size();
7189 for (int i=0; i<N; i++) {
Craig Mautner58458122013-09-14 14:59:50 -07007190 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Losing delayed focus: " +
7191 losers.get(i));
Dianne Hackborne3f23a32013-03-01 13:25:35 -08007192 losers.get(i).reportFocusChangedSerialized(false, mInTouchMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007193 }
7194 } break;
7195
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08007196 case DO_TRAVERSAL: {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007197 synchronized(mWindowMap) {
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08007198 mTraversalScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007199 performLayoutAndPlaceSurfacesLocked();
7200 }
7201 } break;
7202
7203 case ADD_STARTING: {
7204 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7205 final StartingData sd = wtoken.startingData;
7206
7207 if (sd == null) {
7208 // Animation has been canceled... do nothing.
7209 return;
7210 }
Romain Guy06882f82009-06-10 13:36:04 -07007211
Joe Onorato8a9b2202010-02-26 18:56:32 -08007212 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007213 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07007214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007215 View view = null;
7216 try {
7217 view = mPolicy.addStartingWindow(
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07007218 wtoken.token, sd.pkg, sd.theme, sd.compatInfo,
Adam Powell04fe6eb2013-05-31 14:39:48 -07007219 sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.logo, sd.windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007220 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007221 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007222 }
7223
7224 if (view != null) {
7225 boolean abort = false;
7226
7227 synchronized(mWindowMap) {
7228 if (wtoken.removed || wtoken.startingData == null) {
7229 // If the window was successfully added, then
7230 // we need to remove it.
7231 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007232 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007233 "Aborted starting " + wtoken
7234 + ": removed=" + wtoken.removed
7235 + " startingData=" + wtoken.startingData);
Craig Mautner68cc2412013-10-01 10:39:43 -07007236 removeStartingWindowTimeout(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007237 wtoken.startingWindow = null;
7238 wtoken.startingData = null;
7239 abort = true;
7240 }
7241 } else {
7242 wtoken.startingView = view;
7243 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007244 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007245 "Added starting " + wtoken
7246 + ": startingWindow="
7247 + wtoken.startingWindow + " startingView="
7248 + wtoken.startingView);
7249 }
7250
7251 if (abort) {
7252 try {
7253 mPolicy.removeStartingWindow(wtoken.token, view);
7254 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007255 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007256 }
7257 }
7258 }
7259 } break;
7260
Craig Mautner68cc2412013-10-01 10:39:43 -07007261 case REMOVE_STARTING_TIMEOUT: {
7262 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7263 Slog.e(TAG, "Starting window " + wtoken + " timed out");
7264 // Fall through.
7265 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007266 case REMOVE_STARTING: {
7267 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7268 IBinder token = null;
7269 View view = null;
7270 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007271 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007272 + wtoken + ": startingWindow="
7273 + wtoken.startingWindow + " startingView="
7274 + wtoken.startingView);
7275 if (wtoken.startingWindow != null) {
7276 view = wtoken.startingView;
7277 token = wtoken.token;
7278 wtoken.startingData = null;
7279 wtoken.startingView = null;
7280 wtoken.startingWindow = null;
Craig Mautner38b24782012-07-02 16:21:28 -07007281 wtoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007282 }
7283 }
7284 if (view != null) {
7285 try {
7286 mPolicy.removeStartingWindow(token, view);
7287 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007288 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007289 }
7290 }
7291 } break;
7292
7293 case FINISHED_STARTING: {
7294 IBinder token = null;
7295 View view = null;
7296 while (true) {
7297 synchronized (mWindowMap) {
7298 final int N = mFinishedStarting.size();
7299 if (N <= 0) {
7300 break;
7301 }
7302 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
7303
Joe Onorato8a9b2202010-02-26 18:56:32 -08007304 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007305 "Finished starting " + wtoken
7306 + ": startingWindow=" + wtoken.startingWindow
7307 + " startingView=" + wtoken.startingView);
7308
7309 if (wtoken.startingWindow == null) {
7310 continue;
7311 }
7312
7313 view = wtoken.startingView;
7314 token = wtoken.token;
7315 wtoken.startingData = null;
7316 wtoken.startingView = null;
7317 wtoken.startingWindow = null;
Craig Mautner38b24782012-07-02 16:21:28 -07007318 wtoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007319 }
7320
7321 try {
7322 mPolicy.removeStartingWindow(token, view);
7323 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007324 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007325 }
7326 }
7327 } break;
7328
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07007329 case REPORT_APPLICATION_TOKEN_DRAWN: {
7330 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7331
7332 try {
7333 if (DEBUG_VISIBILITY) Slog.v(
7334 TAG, "Reporting drawn in " + wtoken);
7335 wtoken.appToken.windowsDrawn();
7336 } catch (RemoteException ex) {
7337 }
7338 } break;
7339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007340 case REPORT_APPLICATION_TOKEN_WINDOWS: {
7341 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7342
7343 boolean nowVisible = msg.arg1 != 0;
7344 boolean nowGone = msg.arg2 != 0;
7345
7346 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007347 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007348 TAG, "Reporting visible in " + wtoken
7349 + " visible=" + nowVisible
7350 + " gone=" + nowGone);
7351 if (nowVisible) {
7352 wtoken.appToken.windowsVisible();
7353 } else {
7354 wtoken.appToken.windowsGone();
7355 }
7356 } catch (RemoteException ex) {
7357 }
7358 } break;
Romain Guy06882f82009-06-10 13:36:04 -07007359
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007360 case WINDOW_FREEZE_TIMEOUT: {
Craig Mautner59c00972012-07-30 12:10:24 -07007361 // TODO(multidisplay): Can non-default displays rotate?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007362 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007363 Slog.w(TAG, "Window freeze timeout expired.");
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007364 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07007365 int i = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007366 while (i > 0) {
7367 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07007368 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007369 if (w.mOrientationChanging) {
7370 w.mOrientationChanging = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07007371 w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
7372 - mDisplayFreezeTime);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007373 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007374 }
7375 }
7376 performLayoutAndPlaceSurfacesLocked();
7377 }
7378 break;
7379 }
Romain Guy06882f82009-06-10 13:36:04 -07007380
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007381 case APP_TRANSITION_TIMEOUT: {
7382 synchronized (mWindowMap) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08007383 if (mAppTransition.isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08007384 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** APP TRANSITION TIMEOUT");
7385 mAppTransition.setTimeout();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007386 performLayoutAndPlaceSurfacesLocked();
7387 }
7388 }
7389 break;
7390 }
Romain Guy06882f82009-06-10 13:36:04 -07007391
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007392 case PERSIST_ANIMATION_SCALE: {
Jeff Sharkey6e2bee72012-10-01 13:39:08 -07007393 Settings.Global.putFloat(mContext.getContentResolver(),
7394 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
7395 Settings.Global.putFloat(mContext.getContentResolver(),
7396 Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
7397 Settings.Global.putFloat(mContext.getContentResolver(),
7398 Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007399 break;
7400 }
Romain Guy06882f82009-06-10 13:36:04 -07007401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007402 case FORCE_GC: {
Craig Mautner1caa3992012-06-22 09:46:48 -07007403 synchronized (mWindowMap) {
Craig Mautner96868332012-12-04 14:29:11 -08007404 // Since we're holding both mWindowMap and mAnimator we don't need to
7405 // hold mAnimator.mLayoutToAnim.
7406 if (mAnimator.mAnimating || mAnimationScheduled) {
7407 // If we are animating, don't do the gc now but
7408 // delay a bit so we don't interrupt the animation.
7409 sendEmptyMessageDelayed(H.FORCE_GC, 2000);
7410 return;
7411 }
7412 // If we are currently rotating the display, it will
7413 // schedule a new message when done.
7414 if (mDisplayFrozen) {
7415 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007416 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007417 }
7418 Runtime.getRuntime().gc();
7419 break;
7420 }
Romain Guy06882f82009-06-10 13:36:04 -07007421
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007422 case ENABLE_SCREEN: {
7423 performEnableScreen();
7424 break;
7425 }
Romain Guy06882f82009-06-10 13:36:04 -07007426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007427 case APP_FREEZE_TIMEOUT: {
7428 synchronized (mWindowMap) {
Craig Mautner96868332012-12-04 14:29:11 -08007429 Slog.w(TAG, "App freeze timeout expired.");
Craig Mautnerdc548482014-02-05 13:35:24 -08007430 final int numStacks = mStackIdToStack.size();
7431 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
7432 final TaskStack stack = mStackIdToStack.valueAt(stackNdx);
7433 final ArrayList<Task> tasks = stack.getTasks();
7434 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
7435 AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
7436 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
7437 AppWindowToken tok = tokens.get(tokenNdx);
7438 if (tok.mAppAnimator.freezingScreen) {
7439 Slog.w(TAG, "Force clearing freeze: " + tok);
7440 unsetAppFreezingScreenLocked(tok, true, true);
7441 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08007442 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007443 }
7444 }
7445 }
7446 break;
7447 }
Romain Guy06882f82009-06-10 13:36:04 -07007448
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007449 case CLIENT_FREEZE_TIMEOUT: {
7450 synchronized (mWindowMap) {
7451 if (mClientFreezingScreen) {
7452 mClientFreezingScreen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07007453 mLastFinishedFreezeSource = "client-timeout";
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007454 stopFreezingDisplayLocked();
7455 }
7456 }
7457 break;
7458 }
7459
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007460 case SEND_NEW_CONFIGURATION: {
7461 removeMessages(SEND_NEW_CONFIGURATION);
7462 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07007463 break;
7464 }
Romain Guy06882f82009-06-10 13:36:04 -07007465
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07007466 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007467 if (mWindowsChanged) {
7468 synchronized (mWindowMap) {
7469 mWindowsChanged = false;
7470 }
7471 notifyWindowsChanged();
7472 }
7473 break;
7474 }
7475
Christopher Tatea53146c2010-09-07 11:57:52 -07007476 case DRAG_START_TIMEOUT: {
7477 IBinder win = (IBinder)msg.obj;
7478 if (DEBUG_DRAG) {
7479 Slog.w(TAG, "Timeout starting drag by win " + win);
7480 }
7481 synchronized (mWindowMap) {
7482 // !!! TODO: ANR the app that has failed to start the drag in time
7483 if (mDragState != null) {
Chris Tated4533f12010-10-19 15:15:08 -07007484 mDragState.unregister();
Jeff Brown2e44b072011-01-24 15:21:56 -08007485 mInputMonitor.updateInputWindowsLw(true /*force*/);
Christopher Tatea53146c2010-09-07 11:57:52 -07007486 mDragState.reset();
7487 mDragState = null;
7488 }
7489 }
Chris Tated4533f12010-10-19 15:15:08 -07007490 break;
Christopher Tatea53146c2010-09-07 11:57:52 -07007491 }
7492
Chris Tated4533f12010-10-19 15:15:08 -07007493 case DRAG_END_TIMEOUT: {
7494 IBinder win = (IBinder)msg.obj;
7495 if (DEBUG_DRAG) {
7496 Slog.w(TAG, "Timeout ending drag to win " + win);
7497 }
7498 synchronized (mWindowMap) {
7499 // !!! TODO: ANR the drag-receiving app
Christopher Tated9be36c2011-08-16 16:09:33 -07007500 if (mDragState != null) {
7501 mDragState.mDragResult = false;
7502 mDragState.endDragLw();
7503 }
Chris Tated4533f12010-10-19 15:15:08 -07007504 }
7505 break;
7506 }
Jeff Brown2992ea72011-01-28 22:04:14 -08007507
7508 case REPORT_HARD_KEYBOARD_STATUS_CHANGE: {
7509 notifyHardKeyboardStatusChange();
7510 break;
7511 }
Dianne Hackborn38e29a62011-09-18 14:43:08 -07007512
7513 case BOOT_TIMEOUT: {
7514 performBootTimeout();
7515 break;
7516 }
7517
7518 case WAITING_FOR_DRAWN_TIMEOUT: {
7519 Pair<WindowState, IRemoteCallback> pair;
7520 synchronized (mWindowMap) {
7521 pair = (Pair<WindowState, IRemoteCallback>)msg.obj;
7522 Slog.w(TAG, "Timeout waiting for drawn: " + pair.first);
7523 if (!mWaitingForDrawn.remove(pair)) {
7524 return;
7525 }
7526 }
7527 try {
7528 pair.second.sendResult(null);
7529 } catch (RemoteException e) {
7530 }
7531 break;
7532 }
Craig Mautnera608b882012-03-30 13:03:49 -07007533
Craig Mautner0447a812012-05-22 16:01:31 -07007534 case SHOW_STRICT_MODE_VIOLATION: {
Chris Craik3198ef32012-10-10 14:52:30 -07007535 showStrictModeViolation(msg.arg1, msg.arg2);
Craig Mautner0447a812012-05-22 16:01:31 -07007536 break;
7537 }
7538
Dianne Hackborn84375872012-06-01 19:03:50 -07007539 case DO_ANIMATION_CALLBACK: {
7540 try {
7541 ((IRemoteCallback)msg.obj).sendResult(null);
7542 } catch (RemoteException e) {
7543 }
7544 break;
7545 }
Craig Mautner722285e2012-09-07 13:55:58 -07007546
Craig Mautner722285e2012-09-07 13:55:58 -07007547 case DO_DISPLAY_ADDED:
Craig Mautnerad25fa32014-01-12 21:19:06 -08007548 handleDisplayAdded(msg.arg1);
Craig Mautner722285e2012-09-07 13:55:58 -07007549 break;
7550
7551 case DO_DISPLAY_REMOVED:
7552 synchronized (mWindowMap) {
7553 handleDisplayRemovedLocked(msg.arg1);
7554 }
7555 break;
7556
7557 case DO_DISPLAY_CHANGED:
7558 synchronized (mWindowMap) {
7559 handleDisplayChangedLocked(msg.arg1);
7560 }
7561 break;
Craig Mautnerd3c93382013-04-24 14:23:39 -07007562
Craig Mautnereb957862013-04-24 15:34:32 -07007563 case TAP_OUTSIDE_STACK: {
7564 int stackId;
Craig Mautnerd3c93382013-04-24 14:23:39 -07007565 synchronized (mWindowMap) {
Craig Mautnereb957862013-04-24 15:34:32 -07007566 stackId = ((DisplayContent)msg.obj).stackIdFromPoint(msg.arg1, msg.arg2);
7567 }
7568 if (stackId >= 0) {
7569 try {
7570 mActivityManager.setFocusedStack(stackId);
7571 } catch (RemoteException e) {
Craig Mautnerd3c93382013-04-24 14:23:39 -07007572 }
7573 }
Craig Mautnereb957862013-04-24 15:34:32 -07007574 }
Craig Mautner5eda9b32013-07-02 11:58:16 -07007575 break;
7576 case NOTIFY_ACTIVITY_DRAWN:
7577 try {
7578 mActivityManager.notifyActivityDrawn((IBinder) msg.obj);
7579 } catch (RemoteException e) {
7580 }
7581 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007582 }
Craig Mautner7d8df392012-04-06 15:26:23 -07007583 if (DEBUG_WINDOW_TRACE) {
7584 Slog.v(TAG, "handleMessage: exit");
7585 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007586 }
7587 }
7588
7589 // -------------------------------------------------------------
7590 // IWindowManager API
7591 // -------------------------------------------------------------
7592
Craig Mautner7d8df392012-04-06 15:26:23 -07007593 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007594 public IWindowSession openSession(IInputMethodClient client,
7595 IInputContext inputContext) {
7596 if (client == null) throw new IllegalArgumentException("null client");
7597 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08007598 Session session = new Session(this, client, inputContext);
Jeff Brown46b9ac02010-04-22 18:58:52 -07007599 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007600 }
7601
Craig Mautner7d8df392012-04-06 15:26:23 -07007602 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007603 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
7604 synchronized (mWindowMap) {
7605 // The focus for the client is the window immediately below
7606 // where we would place the input method window.
7607 int idx = findDesiredInputMethodWindowIndexLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007608 if (idx > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07007609 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007610 WindowState imFocus = getDefaultWindowListLocked().get(idx-1);
Dianne Hackbornac920872012-05-22 11:49:49 -07007611 if (DEBUG_INPUT_METHOD) {
7612 Slog.i(TAG, "Desired input method target: " + imFocus);
Craig Mautner59c00972012-07-30 12:10:24 -07007613 Slog.i(TAG, "Current focus: " + mCurrentFocus);
7614 Slog.i(TAG, "Last focus: " + mLastFocus);
Dianne Hackbornac920872012-05-22 11:49:49 -07007615 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007616 if (imFocus != null) {
Dianne Hackborne75d8722011-01-27 19:37:40 -08007617 // This may be a starting window, in which case we still want
7618 // to count it as okay.
7619 if (imFocus.mAttrs.type == LayoutParams.TYPE_APPLICATION_STARTING
7620 && imFocus.mAppToken != null) {
7621 // The client has definitely started, so it really should
7622 // have a window in this app token. Let's look for it.
7623 for (int i=0; i<imFocus.mAppToken.windows.size(); i++) {
7624 WindowState w = imFocus.mAppToken.windows.get(i);
7625 if (w != imFocus) {
Dianne Hackbornac920872012-05-22 11:49:49 -07007626 Log.i(TAG, "Switching to real app window: " + w);
Dianne Hackborne75d8722011-01-27 19:37:40 -08007627 imFocus = w;
7628 break;
7629 }
7630 }
7631 }
Dianne Hackbornac920872012-05-22 11:49:49 -07007632 if (DEBUG_INPUT_METHOD) {
7633 Slog.i(TAG, "IM target client: " + imFocus.mSession.mClient);
7634 if (imFocus.mSession.mClient != null) {
7635 Slog.i(TAG, "IM target client binder: "
7636 + imFocus.mSession.mClient.asBinder());
7637 Slog.i(TAG, "Requesting client binder: " + client.asBinder());
7638 }
7639 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007640 if (imFocus.mSession.mClient != null &&
7641 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
7642 return true;
7643 }
7644 }
7645 }
Craig Mautner59c00972012-07-30 12:10:24 -07007646
7647 // Okay, how about this... what is the current focus?
7648 // It seems in some cases we may not have moved the IM
7649 // target window, such as when it was in a pop-up window,
7650 // so let's also look at the current focus. (An example:
7651 // go to Gmail, start searching so the keyboard goes up,
7652 // press home. Sometimes the IME won't go down.)
7653 // Would be nice to fix this more correctly, but it's
7654 // way at the end of a release, and this should be good enough.
7655 if (mCurrentFocus != null && mCurrentFocus.mSession.mClient != null
7656 && mCurrentFocus.mSession.mClient.asBinder() == client.asBinder()) {
7657 return true;
7658 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007659 }
7660 return false;
7661 }
Romain Guy06882f82009-06-10 13:36:04 -07007662
Dianne Hackborn672cf452013-03-26 15:24:24 -07007663 @Override
Craig Mautner59c00972012-07-30 12:10:24 -07007664 public void getInitialDisplaySize(int displayId, Point size) {
Craig Mautner58106812012-12-28 12:27:40 -08007665 synchronized (mWindowMap) {
7666 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Jeff Browna506a6e2013-06-04 00:02:38 -07007667 if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
Craig Mautner58106812012-12-28 12:27:40 -08007668 synchronized(displayContent.mDisplaySizeLock) {
7669 size.x = displayContent.mInitialDisplayWidth;
7670 size.y = displayContent.mInitialDisplayHeight;
7671 }
Craig Mautner2d5618c2012-10-18 13:55:47 -07007672 }
Dianne Hackborn7d608422011-08-07 16:24:18 -07007673 }
7674 }
7675
Craig Mautner2d5618c2012-10-18 13:55:47 -07007676 @Override
Dianne Hackborn672cf452013-03-26 15:24:24 -07007677 public void getBaseDisplaySize(int displayId, Point size) {
7678 synchronized (mWindowMap) {
7679 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Jeff Browna506a6e2013-06-04 00:02:38 -07007680 if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
Dianne Hackborn672cf452013-03-26 15:24:24 -07007681 synchronized(displayContent.mDisplaySizeLock) {
7682 size.x = displayContent.mBaseDisplayWidth;
7683 size.y = displayContent.mBaseDisplayHeight;
7684 }
7685 }
7686 }
7687 }
7688
7689 @Override
Jeff Brown43aa1592012-09-10 17:36:31 -07007690 public void setForcedDisplaySize(int displayId, int width, int height) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08007691 if (mContext.checkCallingOrSelfPermission(
7692 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7693 PackageManager.PERMISSION_GRANTED) {
7694 throw new SecurityException("Must hold permission " +
7695 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7696 }
7697 if (displayId != Display.DEFAULT_DISPLAY) {
7698 throw new IllegalArgumentException("Can only set the default display");
7699 }
Dianne Hackborn0cca3db2013-10-23 10:23:39 -07007700 final long ident = Binder.clearCallingIdentity();
7701 try {
7702 synchronized(mWindowMap) {
7703 // Set some sort of reasonable bounds on the size of the display that we
7704 // will try to emulate.
7705 final int MIN_WIDTH = 200;
7706 final int MIN_HEIGHT = 200;
7707 final int MAX_SCALE = 2;
7708 final DisplayContent displayContent = getDisplayContentLocked(displayId);
7709 if (displayContent != null) {
7710 width = Math.min(Math.max(width, MIN_WIDTH),
7711 displayContent.mInitialDisplayWidth * MAX_SCALE);
7712 height = Math.min(Math.max(height, MIN_HEIGHT),
7713 displayContent.mInitialDisplayHeight * MAX_SCALE);
7714 setForcedDisplaySizeLocked(displayContent, width, height);
7715 Settings.Global.putString(mContext.getContentResolver(),
7716 Settings.Global.DISPLAY_SIZE_FORCED, width + "," + height);
7717 }
Craig Mautner2d5618c2012-10-18 13:55:47 -07007718 }
Dianne Hackborn0cca3db2013-10-23 10:23:39 -07007719 } finally {
7720 Binder.restoreCallingIdentity(ident);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007721 }
7722 }
7723
Dianne Hackborndde331c2012-08-03 14:01:57 -07007724 private void readForcedDisplaySizeAndDensityLocked(final DisplayContent displayContent) {
Colin Crossef96fd92013-07-18 17:09:56 -07007725 String sizeStr = Settings.Global.getString(mContext.getContentResolver(),
Jeff Brown43aa1592012-09-10 17:36:31 -07007726 Settings.Global.DISPLAY_SIZE_FORCED);
Dianne Hackborn635a6d52013-07-29 17:15:38 -07007727 if (sizeStr == null || sizeStr.length() == 0) {
Colin Crossef96fd92013-07-18 17:09:56 -07007728 sizeStr = SystemProperties.get(SIZE_OVERRIDE, null);
7729 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007730 if (sizeStr != null && sizeStr.length() > 0) {
7731 final int pos = sizeStr.indexOf(',');
7732 if (pos > 0 && sizeStr.lastIndexOf(',') == pos) {
7733 int width, height;
7734 try {
7735 width = Integer.parseInt(sizeStr.substring(0, pos));
7736 height = Integer.parseInt(sizeStr.substring(pos+1));
7737 synchronized(displayContent.mDisplaySizeLock) {
7738 if (displayContent.mBaseDisplayWidth != width
7739 || displayContent.mBaseDisplayHeight != height) {
Dianne Hackborndde331c2012-08-03 14:01:57 -07007740 Slog.i(TAG, "FORCED DISPLAY SIZE: " + width + "x" + height);
7741 displayContent.mBaseDisplayWidth = width;
7742 displayContent.mBaseDisplayHeight = height;
7743 }
7744 }
7745 } catch (NumberFormatException ex) {
7746 }
7747 }
Joe Onorato571ae902011-05-24 13:48:43 -07007748 }
Colin Crossef96fd92013-07-18 17:09:56 -07007749 String densityStr = Settings.Global.getString(mContext.getContentResolver(),
Jeff Brown43aa1592012-09-10 17:36:31 -07007750 Settings.Global.DISPLAY_DENSITY_FORCED);
Dianne Hackborn635a6d52013-07-29 17:15:38 -07007751 if (densityStr == null || densityStr.length() == 0) {
Colin Crossef96fd92013-07-18 17:09:56 -07007752 densityStr = SystemProperties.get(DENSITY_OVERRIDE, null);
7753 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007754 if (densityStr != null && densityStr.length() > 0) {
7755 int density;
7756 try {
7757 density = Integer.parseInt(densityStr);
7758 synchronized(displayContent.mDisplaySizeLock) {
7759 if (displayContent.mBaseDisplayDensity != density) {
Dianne Hackborndde331c2012-08-03 14:01:57 -07007760 Slog.i(TAG, "FORCED DISPLAY DENSITY: " + density);
7761 displayContent.mBaseDisplayDensity = density;
7762 }
7763 }
7764 } catch (NumberFormatException ex) {
7765 }
Joe Onorato571ae902011-05-24 13:48:43 -07007766 }
Joe Onorato571ae902011-05-24 13:48:43 -07007767 }
7768
Craig Mautner2d5618c2012-10-18 13:55:47 -07007769 // displayContent must not be null
Craig Mautner59c00972012-07-30 12:10:24 -07007770 private void setForcedDisplaySizeLocked(DisplayContent displayContent, int width, int height) {
Joe Onorato571ae902011-05-24 13:48:43 -07007771 Slog.i(TAG, "Using new display size: " + width + "x" + height);
7772
Craig Mautner59c00972012-07-30 12:10:24 -07007773 synchronized(displayContent.mDisplaySizeLock) {
7774 displayContent.mBaseDisplayWidth = width;
7775 displayContent.mBaseDisplayHeight = height;
Dianne Hackborn1fbee792011-11-30 11:29:58 -08007776 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007777 reconfigureDisplayLocked(displayContent);
7778 }
7779
Craig Mautner2d5618c2012-10-18 13:55:47 -07007780 @Override
Dianne Hackborndde331c2012-08-03 14:01:57 -07007781 public void clearForcedDisplaySize(int displayId) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08007782 if (mContext.checkCallingOrSelfPermission(
7783 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7784 PackageManager.PERMISSION_GRANTED) {
7785 throw new SecurityException("Must hold permission " +
7786 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7787 }
7788 if (displayId != Display.DEFAULT_DISPLAY) {
7789 throw new IllegalArgumentException("Can only set the default display");
7790 }
Dianne Hackborn0cca3db2013-10-23 10:23:39 -07007791 final long ident = Binder.clearCallingIdentity();
7792 try {
7793 synchronized(mWindowMap) {
7794 final DisplayContent displayContent = getDisplayContentLocked(displayId);
7795 if (displayContent != null) {
7796 setForcedDisplaySizeLocked(displayContent, displayContent.mInitialDisplayWidth,
7797 displayContent.mInitialDisplayHeight);
7798 Settings.Global.putString(mContext.getContentResolver(),
7799 Settings.Global.DISPLAY_SIZE_FORCED, "");
7800 }
Craig Mautner2d5618c2012-10-18 13:55:47 -07007801 }
Dianne Hackborn0cca3db2013-10-23 10:23:39 -07007802 } finally {
7803 Binder.restoreCallingIdentity(ident);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007804 }
7805 }
7806
Craig Mautner2d5618c2012-10-18 13:55:47 -07007807 @Override
Dianne Hackborn672cf452013-03-26 15:24:24 -07007808 public int getInitialDisplayDensity(int displayId) {
7809 synchronized (mWindowMap) {
7810 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Jeff Browna506a6e2013-06-04 00:02:38 -07007811 if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
Dianne Hackborn672cf452013-03-26 15:24:24 -07007812 synchronized(displayContent.mDisplaySizeLock) {
7813 return displayContent.mInitialDisplayDensity;
7814 }
7815 }
7816 }
7817 return -1;
7818 }
7819
7820 @Override
7821 public int getBaseDisplayDensity(int displayId) {
7822 synchronized (mWindowMap) {
7823 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Jeff Browna506a6e2013-06-04 00:02:38 -07007824 if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
Dianne Hackborn672cf452013-03-26 15:24:24 -07007825 synchronized(displayContent.mDisplaySizeLock) {
7826 return displayContent.mBaseDisplayDensity;
7827 }
7828 }
7829 }
7830 return -1;
7831 }
7832
7833 @Override
Dianne Hackborndde331c2012-08-03 14:01:57 -07007834 public void setForcedDisplayDensity(int displayId, int density) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08007835 if (mContext.checkCallingOrSelfPermission(
7836 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7837 PackageManager.PERMISSION_GRANTED) {
7838 throw new SecurityException("Must hold permission " +
7839 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7840 }
7841 if (displayId != Display.DEFAULT_DISPLAY) {
7842 throw new IllegalArgumentException("Can only set the default display");
7843 }
Dianne Hackborn0cca3db2013-10-23 10:23:39 -07007844 final long ident = Binder.clearCallingIdentity();
7845 try {
7846 synchronized(mWindowMap) {
7847 final DisplayContent displayContent = getDisplayContentLocked(displayId);
7848 if (displayContent != null) {
7849 setForcedDisplayDensityLocked(displayContent, density);
7850 Settings.Global.putString(mContext.getContentResolver(),
7851 Settings.Global.DISPLAY_DENSITY_FORCED, Integer.toString(density));
7852 }
Craig Mautner2d5618c2012-10-18 13:55:47 -07007853 }
Dianne Hackborn0cca3db2013-10-23 10:23:39 -07007854 } finally {
7855 Binder.restoreCallingIdentity(ident);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007856 }
7857 }
7858
Craig Mautner2d5618c2012-10-18 13:55:47 -07007859 // displayContent must not be null
Dianne Hackborndde331c2012-08-03 14:01:57 -07007860 private void setForcedDisplayDensityLocked(DisplayContent displayContent, int density) {
7861 Slog.i(TAG, "Using new display density: " + density);
7862
7863 synchronized(displayContent.mDisplaySizeLock) {
7864 displayContent.mBaseDisplayDensity = density;
7865 }
7866 reconfigureDisplayLocked(displayContent);
7867 }
7868
Craig Mautner2d5618c2012-10-18 13:55:47 -07007869 @Override
Dianne Hackborndde331c2012-08-03 14:01:57 -07007870 public void clearForcedDisplayDensity(int displayId) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08007871 if (mContext.checkCallingOrSelfPermission(
7872 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7873 PackageManager.PERMISSION_GRANTED) {
7874 throw new SecurityException("Must hold permission " +
7875 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7876 }
7877 if (displayId != Display.DEFAULT_DISPLAY) {
7878 throw new IllegalArgumentException("Can only set the default display");
7879 }
Dianne Hackborn0cca3db2013-10-23 10:23:39 -07007880 final long ident = Binder.clearCallingIdentity();
7881 try {
7882 synchronized(mWindowMap) {
7883 final DisplayContent displayContent = getDisplayContentLocked(displayId);
7884 if (displayContent != null) {
7885 setForcedDisplayDensityLocked(displayContent,
7886 displayContent.mInitialDisplayDensity);
7887 Settings.Global.putString(mContext.getContentResolver(),
7888 Settings.Global.DISPLAY_DENSITY_FORCED, "");
7889 }
Craig Mautner2d5618c2012-10-18 13:55:47 -07007890 }
Dianne Hackborn0cca3db2013-10-23 10:23:39 -07007891 } finally {
7892 Binder.restoreCallingIdentity(ident);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007893 }
7894 }
7895
Craig Mautner2d5618c2012-10-18 13:55:47 -07007896 // displayContent must not be null
Dianne Hackborndde331c2012-08-03 14:01:57 -07007897 private void reconfigureDisplayLocked(DisplayContent displayContent) {
Craig Mautner69b08182012-09-05 13:07:13 -07007898 // TODO: Multidisplay: for now only use with default display.
Jeff Brownef981a42013-08-07 14:13:37 -07007899 configureDisplayPolicyLocked(displayContent);
Craig Mautner19d59bc2012-09-04 11:15:56 -07007900 displayContent.layoutNeeded = true;
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007901
7902 boolean configChanged = updateOrientationFromAppTokensLocked(false);
7903 mTempConfiguration.setToDefaults();
7904 mTempConfiguration.fontScale = mCurConfiguration.fontScale;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08007905 if (computeScreenConfigurationLocked(mTempConfiguration)) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007906 if (mCurConfiguration.diff(mTempConfiguration) != 0) {
7907 configChanged = true;
7908 }
7909 }
7910
7911 if (configChanged) {
7912 mWaitingForConfig = true;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007913 startFreezingDisplayLocked(false, 0, 0);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007914 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
7915 }
7916
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007917 performLayoutAndPlaceSurfacesLocked();
7918 }
7919
Jeff Brownef981a42013-08-07 14:13:37 -07007920 private void configureDisplayPolicyLocked(DisplayContent displayContent) {
7921 mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
7922 displayContent.mBaseDisplayWidth,
7923 displayContent.mBaseDisplayHeight,
7924 displayContent.mBaseDisplayDensity);
7925
7926 DisplayInfo displayInfo = displayContent.getDisplayInfo();
7927 mPolicy.setDisplayOverscan(displayContent.getDisplay(),
7928 displayInfo.overscanLeft, displayInfo.overscanTop,
7929 displayInfo.overscanRight, displayInfo.overscanBottom);
7930 }
7931
Craig Mautner11bf9a52013-02-19 14:08:51 -08007932 @Override
Dianne Hackbornc652de82013-02-15 16:32:56 -08007933 public void setOverscan(int displayId, int left, int top, int right, int bottom) {
7934 if (mContext.checkCallingOrSelfPermission(
7935 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7936 PackageManager.PERMISSION_GRANTED) {
7937 throw new SecurityException("Must hold permission " +
7938 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7939 }
Dianne Hackborn0cca3db2013-10-23 10:23:39 -07007940 final long ident = Binder.clearCallingIdentity();
7941 try {
7942 synchronized(mWindowMap) {
7943 DisplayContent displayContent = getDisplayContentLocked(displayId);
7944 if (displayContent != null) {
7945 setOverscanLocked(displayContent, left, top, right, bottom);
7946 }
Dianne Hackbornc652de82013-02-15 16:32:56 -08007947 }
Dianne Hackborn0cca3db2013-10-23 10:23:39 -07007948 } finally {
7949 Binder.restoreCallingIdentity(ident);
Dianne Hackbornc652de82013-02-15 16:32:56 -08007950 }
7951 }
7952
Jeff Brownef981a42013-08-07 14:13:37 -07007953 private void setOverscanLocked(DisplayContent displayContent,
7954 int left, int top, int right, int bottom) {
7955 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
7956 synchronized (displayContent.mDisplaySizeLock) {
7957 displayInfo.overscanLeft = left;
7958 displayInfo.overscanTop = top;
7959 displayInfo.overscanRight = right;
7960 displayInfo.overscanBottom = bottom;
7961 }
7962
7963 mDisplaySettings.setOverscanLocked(displayInfo.name, left, top, right, bottom);
7964 mDisplaySettings.writeSettingsLocked();
7965
7966 reconfigureDisplayLocked(displayContent);
7967 }
7968
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007969 // -------------------------------------------------------------
7970 // Internals
7971 // -------------------------------------------------------------
7972
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007973 final WindowState windowForClientLocked(Session session, IWindow client,
7974 boolean throwOnError) {
7975 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007976 }
Romain Guy06882f82009-06-10 13:36:04 -07007977
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007978 final WindowState windowForClientLocked(Session session, IBinder client,
7979 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007980 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007981 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007982 TAG, "Looking up client " + client + ": " + win);
7983 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007984 RuntimeException ex = new IllegalArgumentException(
7985 "Requested window " + client + " does not exist");
7986 if (throwOnError) {
7987 throw ex;
7988 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007989 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007990 return null;
7991 }
7992 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007993 RuntimeException ex = new IllegalArgumentException(
7994 "Requested window " + client + " is in session " +
7995 win.mSession + ", not " + session);
7996 if (throwOnError) {
7997 throw ex;
7998 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007999 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008000 return null;
8001 }
8002
8003 return win;
8004 }
8005
Dianne Hackborna8f60182009-09-01 19:01:50 -07008006 final void rebuildAppWindowListLocked() {
Craig Mautner85689b92013-10-02 14:52:13 -07008007 rebuildAppWindowListLocked(getDefaultDisplayContentLocked());
Craig Mautner59c00972012-07-30 12:10:24 -07008008 }
8009
8010 private void rebuildAppWindowListLocked(final DisplayContent displayContent) {
8011 final WindowList windows = displayContent.getWindowList();
8012 int NW = windows.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07008013 int i;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008014 int lastBelow = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008015 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008016
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008017 if (mRebuildTmp.length < NW) {
8018 mRebuildTmp = new WindowState[NW+10];
8019 }
8020
Dianne Hackborna8f60182009-09-01 19:01:50 -07008021 // First remove all existing app windows.
8022 i=0;
8023 while (i < NW) {
Craig Mautner59c00972012-07-30 12:10:24 -07008024 WindowState w = windows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008025 if (w.mAppToken != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07008026 WindowState win = windows.remove(i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008027 win.mRebuilding = true;
8028 mRebuildTmp[numRemoved] = win;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008029 mWindowsChanged = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07008030 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008031 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008032 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07008033 continue;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008034 } else if (lastBelow == i-1) {
Craig Mautner65d11b32012-10-01 13:59:52 -07008035 if (w.mAttrs.type == TYPE_WALLPAPER || w.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008036 lastBelow = i;
8037 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07008038 }
8039 i++;
8040 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008041
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008042 // Keep whatever windows were below the app windows still below,
8043 // by skipping them.
8044 lastBelow++;
8045 i = lastBelow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008046
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008047 // First add all of the exiting app tokens... these are no longer
8048 // in the main app list, but still have windows shown. We put them
8049 // in the back because now that the animation is over we no longer
8050 // will care about them.
Craig Mautnerdc548482014-02-05 13:35:24 -08008051 final ArrayList<TaskStack> stacks = displayContent.getStacks();
8052 final int numStacks = stacks.size();
8053 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
8054 AppTokenList exitingAppTokens = stacks.get(stackNdx).mExitingAppTokens;
8055 int NT = exitingAppTokens.size();
8056 for (int j = 0; j < NT; j++) {
8057 i = reAddAppWindowsLocked(displayContent, i, exitingAppTokens.get(j));
8058 }
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008059 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008060
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008061 // And add in the still active app tokens in Z order.
Craig Mautnerdc548482014-02-05 13:35:24 -08008062 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
8063 final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
8064 final int numTasks = tasks.size();
8065 for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
8066 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
8067 final int numTokens = tokens.size();
8068 for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
8069 final AppWindowToken wtoken = tokens.get(tokenNdx);
8070 i = reAddAppWindowsLocked(displayContent, i, wtoken);
8071 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08008072 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07008073 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008074
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008075 i -= lastBelow;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008076 if (i != numRemoved) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08008077 Slog.w(TAG, "On display=" + displayContent.getDisplayId() + " Rebuild removed " +
8078 numRemoved + " windows but added " + i,
Craig Mautner9e4f28c2013-04-03 10:53:23 -07008079 new RuntimeException("here").fillInStackTrace());
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008080 for (i=0; i<numRemoved; i++) {
8081 WindowState ws = mRebuildTmp[i];
8082 if (ws.mRebuilding) {
8083 StringWriter sw = new StringWriter();
Dianne Hackborn8c841092013-06-24 13:46:13 -07008084 PrintWriter pw = new FastPrintWriter(sw, false, 1024);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07008085 ws.dump(pw, "", true);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008086 pw.flush();
8087 Slog.w(TAG, "This window was lost: " + ws);
8088 Slog.w(TAG, sw.toString());
Craig Mautner96868332012-12-04 14:29:11 -08008089 ws.mWinAnimator.destroySurfaceLocked();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008090 }
8091 }
8092 Slog.w(TAG, "Current app token list:");
Craig Mautner496bdbb2013-02-14 09:32:55 -08008093 dumpAppTokensLocked();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008094 Slog.w(TAG, "Final window list:");
8095 dumpWindowsLocked();
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008096 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07008097 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008098
Craig Mautner59c00972012-07-30 12:10:24 -07008099 private final void assignLayersLocked(WindowList windows) {
8100 int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008101 int curBaseLayer = 0;
8102 int curLayer = 0;
8103 int i;
Romain Guy06882f82009-06-10 13:36:04 -07008104
Craig Mautner018be3d2013-08-27 13:25:17 -07008105 if (DEBUG_LAYERS) Slog.v(TAG, "Assigning layers based on windows=" + windows,
8106 new RuntimeException("here").fillInStackTrace());
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08008107
Svetoslav Ganov55468c62012-10-15 15:09:02 -07008108 boolean anyLayerChanged = false;
8109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008110 for (i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07008111 final WindowState w = windows.get(i);
Craig Mautneracafd192012-05-10 10:41:02 -07008112 final WindowStateAnimator winAnimator = w.mWinAnimator;
8113 boolean layerChanged = false;
8114 int oldLayer = w.mLayer;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008115 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
8116 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008117 curLayer += WINDOW_LAYER_MULTIPLIER;
8118 w.mLayer = curLayer;
8119 } else {
8120 curBaseLayer = curLayer = w.mBaseLayer;
8121 w.mLayer = curLayer;
8122 }
Craig Mautneracafd192012-05-10 10:41:02 -07008123 if (w.mLayer != oldLayer) {
8124 layerChanged = true;
Svetoslav Ganov55468c62012-10-15 15:09:02 -07008125 anyLayerChanged = true;
Craig Mautneracafd192012-05-10 10:41:02 -07008126 }
Craig Mautnerf7666462013-04-28 08:58:21 -07008127 final AppWindowToken wtoken = w.mAppToken;
Craig Mautneracafd192012-05-10 10:41:02 -07008128 oldLayer = winAnimator.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008129 if (w.mTargetAppToken != null) {
Craig Mautneracafd192012-05-10 10:41:02 -07008130 winAnimator.mAnimLayer =
Craig Mautner59431632012-04-04 11:56:44 -07008131 w.mLayer + w.mTargetAppToken.mAppAnimator.animLayerAdjustment;
Craig Mautnerf7666462013-04-28 08:58:21 -07008132 } else if (wtoken != null) {
Craig Mautneracafd192012-05-10 10:41:02 -07008133 winAnimator.mAnimLayer =
Craig Mautnerf7666462013-04-28 08:58:21 -07008134 w.mLayer + wtoken.mAppAnimator.animLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008135 } else {
Craig Mautneracafd192012-05-10 10:41:02 -07008136 winAnimator.mAnimLayer = w.mLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008137 }
8138 if (w.mIsImWindow) {
Craig Mautneracafd192012-05-10 10:41:02 -07008139 winAnimator.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008140 } else if (w.mIsWallpaper) {
Craig Mautneracafd192012-05-10 10:41:02 -07008141 winAnimator.mAnimLayer += mWallpaperAnimLayerAdjustment;
8142 }
8143 if (winAnimator.mAnimLayer != oldLayer) {
8144 layerChanged = true;
Svetoslav Ganov55468c62012-10-15 15:09:02 -07008145 anyLayerChanged = true;
Craig Mautneracafd192012-05-10 10:41:02 -07008146 }
Craig Mautner05d29032013-05-03 13:40:13 -07008147 if (layerChanged && w.getStack().isDimming(winAnimator)) {
8148 // Force an animation pass just to update the mDimLayer layer.
Craig Mautner96868332012-12-04 14:29:11 -08008149 scheduleAnimationLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008150 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008151 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
Craig Mautner8863cca2012-09-18 15:04:34 -07008152 + "mBase=" + w.mBaseLayer
8153 + " mLayer=" + w.mLayer
Craig Mautnerf7666462013-04-28 08:58:21 -07008154 + (wtoken == null ?
8155 "" : " mAppLayer=" + wtoken.mAppAnimator.animLayerAdjustment)
Craig Mautner8863cca2012-09-18 15:04:34 -07008156 + " =mAnimLayer=" + winAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008157 //System.out.println(
8158 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
8159 }
Svetoslav Ganov55468c62012-10-15 15:09:02 -07008160
Svetoslav Ganov545252f2012-12-10 18:29:24 -08008161 //TODO (multidisplay): Magnification is supported only for the default display.
8162 if (mDisplayMagnifier != null && anyLayerChanged
8163 && windows.get(windows.size() - 1).getDisplayId() == Display.DEFAULT_DISPLAY) {
8164 mDisplayMagnifier.onWindowLayersChangedLocked();
Svetoslav Ganov55468c62012-10-15 15:09:02 -07008165 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008166 }
8167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008168 private final void performLayoutAndPlaceSurfacesLocked() {
Dianne Hackborn7ad44382012-10-18 17:46:00 -07008169 int loopCount = 6;
Craig Mautnera13a41d2012-10-16 12:53:13 -07008170 do {
8171 mTraversalScheduled = false;
8172 performLayoutAndPlaceSurfacesLockedLoop();
8173 mH.removeMessages(H.DO_TRAVERSAL);
Dianne Hackborn7ad44382012-10-18 17:46:00 -07008174 loopCount--;
8175 } while (mTraversalScheduled && loopCount > 0);
Craig Mautner96868332012-12-04 14:29:11 -08008176 mInnerFields.mWallpaperActionPending = false;
Craig Mautnera13a41d2012-10-16 12:53:13 -07008177 }
8178
8179 private boolean mInLayout = false;
8180 private final void performLayoutAndPlaceSurfacesLockedLoop() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008181 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07008182 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008183 throw new RuntimeException("Recursive call!");
8184 }
Craig Mautneref25d7a2012-05-15 23:01:47 -07008185 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
8186 + Debug.getCallers(3));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008187 return;
8188 }
8189
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008190 if (mWaitingForConfig) {
8191 // Our configuration has changed (most likely rotation), but we
8192 // don't yet have the complete configuration to report to
8193 // applications. Don't do any window layout until we have it.
8194 return;
8195 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08008196
Jeff Browne215f262012-09-10 16:01:14 -07008197 if (!mDisplayReady) {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008198 // Not yet initialized, nothing to do.
8199 return;
8200 }
8201
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07008202 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008203 mInLayout = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008204 boolean recoveringMemory = false;
Craig Mautner6cfa7292013-01-15 09:05:42 -08008205
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008206 try {
8207 if (mForceRemoves != null) {
8208 recoveringMemory = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008209 // Wait a little bit for things to settle down, and off we go.
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008210 for (int i=0; i<mForceRemoves.size(); i++) {
8211 WindowState ws = mForceRemoves.get(i);
8212 Slog.i(TAG, "Force removing: " + ws);
8213 removeWindowInnerLocked(ws.mSession, ws);
8214 }
8215 mForceRemoves = null;
8216 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
8217 Object tmp = new Object();
8218 synchronized (tmp) {
8219 try {
8220 tmp.wait(250);
8221 } catch (InterruptedException e) {
8222 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008223 }
8224 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008225 } catch (RuntimeException e) {
Dianne Hackborn89620282011-09-11 12:47:45 -07008226 Log.wtf(TAG, "Unhandled exception while force removing for memory", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008227 }
Craig Mautner59c00972012-07-30 12:10:24 -07008228
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008229 try {
Craig Mautner76a71652012-09-03 23:23:58 -07008230 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Craig Mautnerbb1449b2012-03-23 16:11:14 -07008231
Craig Mautner59c00972012-07-30 12:10:24 -07008232 mInLayout = false;
8233
Craig Mautner19d59bc2012-09-04 11:15:56 -07008234 if (needsLayout()) {
Craig Mautnerbb1449b2012-03-23 16:11:14 -07008235 if (++mLayoutRepeatCount < 6) {
8236 requestTraversalLocked();
8237 } else {
8238 Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
8239 mLayoutRepeatCount = 0;
8240 }
8241 } else {
8242 mLayoutRepeatCount = 0;
8243 }
Craig Mautnerbb1449b2012-03-23 16:11:14 -07008244
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008245 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008246 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
You Kimcb6291c2012-12-04 23:22:28 +09008247 mH.sendEmptyMessage(H.REPORT_WINDOWS_CHANGE);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008248 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008249 } catch (RuntimeException e) {
8250 mInLayout = false;
Dianne Hackborn89620282011-09-11 12:47:45 -07008251 Log.wtf(TAG, "Unhandled exception while laying out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008252 }
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07008253
8254 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008255 }
8256
Craig Mautner59c00972012-07-30 12:10:24 -07008257 private final void performLayoutLockedInner(final DisplayContent displayContent,
8258 boolean initial, boolean updateInputWindows) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07008259 if (!displayContent.layoutNeeded) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008260 return;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008261 }
Craig Mautner19d59bc2012-09-04 11:15:56 -07008262 displayContent.layoutNeeded = false;
Craig Mautner59c00972012-07-30 12:10:24 -07008263 WindowList windows = displayContent.getWindowList();
Craig Mautner69b08182012-09-05 13:07:13 -07008264 boolean isDefaultDisplay = displayContent.isDefaultDisplay;
Craig Mautner59c00972012-07-30 12:10:24 -07008265
8266 DisplayInfo displayInfo = displayContent.getDisplayInfo();
8267 final int dw = displayInfo.logicalWidth;
8268 final int dh = displayInfo.logicalHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008269
Dianne Hackborndf89e652011-10-06 22:35:11 -07008270 final int NFW = mFakeWindows.size();
8271 for (int i=0; i<NFW; i++) {
8272 mFakeWindows.get(i).layout(dw, dh);
8273 }
8274
Craig Mautner59c00972012-07-30 12:10:24 -07008275 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008276 int i;
8277
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008278 if (DEBUG_LAYOUT) {
8279 Slog.v(TAG, "-------------------------------------");
8280 Slog.v(TAG, "performLayout: needed="
Craig Mautner19d59bc2012-09-04 11:15:56 -07008281 + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008282 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008283
8284 WindowStateAnimator universeBackground = null;
8285
Craig Mautner69b08182012-09-05 13:07:13 -07008286 mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mRotation);
8287 if (isDefaultDisplay) {
8288 // Not needed on non-default displays.
John Spurlock46646232013-09-30 22:32:42 -04008289 mSystemDecorLayer = mPolicy.getSystemDecorLayerLw();
Craig Mautner69b08182012-09-05 13:07:13 -07008290 mScreenRect.set(0, 0, dw, dh);
8291 }
Romain Guy06882f82009-06-10 13:36:04 -07008292
John Spurlock4e92a7c2013-09-24 17:09:05 -04008293 mPolicy.getContentRectLw(mTmpContentRect);
Craig Mautnerbdc748af2013-12-02 14:08:25 -08008294 displayContent.resize(mTmpContentRect);
Craig Mautner967212c2013-04-13 21:10:58 -07008295
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008296 int seq = mLayoutSeq+1;
8297 if (seq < 0) seq = 0;
8298 mLayoutSeq = seq;
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008299
8300 boolean behindDream = false;
8301
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008302 // First perform layout of any root windows (not attached
8303 // to another window).
8304 int topAttached = -1;
8305 for (i = N-1; i >= 0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07008306 final WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008307
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008308 // Don't do layout of a window if it is not visible, or
8309 // soon won't be visible, to avoid wasting time and funky
8310 // changes while a window is animating away.
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008311 final boolean gone = (behindDream && mPolicy.canBeForceHidden(win, win.mAttrs))
Craig Mautnerae446592012-12-06 19:05:05 -08008312 || win.isGoneForLayoutLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008313
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008314 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008315 Slog.v(TAG, "1ST PASS " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008316 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
Craig Mautner812d2ca2012-09-27 15:35:34 -07008317 + " mLayoutAttached=" + win.mLayoutAttached
Craig Mautnera3f4bf52012-10-10 20:37:48 -07008318 + " screen changed=" + win.isConfigChanged());
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008319 final AppWindowToken atoken = win.mAppToken;
8320 if (gone) Slog.v(TAG, " GONE: mViewVisibility="
8321 + win.mViewVisibility + " mRelayoutCalled="
8322 + win.mRelayoutCalled + " hidden="
8323 + win.mRootToken.hidden + " hiddenRequested="
8324 + (atoken != null && atoken.hiddenRequested)
8325 + " mAttachedHidden=" + win.mAttachedHidden);
8326 else Slog.v(TAG, " VIS: mViewVisibility="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008327 + win.mViewVisibility + " mRelayoutCalled="
8328 + win.mRelayoutCalled + " hidden="
8329 + win.mRootToken.hidden + " hiddenRequested="
8330 + (atoken != null && atoken.hiddenRequested)
8331 + " mAttachedHidden=" + win.mAttachedHidden);
8332 }
Craig Mautner69b08182012-09-05 13:07:13 -07008333
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008334 // If this view is GONE, then skip it -- keep the current
8335 // frame, and let the caller know so they can ignore it
8336 // if they want. (We do the normal layout for INVISIBLE
8337 // windows, since that means "perform layout as normal,
8338 // just don't display").
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008339 if (!gone || !win.mHaveFrame || win.mLayoutNeeded
Craig Mautner4c5eb222013-11-18 12:59:05 -08008340 || ((win.isConfigChanged() || win.setInsetsChanged()) &&
8341 (win.mAttrs.type == TYPE_KEYGUARD ||
8342 win.mAppToken != null && win.mAppToken.layoutConfigChanges))
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008343 || win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008344 if (!win.mLayoutAttached) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008345 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08008346 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008347 win.mContentChanged = false;
8348 }
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008349 if (win.mAttrs.type == TYPE_DREAM) {
8350 // Don't layout windows behind a dream, so that if it
8351 // does stuff like hide the status bar we won't get a
8352 // bad transition when it goes away.
8353 behindDream = true;
8354 }
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008355 win.mLayoutNeeded = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008356 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008357 mPolicy.layoutWindowLw(win, win.mAttrs, null);
8358 win.mLayoutSeq = seq;
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008359 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008360 + win.mFrame + " mContainingFrame="
8361 + win.mContainingFrame + " mDisplayFrame="
8362 + win.mDisplayFrame);
8363 } else {
8364 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008365 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07008366 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008367 if (win.mViewVisibility == View.VISIBLE
8368 && win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND
8369 && universeBackground == null) {
8370 universeBackground = win.mWinAnimator;
8371 }
8372 }
8373
8374 if (mAnimator.mUniverseBackground != universeBackground) {
8375 mFocusMayChange = true;
8376 mAnimator.mUniverseBackground = universeBackground;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008377 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008378
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008379 boolean attachedBehindDream = false;
8380
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008381 // Now perform layout of attached windows, which usually
8382 // depend on the position of the window they are attached to.
8383 // XXX does not deal with windows that are attached to windows
8384 // that are themselves attached.
8385 for (i = topAttached; i >= 0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07008386 final WindowState win = windows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008387
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008388 if (win.mLayoutAttached) {
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008389 if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008390 + " mHaveFrame=" + win.mHaveFrame
8391 + " mViewVisibility=" + win.mViewVisibility
8392 + " mRelayoutCalled=" + win.mRelayoutCalled);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008393 // If this view is GONE, then skip it -- keep the current
8394 // frame, and let the caller know so they can ignore it
8395 // if they want. (We do the normal layout for INVISIBLE
8396 // windows, since that means "perform layout as normal,
8397 // just don't display").
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008398 if (attachedBehindDream && mPolicy.canBeForceHidden(win, win.mAttrs)) {
8399 continue;
8400 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008401 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008402 || !win.mHaveFrame || win.mLayoutNeeded) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008403 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08008404 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008405 win.mContentChanged = false;
8406 }
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008407 win.mLayoutNeeded = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008408 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008409 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
8410 win.mLayoutSeq = seq;
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008411 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008412 + win.mFrame + " mContainingFrame="
8413 + win.mContainingFrame + " mDisplayFrame="
8414 + win.mDisplayFrame);
8415 }
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008416 } else if (win.mAttrs.type == TYPE_DREAM) {
8417 // Don't layout windows behind a dream, so that if it
8418 // does stuff like hide the status bar we won't get a
8419 // bad transition when it goes away.
8420 attachedBehindDream = behindDream;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008421 }
8422 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08008423
Jeff Brown349703e2010-06-22 01:27:15 -07008424 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown3a22cd92011-01-21 13:59:04 -08008425 mInputMonitor.setUpdateInputWindowsNeededLw();
8426 if (updateInputWindows) {
Jeff Brown2e44b072011-01-24 15:21:56 -08008427 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08008428 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008429
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008430 mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008431 }
Romain Guy06882f82009-06-10 13:36:04 -07008432
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008433 void makeWindowFreezingScreenIfNeededLocked(WindowState w) {
8434 // If the screen is currently frozen or off, then keep
8435 // it frozen/off until this window draws at its new
8436 // orientation.
Craig Mautner2fb98b12012-03-20 17:24:00 -07008437 if (!okToDisplay()) {
Craig Mautner34b73df2014-01-12 21:11:08 -08008438 if (DEBUG_ORIENTATION) Slog.v(TAG, "Changing surface while display frozen: " + w);
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008439 w.mOrientationChanging = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -07008440 w.mLastFreezeDuration = 0;
Craig Mautner3255a282012-04-16 15:42:47 -07008441 mInnerFields.mOrientationChangeComplete = false;
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008442 if (!mWindowsFreezingScreen) {
8443 mWindowsFreezingScreen = true;
8444 // XXX should probably keep timeout from
8445 // when we first froze the display.
8446 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
Craig Mautner6cfa7292013-01-15 09:05:42 -08008447 mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT,
You Kimcb6291c2012-12-04 23:22:28 +09008448 WINDOW_FREEZE_TIMEOUT_DURATION);
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008449 }
8450 }
8451 }
8452
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008453 /**
8454 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
Craig Mautner19d59bc2012-09-04 11:15:56 -07008455 * @param windows List of windows on default display.
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008456 * @return bitmap indicating if another pass through layout must be made.
8457 */
Craig Mautner59c00972012-07-30 12:10:24 -07008458 public int handleAppTransitionReadyLocked(WindowList windows) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008459 int changes = 0;
8460 int i;
8461 int NN = mOpeningApps.size();
8462 boolean goodToGo = true;
8463 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8464 "Checking " + NN + " opening apps (frozen="
8465 + mDisplayFrozen + " timeout="
Craig Mautner164d4bb2012-11-26 13:51:23 -08008466 + mAppTransition.isTimeout() + ")...");
8467 if (!mDisplayFrozen && !mAppTransition.isTimeout()) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008468 // If the display isn't frozen, wait to do anything until
8469 // all of the apps are ready. Otherwise just go because
8470 // we'll unfreeze the display when everyone is ready.
8471 for (i=0; i<NN && goodToGo; i++) {
8472 AppWindowToken wtoken = mOpeningApps.get(i);
8473 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Craig Mautner1d961d42012-05-27 12:02:11 -07008474 "Check opening app=" + wtoken + ": allDrawn="
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008475 + wtoken.allDrawn + " startingDisplayed="
Craig Mautner7358fbf2012-04-12 21:06:33 -07008476 + wtoken.startingDisplayed + " startingMoved="
8477 + wtoken.startingMoved);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008478 if (!wtoken.allDrawn && !wtoken.startingDisplayed
8479 && !wtoken.startingMoved) {
8480 goodToGo = false;
8481 }
8482 }
8483 }
8484 if (goodToGo) {
8485 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
Craig Mautner164d4bb2012-11-26 13:51:23 -08008486 int transit = mAppTransition.getAppTransition();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008487 if (mSkipAppTransitionAnimation) {
Craig Mautner4b71aa12012-12-27 17:20:01 -08008488 transit = AppTransition.TRANSIT_UNSET;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008489 }
Craig Mautner164d4bb2012-11-26 13:51:23 -08008490 mAppTransition.goodToGo();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008491 mStartingIconInTransition = false;
8492 mSkipAppTransitionAnimation = false;
8493
8494 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
8495
Craig Mautneref25d7a2012-05-15 23:01:47 -07008496 rebuildAppWindowListLocked();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008497
Craig Mautner0afddcb2012-05-08 15:38:00 -07008498 // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
Craig Mautner83339b42012-05-01 22:13:23 -07008499 WindowState oldWallpaper =
8500 mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
Craig Mautner0afddcb2012-05-08 15:38:00 -07008501 && !mWallpaperTarget.mWinAnimator.isDummyAnimation()
Craig Mautner83339b42012-05-01 22:13:23 -07008502 ? null : mWallpaperTarget;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008503
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008504 mInnerFields.mWallpaperMayChange = false;
8505
8506 // The top-most window will supply the layout params,
8507 // and we will determine it below.
8508 LayoutParams animLp = null;
8509 int bestAnimLayer = -1;
8510 boolean fullscreenAnim = false;
8511
8512 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8513 "New wallpaper target=" + mWallpaperTarget
Daniel Sandlerab886f52012-06-04 14:36:25 -04008514 + ", oldWallpaper=" + oldWallpaper
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008515 + ", lower target=" + mLowerWallpaperTarget
8516 + ", upper target=" + mUpperWallpaperTarget);
Craig Mautnerae446592012-12-06 19:05:05 -08008517
8518 boolean openingAppHasWallpaper = false;
8519 boolean closingAppHasWallpaper = false;
8520 final AppWindowToken lowerWallpaperAppToken;
8521 final AppWindowToken upperWallpaperAppToken;
8522 if (mLowerWallpaperTarget == null) {
8523 lowerWallpaperAppToken = upperWallpaperAppToken = null;
8524 } else {
8525 lowerWallpaperAppToken = mLowerWallpaperTarget.mAppToken;
8526 upperWallpaperAppToken = mUpperWallpaperTarget.mAppToken;
8527 }
8528
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008529 // Do a first pass through the tokens for two
8530 // things:
8531 // (1) Determine if both the closing and opening
8532 // app token sets are wallpaper targets, in which
8533 // case special animations are needed
8534 // (since the wallpaper needs to stay static
8535 // behind them).
8536 // (2) Find the layout params of the top-most
8537 // application window in the tokens, which is
8538 // what will control the animation theme.
8539 final int NC = mClosingApps.size();
8540 NN = NC + mOpeningApps.size();
8541 for (i=0; i<NN; i++) {
Craig Mautnerae446592012-12-06 19:05:05 -08008542 final AppWindowToken wtoken;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008543 if (i < NC) {
8544 wtoken = mClosingApps.get(i);
Craig Mautnerae446592012-12-06 19:05:05 -08008545 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
8546 closingAppHasWallpaper = true;
8547 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008548 } else {
Craig Mautnerae446592012-12-06 19:05:05 -08008549 wtoken = mOpeningApps.get(i - NC);
8550 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
8551 openingAppHasWallpaper = true;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008552 }
8553 }
Craig Mautnerae446592012-12-06 19:05:05 -08008554
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008555 if (wtoken.appFullscreen) {
8556 WindowState ws = wtoken.findMainWindow();
8557 if (ws != null) {
8558 animLp = ws.mAttrs;
8559 bestAnimLayer = ws.mLayer;
8560 fullscreenAnim = true;
8561 }
8562 } else if (!fullscreenAnim) {
8563 WindowState ws = wtoken.findMainWindow();
8564 if (ws != null) {
8565 if (ws.mLayer > bestAnimLayer) {
8566 animLp = ws.mAttrs;
8567 bestAnimLayer = ws.mLayer;
8568 }
8569 }
8570 }
8571 }
8572
Craig Mautner798adef2013-10-22 14:29:01 -07008573 mAnimateWallpaperWithTarget = false;
Craig Mautnerae446592012-12-06 19:05:05 -08008574 if (closingAppHasWallpaper && openingAppHasWallpaper) {
8575 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Wallpaper animation!");
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008576 switch (transit) {
Craig Mautner4b71aa12012-12-27 17:20:01 -08008577 case AppTransition.TRANSIT_ACTIVITY_OPEN:
8578 case AppTransition.TRANSIT_TASK_OPEN:
8579 case AppTransition.TRANSIT_TASK_TO_FRONT:
8580 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008581 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08008582 case AppTransition.TRANSIT_ACTIVITY_CLOSE:
8583 case AppTransition.TRANSIT_TASK_CLOSE:
8584 case AppTransition.TRANSIT_TASK_TO_BACK:
8585 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008586 break;
8587 }
Craig Mautnerae446592012-12-06 19:05:05 -08008588 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "New transit: " + transit);
Adam Lesinski76afd1f2013-10-23 10:45:28 -07008589 } else if ((oldWallpaper != null) && !mOpeningApps.isEmpty()
8590 && !mOpeningApps.contains(oldWallpaper.mAppToken)) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008591 // We are transitioning from an activity with
8592 // a wallpaper to one without.
Craig Mautner4b71aa12012-12-27 17:20:01 -08008593 transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008594 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8595 "New transit away from wallpaper: " + transit);
Craig Mautner8863cca2012-09-18 15:04:34 -07008596 } else if (mWallpaperTarget != null && mWallpaperTarget.isVisibleLw()) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008597 // We are transitioning from an activity without
8598 // a wallpaper to now showing the wallpaper
Craig Mautner4b71aa12012-12-27 17:20:01 -08008599 transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008600 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8601 "New transit into wallpaper: " + transit);
Craig Mautner798adef2013-10-22 14:29:01 -07008602 } else {
8603 mAnimateWallpaperWithTarget = true;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008604 }
8605
8606 // If all closing windows are obscured, then there is
8607 // no need to do an animation. This is the case, for
8608 // example, when this transition is being done behind
8609 // the lock screen.
8610 if (!mPolicy.allowAppAnimationsLw()) {
Craig Mautner28816302013-10-10 20:31:00 -07008611 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8612 "Animations disallowed by keyguard or dream.");
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008613 animLp = null;
8614 }
8615
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008616 AppWindowToken topOpeningApp = null;
8617 int topOpeningLayer = 0;
8618
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008619 NN = mOpeningApps.size();
8620 for (i=0; i<NN; i++) {
8621 AppWindowToken wtoken = mOpeningApps.get(i);
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008622 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Craig Mautnerbec53f72012-04-05 11:49:05 -07008623 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008624 appAnimator.clearThumbnail();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008625 wtoken.inPendingTransaction = false;
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008626 appAnimator.animation = null;
Craig Mautnerbec53f72012-04-05 11:49:05 -07008627 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008628 wtoken.updateReportedVisibilityLocked();
8629 wtoken.waitingToShow = false;
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008630
8631 appAnimator.mAllAppWinAnimators.clear();
8632 final int N = wtoken.allAppWindows.size();
8633 for (int j = 0; j < N; j++) {
8634 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
8635 }
8636 mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
8637
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008638 if (animLp != null) {
8639 int layer = -1;
8640 for (int j=0; j<wtoken.windows.size(); j++) {
8641 WindowState win = wtoken.windows.get(j);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07008642 if (win.mWinAnimator.mAnimLayer > layer) {
8643 layer = win.mWinAnimator.mAnimLayer;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008644 }
8645 }
8646 if (topOpeningApp == null || layer > topOpeningLayer) {
8647 topOpeningApp = wtoken;
8648 topOpeningLayer = layer;
8649 }
8650 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008651 }
8652 NN = mClosingApps.size();
8653 for (i=0; i<NN; i++) {
8654 AppWindowToken wtoken = mClosingApps.get(i);
Craig Mautner28816302013-10-10 20:31:00 -07008655 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
Craig Mautner59431632012-04-04 11:56:44 -07008656 wtoken.mAppAnimator.clearThumbnail();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008657 wtoken.inPendingTransaction = false;
Craig Mautner59431632012-04-04 11:56:44 -07008658 wtoken.mAppAnimator.animation = null;
Adam Lesinski76afd1f2013-10-23 10:45:28 -07008659 setTokenVisibilityLocked(wtoken, animLp, false, transit, false);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008660 wtoken.updateReportedVisibilityLocked();
8661 wtoken.waitingToHide = false;
8662 // Force the allDrawn flag, because we want to start
8663 // this guy's animations regardless of whether it's
8664 // gotten drawn.
8665 wtoken.allDrawn = true;
Craig Mautner7636dfb2012-11-16 15:24:11 -08008666 wtoken.deferClearAllDrawn = false;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008667 }
8668
Craig Mautner164d4bb2012-11-26 13:51:23 -08008669 AppWindowAnimator appAnimator =
8670 topOpeningApp == null ? null : topOpeningApp.mAppAnimator;
8671 Bitmap nextAppTransitionThumbnail = mAppTransition.getNextAppTransitionThumbnail();
8672 if (nextAppTransitionThumbnail != null && appAnimator != null
8673 && appAnimator.animation != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008674 // This thumbnail animation is very special, we need to have
8675 // an extra surface with the thumbnail included with the animation.
Craig Mautner164d4bb2012-11-26 13:51:23 -08008676 Rect dirty = new Rect(0, 0, nextAppTransitionThumbnail.getWidth(),
8677 nextAppTransitionThumbnail.getHeight());
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008678 try {
Jeff Browne215f262012-09-10 16:01:14 -07008679 // TODO(multi-display): support other displays
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008680 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07008681 final Display display = displayContent.getDisplay();
Mathias Agopian29479eb2013-02-14 14:36:04 -08008682 SurfaceControl surfaceControl = new SurfaceControl(mFxSession,
Jeff Brown64a55af2012-08-26 02:47:39 -07008683 "thumbnail anim",
Craig Mautner6881a102012-07-27 13:04:51 -07008684 dirty.width(), dirty.height(),
Mathias Agopian3866f0d2013-02-11 22:08:48 -08008685 PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
Mathias Agopian29479eb2013-02-14 14:36:04 -08008686 surfaceControl.setLayerStack(display.getLayerStack());
8687 appAnimator.thumbnail = surfaceControl;
8688 if (SHOW_TRANSACTIONS) Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008689 Surface drawSurface = new Surface();
Mathias Agopian29479eb2013-02-14 14:36:04 -08008690 drawSurface.copyFrom(surfaceControl);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008691 Canvas c = drawSurface.lockCanvas(dirty);
Craig Mautner164d4bb2012-11-26 13:51:23 -08008692 c.drawBitmap(nextAppTransitionThumbnail, 0, 0, null);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008693 drawSurface.unlockCanvasAndPost(c);
8694 drawSurface.release();
Craig Mautner164d4bb2012-11-26 13:51:23 -08008695 appAnimator.thumbnailLayer = topOpeningLayer;
8696 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
8697 Animation anim = mAppTransition.createThumbnailAnimationLocked(
8698 transit, true, true, displayInfo.appWidth, displayInfo.appHeight);
8699 appAnimator.thumbnailAnimation = anim;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008700 anim.restrictDuration(MAX_ANIMATION_DURATION);
8701 anim.scaleCurrentDuration(mTransitionAnimationScale);
Craig Mautner164d4bb2012-11-26 13:51:23 -08008702 Point p = new Point();
8703 mAppTransition.getStartingPoint(p);
8704 appAnimator.thumbnailX = p.x;
8705 appAnimator.thumbnailY = p.y;
Igor Murashkina86ab6402013-08-30 12:58:36 -07008706 } catch (OutOfResourcesException e) {
8707 Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w=" + dirty.width()
Mathias Agopian3866f0d2013-02-11 22:08:48 -08008708 + " h=" + dirty.height(), e);
8709 appAnimator.clearThumbnail();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008710 }
8711 }
8712
Craig Mautner164d4bb2012-11-26 13:51:23 -08008713 mAppTransition.postAnimationCallback();
8714 mAppTransition.clear();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008715
8716 mOpeningApps.clear();
8717 mClosingApps.clear();
8718
8719 // This has changed the visibility of windows, so perform
8720 // a new layout to get them all up-to-date.
Craig Mautner39834192012-09-02 07:47:24 -07008721 changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008722 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008723 getDefaultDisplayContentLocked().layoutNeeded = true;
Craig Mautner59c00972012-07-30 12:10:24 -07008724
8725 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008726 if (windows == getDefaultWindowListLocked()
8727 && !moveInputMethodWindowsIfNeededLocked(true)) {
Craig Mautner59c00972012-07-30 12:10:24 -07008728 assignLayersLocked(windows);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008729 }
Craig Mautner59c00972012-07-30 12:10:24 -07008730 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, false /*updateInputWindows*/);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008731 mFocusMayChange = false;
8732 }
8733
8734 return changes;
8735 }
8736
8737 /**
8738 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008739 * @return bitmap indicating if another pass through layout must be made.
8740 */
Craig Mautner2f995a72012-02-21 09:53:21 -08008741 private int handleAnimatingStoppedAndTransitionLocked() {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008742 int changes = 0;
8743
Craig Mautner9a29a5d2012-12-27 19:03:40 -08008744 mAppTransition.setIdle();
Craig Mautneref25d7a2012-05-15 23:01:47 -07008745 // Restore window app tokens to the ActivityManager views
Craig Mautnerdc548482014-02-05 13:35:24 -08008746 ArrayList<TaskStack> stacks = getDefaultDisplayContentLocked().getStacks();
8747 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
8748 final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
8749 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
8750 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
8751 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
8752 tokens.get(tokenNdx).sendingToBottom = false;
8753 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08008754 }
Craig Mautner3f99fde2012-06-19 14:10:01 -07008755 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008756 rebuildAppWindowListLocked();
Craig Mautneref25d7a2012-05-15 23:01:47 -07008757
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008758 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Craig Mautnerae446592012-12-06 19:05:05 -08008759 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
8760 "Wallpaper layer changed: assigning layers + relayout");
Craig Mautneref25d7a2012-05-15 23:01:47 -07008761 moveInputMethodWindowsIfNeededLocked(true);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008762 mInnerFields.mWallpaperMayChange = true;
8763 // Since the window list has been rebuilt, focus might
8764 // have to be recomputed since the actual order of windows
8765 // might have changed again.
8766 mFocusMayChange = true;
8767
8768 return changes;
8769 }
8770
Craig Mautnere32c3072012-03-12 15:25:35 -07008771 private void updateResizingWindows(final WindowState w) {
Craig Mautnera608b882012-03-30 13:03:49 -07008772 final WindowStateAnimator winAnimator = w.mWinAnimator;
Craig Mautnerade0a9a2012-10-06 13:55:07 -07008773 if (w.mHasSurface && w.mLayoutSeq == mLayoutSeq) {
Craig Mautner4c5eb222013-11-18 12:59:05 -08008774 w.setInsetsChanged();
Craig Mautner812d2ca2012-09-27 15:35:34 -07008775 boolean configChanged = w.isConfigChanged();
Craig Mautnere32c3072012-03-12 15:25:35 -07008776 if (DEBUG_CONFIGURATION && configChanged) {
8777 Slog.v(TAG, "Win " + w + " config changed: "
8778 + mCurConfiguration);
8779 }
8780 if (localLOGV) Slog.v(TAG, "Resizing " + w
8781 + ": configChanged=" + configChanged
8782 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
8783 w.mLastFrame.set(w.mFrame);
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07008784 if (w.mContentInsetsChanged
Craig Mautnere32c3072012-03-12 15:25:35 -07008785 || w.mVisibleInsetsChanged
Craig Mautnera608b882012-03-30 13:03:49 -07008786 || winAnimator.mSurfaceResized
Craig Mautnere32c3072012-03-12 15:25:35 -07008787 || configChanged) {
8788 if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
Craig Mautnerc5a6e442013-06-05 17:22:35 -07008789 Slog.v(TAG, "Resize reasons for w=" + w + ": "
Craig Mautnere32c3072012-03-12 15:25:35 -07008790 + " contentInsetsChanged=" + w.mContentInsetsChanged
Craig Mautnerae446592012-12-06 19:05:05 -08008791 + " " + w.mContentInsets.toShortString()
Craig Mautnere32c3072012-03-12 15:25:35 -07008792 + " visibleInsetsChanged=" + w.mVisibleInsetsChanged
Craig Mautnerae446592012-12-06 19:05:05 -08008793 + " " + w.mVisibleInsets.toShortString()
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008794 + " surfaceResized=" + winAnimator.mSurfaceResized
Craig Mautnere32c3072012-03-12 15:25:35 -07008795 + " configChanged=" + configChanged);
8796 }
8797
Dianne Hackbornc4aad012013-02-22 15:05:25 -08008798 w.mLastOverscanInsets.set(w.mOverscanInsets);
Craig Mautnere32c3072012-03-12 15:25:35 -07008799 w.mLastContentInsets.set(w.mContentInsets);
8800 w.mLastVisibleInsets.set(w.mVisibleInsets);
8801 makeWindowFreezingScreenIfNeededLocked(w);
8802 // If the orientation is changing, then we need to
8803 // hold off on unfreezing the display until this
8804 // window has been redrawn; to do that, we need
8805 // to go through the process of getting informed
8806 // by the application when it has finished drawing.
8807 if (w.mOrientationChanging) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07008808 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautner83339b42012-05-01 22:13:23 -07008809 "Orientation start waiting for draw mDrawState=DRAW_PENDING in "
Mathias Agopian29479eb2013-02-14 14:36:04 -08008810 + w + ", surface " + winAnimator.mSurfaceControl);
Craig Mautner749a7bb2012-04-02 13:49:53 -07008811 winAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
Craig Mautnere32c3072012-03-12 15:25:35 -07008812 if (w.mAppToken != null) {
8813 w.mAppToken.allDrawn = false;
Craig Mautner7636dfb2012-11-16 15:24:11 -08008814 w.mAppToken.deferClearAllDrawn = false;
Craig Mautnere32c3072012-03-12 15:25:35 -07008815 }
8816 }
8817 if (!mResizingWindows.contains(w)) {
8818 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008819 "Resizing window " + w + " to " + winAnimator.mSurfaceW
8820 + "x" + winAnimator.mSurfaceH);
Craig Mautnere32c3072012-03-12 15:25:35 -07008821 mResizingWindows.add(w);
8822 }
8823 } else if (w.mOrientationChanging) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07008824 if (w.isDrawnLw()) {
Craig Mautnere32c3072012-03-12 15:25:35 -07008825 if (DEBUG_ORIENTATION) Slog.v(TAG,
8826 "Orientation not waiting for draw in "
Mathias Agopian29479eb2013-02-14 14:36:04 -08008827 + w + ", surface " + winAnimator.mSurfaceControl);
Craig Mautnere32c3072012-03-12 15:25:35 -07008828 w.mOrientationChanging = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07008829 w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
8830 - mDisplayFreezeTime);
Craig Mautnere32c3072012-03-12 15:25:35 -07008831 }
8832 }
8833 }
8834 }
8835
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008836 /**
8837 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
8838 *
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008839 * @param w WindowState this method is applied to.
8840 * @param currentTime The time which animations use for calculating transitions.
8841 * @param innerDw Width of app window.
8842 * @param innerDh Height of app window.
8843 */
8844 private void handleNotObscuredLocked(final WindowState w, final long currentTime,
8845 final int innerDw, final int innerDh) {
8846 final WindowManager.LayoutParams attrs = w.mAttrs;
8847 final int attrFlags = attrs.flags;
8848 final boolean canBeSeen = w.isDisplayedLw();
Jeff Brown4fd79172013-11-07 17:58:15 -08008849 final boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
8850
8851 if (opaqueDrawn && w.isFullscreen(innerDw, innerDh)) {
8852 // This window completely covers everything behind it,
8853 // so we want to leave all of them as undimmed (for
8854 // performance reasons).
8855 mInnerFields.mObscured = true;
8856 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008857
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07008858 if (w.mHasSurface) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008859 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
8860 mInnerFields.mHoldScreen = w.mSession;
8861 }
8862 if (!mInnerFields.mSyswin && w.mAttrs.screenBrightness >= 0
8863 && mInnerFields.mScreenBrightness < 0) {
8864 mInnerFields.mScreenBrightness = w.mAttrs.screenBrightness;
8865 }
8866 if (!mInnerFields.mSyswin && w.mAttrs.buttonBrightness >= 0
8867 && mInnerFields.mButtonBrightness < 0) {
8868 mInnerFields.mButtonBrightness = w.mAttrs.buttonBrightness;
8869 }
Jeff Brown1e3b98d2012-09-30 18:58:59 -07008870 if (!mInnerFields.mSyswin && w.mAttrs.userActivityTimeout >= 0
8871 && mInnerFields.mUserActivityTimeout < 0) {
8872 mInnerFields.mUserActivityTimeout = w.mAttrs.userActivityTimeout;
8873 }
8874
Craig Mautner65d11b32012-10-01 13:59:52 -07008875 final int type = attrs.type;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008876 if (canBeSeen
Craig Mautner65d11b32012-10-01 13:59:52 -07008877 && (type == TYPE_SYSTEM_DIALOG
Craig Mautner88400d32012-09-30 12:35:45 -07008878 || type == TYPE_RECENTS_OVERLAY
Craig Mautner65d11b32012-10-01 13:59:52 -07008879 || type == TYPE_KEYGUARD
8880 || type == TYPE_SYSTEM_ERROR)) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008881 mInnerFields.mSyswin = true;
8882 }
Craig Mautner65d11b32012-10-01 13:59:52 -07008883
8884 if (canBeSeen) {
Jeff Brown4fd79172013-11-07 17:58:15 -08008885 // This function assumes that the contents of the default display are
8886 // processed first before secondary displays.
Craig Mautnerdf88d732014-01-27 09:21:32 -08008887 final DisplayContent displayContent = w.getDisplayContent();
8888 if (displayContent != null && displayContent.isDefaultDisplay) {
Jeff Brown4fd79172013-11-07 17:58:15 -08008889 // While a dream or keyguard is showing, obscure ordinary application
8890 // content on secondary displays (by forcibly enabling mirroring unless
8891 // there is other content we want to show) but still allow opaque
8892 // keyguard dialogs to be shown.
8893 if (type == TYPE_DREAM || type == TYPE_KEYGUARD) {
8894 mInnerFields.mObscureApplicationContentOnSecondaryDisplays = true;
8895 }
8896 mInnerFields.mDisplayHasContent = true;
Craig Mautnerdf88d732014-01-27 09:21:32 -08008897 } else if (displayContent != null &&
8898 (!mInnerFields.mObscureApplicationContentOnSecondaryDisplays
8899 || (mInnerFields.mObscured && type == TYPE_KEYGUARD_DIALOG))) {
Jeff Brown4fd79172013-11-07 17:58:15 -08008900 // Allow full screen keyguard presentation dialogs to be seen.
8901 mInnerFields.mDisplayHasContent = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07008902 }
8903 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008904 }
Craig Mautner312eac42012-11-13 10:56:22 -08008905 }
8906
Craig Mautnerdc548482014-02-05 13:35:24 -08008907 private void handleFlagDimBehind(WindowState w) {
Craig Mautner312eac42012-11-13 10:56:22 -08008908 final WindowManager.LayoutParams attrs = w.mAttrs;
8909 if ((attrs.flags & FLAG_DIM_BEHIND) != 0
8910 && w.isDisplayedLw()
Craig Mautner236a35b2012-06-08 09:54:59 -07008911 && !w.mExiting) {
Craig Mautner312eac42012-11-13 10:56:22 -08008912 final WindowStateAnimator winAnimator = w.mWinAnimator;
Craig Mautner05d29032013-05-03 13:40:13 -07008913 final TaskStack stack = w.getStack();
8914 stack.setDimmingTag();
8915 if (!stack.isDimming(winAnimator)) {
Craig Mautner312eac42012-11-13 10:56:22 -08008916 if (localLOGV) Slog.v(TAG, "Win " + w + " start dimming.");
Craig Mautner05d29032013-05-03 13:40:13 -07008917 stack.startDimmingIfNeeded(winAnimator);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008918 }
8919 }
8920 }
8921
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08008922 private void updateAllDrawnLocked(DisplayContent displayContent) {
Craig Mautner6fbda632012-07-03 09:26:39 -07008923 // See if any windows have been drawn, so they (and others
8924 // associated with them) can now be shown.
Craig Mautnerdc548482014-02-05 13:35:24 -08008925 ArrayList<TaskStack> stacks = displayContent.getStacks();
8926 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
8927 final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
8928 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
8929 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
8930 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
8931 final AppWindowToken wtoken = tokens.get(tokenNdx);
8932 if (!wtoken.allDrawn) {
8933 int numInteresting = wtoken.numInterestingWindows;
8934 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
8935 if (DEBUG_VISIBILITY) Slog.v(TAG,
8936 "allDrawn: " + wtoken
8937 + " interesting=" + numInteresting
8938 + " drawn=" + wtoken.numDrawnWindows);
8939 wtoken.allDrawn = true;
8940 mH.obtainMessage(H.NOTIFY_ACTIVITY_DRAWN, wtoken.token).sendToTarget();
8941 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08008942 }
Craig Mautner6fbda632012-07-03 09:26:39 -07008943 }
8944 }
8945 }
8946 }
8947
Brad Fitzpatrick68044332010-11-22 18:19:48 -08008948 // "Something has changed! Let's make it correct now."
Craig Mautner76a71652012-09-03 23:23:58 -07008949 private final void performLayoutAndPlaceSurfacesLockedInner(boolean recoveringMemory) {
Craig Mautner7d8df392012-04-06 15:26:23 -07008950 if (DEBUG_WINDOW_TRACE) {
Craig Mautner3255a282012-04-16 15:42:47 -07008951 Slog.v(TAG, "performLayoutAndPlaceSurfacesLockedInner: entry. Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -07008952 + Debug.getCallers(3));
Craig Mautner7d8df392012-04-06 15:26:23 -07008953 }
Joe Onorato34bcebc2010-07-07 18:05:01 -04008954
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008955 final long currentTime = SystemClock.uptimeMillis();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008956
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008957 int i;
8958
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008959 if (mFocusMayChange) {
8960 mFocusMayChange = false;
Jeff Brown3a22cd92011-01-21 13:59:04 -08008961 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
8962 false /*updateInputWindows*/);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008963 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008964
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008965 // Initialize state of exiting tokens.
Craig Mautnerf8924152013-07-16 09:10:55 -07008966 final int numDisplays = mDisplayContents.size();
8967 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
8968 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08008969 for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {
8970 displayContent.mExitingTokens.get(i).hasVisible = false;
8971 }
Craig Mautnerdc548482014-02-05 13:35:24 -08008972 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008973
Craig Mautnerdc548482014-02-05 13:35:24 -08008974 for (int stackNdx = mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08008975 // Initialize state of exiting applications.
Craig Mautnerdc548482014-02-05 13:35:24 -08008976 final AppTokenList exitingAppTokens =
8977 mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
8978 for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
8979 exitingAppTokens.get(tokenNdx).hasVisible = false;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08008980 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008981 }
8982
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008983 mInnerFields.mHoldScreen = null;
8984 mInnerFields.mScreenBrightness = -1;
8985 mInnerFields.mButtonBrightness = -1;
Jeff Brown1e3b98d2012-09-30 18:58:59 -07008986 mInnerFields.mUserActivityTimeout = -1;
Jeff Brown4fd79172013-11-07 17:58:15 -08008987 mInnerFields.mObscureApplicationContentOnSecondaryDisplays = false;
Jeff Brown1e3b98d2012-09-30 18:58:59 -07008988
Craig Mautner6fbda632012-07-03 09:26:39 -07008989 mTransactionSequence++;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07008990
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008991 final DisplayContent defaultDisplay = getDefaultDisplayContentLocked();
Craig Mautner76a71652012-09-03 23:23:58 -07008992 final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
8993 final int defaultDw = defaultInfo.logicalWidth;
8994 final int defaultDh = defaultInfo.logicalHeight;
Craig Mautner76a71652012-09-03 23:23:58 -07008995
Dianne Hackborn36991742011-10-11 21:35:26 -07008996 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
8997 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
Mathias Agopian3866f0d2013-02-11 22:08:48 -08008998 SurfaceControl.openTransaction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008999 try {
Craig Mautner76a71652012-09-03 23:23:58 -07009000
Jeff Brown4ed8fe72012-08-30 18:18:29 -07009001 if (mWatermark != null) {
Craig Mautner76a71652012-09-03 23:23:58 -07009002 mWatermark.positionSurface(defaultDw, defaultDh);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07009003 }
9004 if (mStrictModeFlash != null) {
Craig Mautner76a71652012-09-03 23:23:58 -07009005 mStrictModeFlash.positionSurface(defaultDw, defaultDh);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07009006 }
9007
Craig Mautner7358fbf2012-04-12 21:06:33 -07009008 boolean focusDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009009
Craig Mautnerf8924152013-07-16 09:10:55 -07009010 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9011 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08009012 boolean updateAllDrawn = false;
Craig Mautner76a71652012-09-03 23:23:58 -07009013 WindowList windows = displayContent.getWindowList();
9014 DisplayInfo displayInfo = displayContent.getDisplayInfo();
Craig Mautner19d59bc2012-09-04 11:15:56 -07009015 final int displayId = displayContent.getDisplayId();
Craig Mautner76a71652012-09-03 23:23:58 -07009016 final int dw = displayInfo.logicalWidth;
9017 final int dh = displayInfo.logicalHeight;
9018 final int innerDw = displayInfo.appWidth;
9019 final int innerDh = displayInfo.appHeight;
Craig Mautner19d59bc2012-09-04 11:15:56 -07009020 final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009021
Jeff Brown4fd79172013-11-07 17:58:15 -08009022 // Reset for each display.
9023 mInnerFields.mDisplayHasContent = false;
Craig Mautner65d11b32012-10-01 13:59:52 -07009024
Craig Mautner76a71652012-09-03 23:23:58 -07009025 int repeats = 0;
9026 do {
9027 repeats++;
9028 if (repeats > 6) {
9029 Slog.w(TAG, "Animation repeat aborted after too many iterations");
Craig Mautner76a71652012-09-03 23:23:58 -07009030 displayContent.layoutNeeded = false;
9031 break;
Craig Mautner5702d4d2012-06-30 14:10:16 -07009032 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009033
Craig Mautner76a71652012-09-03 23:23:58 -07009034 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("On entry to LockedInner",
9035 displayContent.pendingLayoutChanges);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009036
Craig Mautner0bf6ec92012-12-18 08:33:27 -08009037 if ((displayContent.pendingLayoutChanges &
9038 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
9039 (adjustWallpaperWindowsLocked() &
9040 ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Craig Mautner76a71652012-09-03 23:23:58 -07009041 assignLayersLocked(windows);
Craig Mautner76a71652012-09-03 23:23:58 -07009042 displayContent.layoutNeeded = true;
9043 }
9044
9045 if (isDefaultDisplay && (displayContent.pendingLayoutChanges
9046 & WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
9047 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
9048 if (updateOrientationFromAppTokensLocked(true)) {
Craig Mautner76a71652012-09-03 23:23:58 -07009049 displayContent.layoutNeeded = true;
9050 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009051 }
9052 }
9053
Craig Mautner76a71652012-09-03 23:23:58 -07009054 if ((displayContent.pendingLayoutChanges
9055 & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
Craig Mautner76a71652012-09-03 23:23:58 -07009056 displayContent.layoutNeeded = true;
Craig Mautner6fbda632012-07-03 09:26:39 -07009057 }
Craig Mautner76a71652012-09-03 23:23:58 -07009058
9059 // FIRST LOOP: Perform a layout, if needed.
9060 if (repeats < 4) {
9061 performLayoutLockedInner(displayContent, repeats == 1,
9062 false /*updateInputWindows*/);
9063 } else {
9064 Slog.w(TAG, "Layout repeat skipped after too many iterations");
9065 }
9066
9067 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
9068 // it is animating.
9069 displayContent.pendingLayoutChanges = 0;
9070
9071 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("loop number "
9072 + mLayoutRepeatCount, displayContent.pendingLayoutChanges);
9073
Craig Mautner69b08182012-09-05 13:07:13 -07009074 if (isDefaultDisplay) {
9075 mPolicy.beginPostLayoutPolicyLw(dw, dh);
9076 for (i = windows.size() - 1; i >= 0; i--) {
9077 WindowState w = windows.get(i);
9078 if (w.mHasSurface) {
9079 mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs);
9080 }
Craig Mautner6fbda632012-07-03 09:26:39 -07009081 }
Craig Mautner69b08182012-09-05 13:07:13 -07009082 displayContent.pendingLayoutChanges |= mPolicy.finishPostLayoutPolicyLw();
9083 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
9084 "after finishPostLayoutPolicyLw", displayContent.pendingLayoutChanges);
Craig Mautner76a71652012-09-03 23:23:58 -07009085 }
Craig Mautner76a71652012-09-03 23:23:58 -07009086 } while (displayContent.pendingLayoutChanges != 0);
9087
9088 mInnerFields.mObscured = false;
Craig Mautner76a71652012-09-03 23:23:58 -07009089 mInnerFields.mSyswin = false;
Craig Mautner05d29032013-05-03 13:40:13 -07009090 displayContent.resetDimming();
Craig Mautner76a71652012-09-03 23:23:58 -07009091
9092 // Only used if default window
9093 final boolean someoneLosingFocus = !mLosingFocus.isEmpty();
9094
9095 final int N = windows.size();
9096 for (i=N-1; i>=0; i--) {
9097 WindowState w = windows.get(i);
Craig Mautnere0a38842013-12-16 16:14:02 -08009098 final TaskStack stack = w.getStack();
9099 if (stack == null) {
9100 continue;
9101 }
Craig Mautner76a71652012-09-03 23:23:58 -07009102
9103 final boolean obscuredChanged = w.mObscured != mInnerFields.mObscured;
9104
9105 // Update effect.
9106 w.mObscured = mInnerFields.mObscured;
9107 if (!mInnerFields.mObscured) {
9108 handleNotObscuredLocked(w, currentTime, innerDw, innerDh);
9109 }
9110
Craig Mautnere0a38842013-12-16 16:14:02 -08009111 if (!stack.testDimmingTag()) {
Craig Mautnerdc548482014-02-05 13:35:24 -08009112 handleFlagDimBehind(w);
Craig Mautner312eac42012-11-13 10:56:22 -08009113 }
9114
Craig Mautner76a71652012-09-03 23:23:58 -07009115 if (isDefaultDisplay && obscuredChanged && (mWallpaperTarget == w)
9116 && w.isVisibleLw()) {
9117 // This is the wallpaper target and its obscured state
9118 // changed... make sure the current wallaper's visibility
9119 // has been updated accordingly.
9120 updateWallpaperVisibilityLocked();
9121 }
9122
9123 final WindowStateAnimator winAnimator = w.mWinAnimator;
9124
9125 // If the window has moved due to its containing
9126 // content frame changing, then we'd like to animate
9127 // it.
9128 if (w.mHasSurface && w.shouldAnimateMove()) {
9129 // Frame has moved, containing content frame
9130 // has also moved, and we're not currently animating...
9131 // let's do something.
9132 Animation a = AnimationUtils.loadAnimation(mContext,
9133 com.android.internal.R.anim.window_move_from_decor);
9134 winAnimator.setAnimation(a);
9135 winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
9136 winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
9137 try {
9138 w.mClient.moved(w.mFrame.left, w.mFrame.top);
9139 } catch (RemoteException e) {
9140 }
9141 }
9142
9143 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
9144 w.mContentChanged = false;
9145
9146 // Moved from updateWindowsAndWallpaperLocked().
9147 if (w.mHasSurface) {
9148 // Take care of the window being ready to display.
Craig Mautner69b08182012-09-05 13:07:13 -07009149 final boolean committed =
9150 winAnimator.commitFinishDrawingLocked(currentTime);
9151 if (isDefaultDisplay && committed) {
Dianne Hackborn7ad44382012-10-18 17:46:00 -07009152 if (w.mAttrs.type == TYPE_DREAM) {
9153 // HACK: When a dream is shown, it may at that
9154 // point hide the lock screen. So we need to
9155 // redo the layout to let the phone window manager
9156 // make this happen.
9157 displayContent.pendingLayoutChanges |=
9158 WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
Craig Mautner11462cc2013-05-13 15:56:18 -07009159 if (DEBUG_LAYOUT_REPEATS) {
Dianne Hackborn7ad44382012-10-18 17:46:00 -07009160 debugLayoutRepeats(
9161 "dream and commitFinishDrawingLocked true",
9162 displayContent.pendingLayoutChanges);
9163 }
9164 }
Craig Mautner65d11b32012-10-01 13:59:52 -07009165 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07009166 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Craig Mautner76a71652012-09-03 23:23:58 -07009167 "First draw done in potential wallpaper target " + w);
9168 mInnerFields.mWallpaperMayChange = true;
9169 displayContent.pendingLayoutChanges |=
9170 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Craig Mautner11462cc2013-05-13 15:56:18 -07009171 if (DEBUG_LAYOUT_REPEATS) {
Craig Mautner76a71652012-09-03 23:23:58 -07009172 debugLayoutRepeats(
9173 "wallpaper and commitFinishDrawingLocked true",
9174 displayContent.pendingLayoutChanges);
Craig Mautner6fbda632012-07-03 09:26:39 -07009175 }
9176 }
Craig Mautner76a71652012-09-03 23:23:58 -07009177 }
9178
Craig Mautnera91f9e22012-09-14 16:22:08 -07009179 winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
Craig Mautner76a71652012-09-03 23:23:58 -07009180
9181 final AppWindowToken atoken = w.mAppToken;
Craig Mautner65d11b32012-10-01 13:59:52 -07009182 if (DEBUG_STARTING_WINDOW && atoken != null
9183 && w == atoken.startingWindow) {
Craig Mautner76a71652012-09-03 23:23:58 -07009184 Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen="
9185 + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
9186 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
9187 }
9188 if (atoken != null
9189 && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
9190 if (atoken.lastTransactionSequence != mTransactionSequence) {
9191 atoken.lastTransactionSequence = mTransactionSequence;
9192 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
9193 atoken.startingDisplayed = false;
9194 }
Craig Mautner65d11b32012-10-01 13:59:52 -07009195 if ((w.isOnScreen() || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
Craig Mautner76a71652012-09-03 23:23:58 -07009196 && !w.mExiting && !w.mDestroying) {
Craig Mautner11462cc2013-05-13 15:56:18 -07009197 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Craig Mautner76a71652012-09-03 23:23:58 -07009198 Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
9199 + ", isAnimating=" + winAnimator.isAnimating());
9200 if (!w.isDrawnLw()) {
Mathias Agopian29479eb2013-02-14 14:36:04 -08009201 Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceControl
Craig Mautner76a71652012-09-03 23:23:58 -07009202 + " pv=" + w.mPolicyVisibility
9203 + " mDrawState=" + winAnimator.mDrawState
9204 + " ah=" + w.mAttachedHidden
9205 + " th=" + atoken.hiddenRequested
9206 + " a=" + winAnimator.mAnimating);
Craig Mautner6fbda632012-07-03 09:26:39 -07009207 }
9208 }
Craig Mautner76a71652012-09-03 23:23:58 -07009209 if (w != atoken.startingWindow) {
9210 if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
9211 atoken.numInterestingWindows++;
9212 if (w.isDrawnLw()) {
9213 atoken.numDrawnWindows++;
Craig Mautner11462cc2013-05-13 15:56:18 -07009214 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautner76a71652012-09-03 23:23:58 -07009215 "tokenMayBeDrawn: " + atoken
9216 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen
9217 + " mAppFreezing=" + w.mAppFreezing);
9218 updateAllDrawn = true;
9219 }
9220 }
9221 } else if (w.isDrawnLw()) {
9222 atoken.startingDisplayed = true;
9223 }
Craig Mautner6fbda632012-07-03 09:26:39 -07009224 }
9225 }
9226 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009227
Craig Mautner76a71652012-09-03 23:23:58 -07009228 if (isDefaultDisplay && someoneLosingFocus && (w == mCurrentFocus)
9229 && w.isDisplayedLw()) {
9230 focusDisplayed = true;
9231 }
Craig Mautner51bb12b2012-04-27 14:39:53 -07009232
Craig Mautner76a71652012-09-03 23:23:58 -07009233 updateResizingWindows(w);
9234 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07009235
Jeff Brown4ccb8232014-01-16 22:16:42 -08009236 mDisplayManagerInternal.setDisplayHasContent(displayId,
Jeff Brown4fd79172013-11-07 17:58:15 -08009237 mInnerFields.mDisplayHasContent,
Craig Mautner65d11b32012-10-01 13:59:52 -07009238 true /* inTraversal, must call performTraversalInTrans... below */);
9239
Craig Mautner05d29032013-05-03 13:40:13 -07009240 getDisplayContentLocked(displayId).stopDimmingIfNeeded();
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009241
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08009242 if (updateAllDrawn) {
9243 updateAllDrawnLocked(displayContent);
9244 }
Craig Mautner6fbda632012-07-03 09:26:39 -07009245 }
9246
Craig Mautner7358fbf2012-04-12 21:06:33 -07009247 if (focusDisplayed) {
9248 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
9249 }
Craig Mautner65d11b32012-10-01 13:59:52 -07009250
9251 // Give the display manager a chance to adjust properties
9252 // like display rotation if it needs to.
Jeff Brown4ccb8232014-01-16 22:16:42 -08009253 mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
Craig Mautner65d11b32012-10-01 13:59:52 -07009254
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009255 } catch (RuntimeException e) {
Dianne Hackborn89620282011-09-11 12:47:45 -07009256 Log.wtf(TAG, "Unhandled exception in Window Manager", e);
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07009257 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -08009258 SurfaceControl.closeTransaction();
Chet Haased5d11af2012-10-31 08:57:17 -07009259 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
9260 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009261 }
9262
Craig Mautner76a71652012-09-03 23:23:58 -07009263 final WindowList defaultWindows = defaultDisplay.getWindowList();
9264
Craig Mautner764983d2012-03-22 11:37:36 -07009265 // If we are ready to perform an app transition, check through
9266 // all of the app tokens to be shown and see if they are ready
9267 // to go.
Craig Mautner164d4bb2012-11-26 13:51:23 -08009268 if (mAppTransition.isReady()) {
Craig Mautner76a71652012-09-03 23:23:58 -07009269 defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009270 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAppTransitionReadyLocked",
Craig Mautnerae446592012-12-06 19:05:05 -08009271 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009272 }
9273
Craig Mautner164d4bb2012-11-26 13:51:23 -08009274 if (!mAnimator.mAnimating && mAppTransition.isRunning()) {
Craig Mautner764983d2012-03-22 11:37:36 -07009275 // We have finished the animation of an app transition. To do
9276 // this, we have delayed a lot of operations like showing and
9277 // hiding apps, moving apps in Z-order, etc. The app token list
9278 // reflects the correct Z-order, but the window list may now
9279 // be out of sync with it. So here we will just rebuild the
9280 // entire app window list. Fun!
Craig Mautner76a71652012-09-03 23:23:58 -07009281 defaultDisplay.pendingLayoutChanges |= handleAnimatingStoppedAndTransitionLocked();
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009282 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAnimStopAndXitionLock",
Craig Mautner76a71652012-09-03 23:23:58 -07009283 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009284 }
9285
Craig Mautner76a71652012-09-03 23:23:58 -07009286 if (mInnerFields.mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
Craig Mautner164d4bb2012-11-26 13:51:23 -08009287 && !mAppTransition.isReady()) {
Craig Mautner764983d2012-03-22 11:37:36 -07009288 // At this point, there was a window with a wallpaper that
9289 // was force hiding other windows behind it, but now it
9290 // is going away. This may be simple -- just animate
9291 // away the wallpaper and its window -- or it may be
9292 // hard -- the wallpaper now needs to be shown behind
9293 // something that was hidden.
Craig Mautnerae446592012-12-06 19:05:05 -08009294 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009295 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animateAwayWallpaperLocked",
Craig Mautner76a71652012-09-03 23:23:58 -07009296 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009297 }
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009298 mInnerFields.mWallpaperForceHidingChanged = false;
Craig Mautner764983d2012-03-22 11:37:36 -07009299
Craig Mautnere7ae2502012-03-26 17:11:19 -07009300 if (mInnerFields.mWallpaperMayChange) {
Craig Mautner11462cc2013-05-13 15:56:18 -07009301 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Wallpaper may change! Adjusting");
Craig Mautnerae446592012-12-06 19:05:05 -08009302 defaultDisplay.pendingLayoutChanges |=
9303 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
9304 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
9305 defaultDisplay.pendingLayoutChanges);
Craig Mautnere7ae2502012-03-26 17:11:19 -07009306 }
9307
9308 if (mFocusMayChange) {
9309 mFocusMayChange = false;
9310 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
9311 false /*updateInputWindows*/)) {
Craig Mautner76a71652012-09-03 23:23:58 -07009312 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
Craig Mautnere7ae2502012-03-26 17:11:19 -07009313 }
9314 }
Craig Mautner764983d2012-03-22 11:37:36 -07009315
Craig Mautner19d59bc2012-09-04 11:15:56 -07009316 if (needsLayout()) {
Craig Mautner76a71652012-09-03 23:23:58 -07009317 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
9318 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
9319 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009320 }
9321
Craig Mautnerade0a9a2012-10-06 13:55:07 -07009322 for (i = mResizingWindows.size() - 1; i >= 0; i--) {
9323 WindowState win = mResizingWindows.get(i);
9324 if (win.mAppFreezing) {
9325 // Don't remove this window until rotation has completed.
9326 continue;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009327 }
Craig Mautnerdf88d732014-01-27 09:21:32 -08009328 win.reportResized();
Craig Mautnerade0a9a2012-10-06 13:55:07 -07009329 mResizingWindows.remove(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009330 }
Romain Guy06882f82009-06-10 13:36:04 -07009331
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009332 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
9333 "With display frozen, orientationChangeComplete="
9334 + mInnerFields.mOrientationChangeComplete);
9335 if (mInnerFields.mOrientationChangeComplete) {
9336 if (mWindowsFreezingScreen) {
9337 mWindowsFreezingScreen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009338 mLastFinishedFreezeSource = mInnerFields.mLastWindowFreezeSource;
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009339 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
9340 }
9341 stopFreezingDisplayLocked();
9342 }
9343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009344 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009345 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009346 i = mDestroySurface.size();
9347 if (i > 0) {
9348 do {
9349 i--;
9350 WindowState win = mDestroySurface.get(i);
9351 win.mDestroying = false;
9352 if (mInputMethodWindow == win) {
9353 mInputMethodWindow = null;
9354 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009355 if (win == mWallpaperTarget) {
9356 wallpaperDestroyed = true;
9357 }
Craig Mautner96868332012-12-04 14:29:11 -08009358 win.mWinAnimator.destroySurfaceLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009359 } while (i > 0);
9360 mDestroySurface.clear();
9361 }
9362
9363 // Time to remove any exiting tokens?
Craig Mautnerf8924152013-07-16 09:10:55 -07009364 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9365 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08009366 ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
9367 for (i = exitingTokens.size() - 1; i >= 0; i--) {
9368 WindowToken token = exitingTokens.get(i);
9369 if (!token.hasVisible) {
9370 exitingTokens.remove(i);
9371 if (token.windowType == TYPE_WALLPAPER) {
9372 mWallpaperTokens.remove(token);
9373 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07009374 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009375 }
Craig Mautnerdc548482014-02-05 13:35:24 -08009376 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009377
Craig Mautnerdc548482014-02-05 13:35:24 -08009378 // Time to remove any exiting applications?
9379 for (int stackNdx = mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
9380 // Initialize state of exiting applications.
9381 final AppTokenList exitingAppTokens =
9382 mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08009383 for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
9384 AppWindowToken token = exitingAppTokens.get(i);
9385 if (!token.hasVisible && !mClosingApps.contains(token)) {
9386 // Make sure there is no animation running on this token,
9387 // so any windows associated with it will be removed as
9388 // soon as their animations are complete
9389 token.mAppAnimator.clearAnimation();
9390 token.mAppAnimator.animating = false;
9391 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
9392 "performLayout: App token exiting now removed" + token);
Craig Mautner9ef471f2014-02-07 13:11:47 -08009393 removeAppFromTaskLocked(token);
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08009394 exitingAppTokens.remove(i);
9395 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009396 }
9397 }
9398
Dianne Hackborn12d3a942012-04-27 14:16:30 -07009399 if (!mAnimator.mAnimating && mRelayoutWhileAnimating.size() > 0) {
9400 for (int j=mRelayoutWhileAnimating.size()-1; j>=0; j--) {
9401 try {
9402 mRelayoutWhileAnimating.get(j).mClient.doneAnimating();
9403 } catch (RemoteException e) {
9404 }
9405 }
9406 mRelayoutWhileAnimating.clear();
9407 }
9408
Craig Mautnerae446592012-12-06 19:05:05 -08009409 if (wallpaperDestroyed) {
9410 defaultDisplay.pendingLayoutChanges |=
9411 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
9412 defaultDisplay.layoutNeeded = true;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009413 }
Craig Mautner76a71652012-09-03 23:23:58 -07009414
Craig Mautnerf8924152013-07-16 09:10:55 -07009415 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9416 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautner76a71652012-09-03 23:23:58 -07009417 if (displayContent.pendingLayoutChanges != 0) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009418 displayContent.layoutNeeded = true;
Craig Mautner76a71652012-09-03 23:23:58 -07009419 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009420 }
Jeff Browneb857f12010-07-16 10:06:33 -07009421
Jeff Brown3a22cd92011-01-21 13:59:04 -08009422 // Finally update all input windows now that the window changes have stabilized.
Jeff Brown2e44b072011-01-24 15:21:56 -08009423 mInputMonitor.updateInputWindowsLw(true /*force*/);
Jeff Browneb857f12010-07-16 10:06:33 -07009424
Craig Mautner259328c2012-08-21 19:30:58 -07009425 setHoldScreenLocked(mInnerFields.mHoldScreen);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009426 if (!mDisplayFrozen) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009427 if (mInnerFields.mScreenBrightness < 0 || mInnerFields.mScreenBrightness > 1.0f) {
Jeff Brown6f357d32014-01-15 20:40:55 -08009428 mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009429 } else {
Jeff Brown6f357d32014-01-15 20:40:55 -08009430 mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
Jeff Brown96307042012-07-27 15:51:34 -07009431 toBrightnessOverride(mInnerFields.mScreenBrightness));
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009432 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009433 if (mInnerFields.mButtonBrightness < 0 || mInnerFields.mButtonBrightness > 1.0f) {
Jeff Brown6f357d32014-01-15 20:40:55 -08009434 mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009435 } else {
Jeff Brown6f357d32014-01-15 20:40:55 -08009436 mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
Jeff Brown96307042012-07-27 15:51:34 -07009437 toBrightnessOverride(mInnerFields.mButtonBrightness));
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009438 }
Jeff Brown6f357d32014-01-15 20:40:55 -08009439 mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
Jeff Brown1e3b98d2012-09-30 18:58:59 -07009440 mInnerFields.mUserActivityTimeout);
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009441 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009442
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009443 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009444 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Jeff Brown96307042012-07-27 15:51:34 -07009445 mPowerManager.wakeUp(SystemClock.uptimeMillis());
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009446 mTurnOnScreen = false;
9447 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009448
Craig Mautnera608b882012-03-30 13:03:49 -07009449 if (mInnerFields.mUpdateRotation) {
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009450 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009451 if (updateRotationUncheckedLocked(false)) {
Dianne Hackborn3e4f9d02011-02-04 14:05:55 -08009452 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07009453 } else {
Craig Mautnera608b882012-03-30 13:03:49 -07009454 mInnerFields.mUpdateRotation = false;
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009455 }
9456 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009457
Craig Mautner19d59bc2012-09-04 11:15:56 -07009458 if (mInnerFields.mOrientationChangeComplete && !defaultDisplay.layoutNeeded
9459 && !mInnerFields.mUpdateRotation) {
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07009460 checkDrawnWindowsLocked();
9461 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009462
Craig Mautner76a71652012-09-03 23:23:58 -07009463 final int N = mPendingRemove.size();
9464 if (N > 0) {
9465 if (mPendingRemoveTmp.length < N) {
9466 mPendingRemoveTmp = new WindowState[N+10];
9467 }
9468 mPendingRemove.toArray(mPendingRemoveTmp);
9469 mPendingRemove.clear();
9470 DisplayContentList displayList = new DisplayContentList();
9471 for (i = 0; i < N; i++) {
9472 WindowState w = mPendingRemoveTmp[i];
9473 removeWindowInnerLocked(w.mSession, w);
Craig Mautnerdf88d732014-01-27 09:21:32 -08009474 final DisplayContent displayContent = w.getDisplayContent();
9475 if (displayContent != null && !displayList.contains(displayContent)) {
9476 displayList.add(displayContent);
Craig Mautner76a71652012-09-03 23:23:58 -07009477 }
9478 }
9479
9480 for (DisplayContent displayContent : displayList) {
9481 assignLayersLocked(displayContent.getWindowList());
Craig Mautner19d59bc2012-09-04 11:15:56 -07009482 displayContent.layoutNeeded = true;
Craig Mautner76a71652012-09-03 23:23:58 -07009483 }
Craig Mautner76a71652012-09-03 23:23:58 -07009484 }
9485
Craig Mautner9ef471f2014-02-07 13:11:47 -08009486 // Remove all deferred Stacks, tasks, and activities.
9487 for (int stackNdx = mPendingStacksRemove.size() - 1; stackNdx >= 0; --stackNdx) {
9488 mPendingStacksRemove.removeAt(stackNdx).checkForDeferredActions();
9489 }
9490
Craig Mautnerf7666462013-04-28 08:58:21 -07009491 setFocusedStackFrame();
Craig Mautnerc5a6e442013-06-05 17:22:35 -07009492
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08009493 // Check to see if we are now in a state where the screen should
9494 // be enabled, because the window obscured flags have changed.
9495 enableScreenIfNeededLocked();
Craig Mautner7d8df392012-04-06 15:26:23 -07009496
Craig Mautner96868332012-12-04 14:29:11 -08009497 scheduleAnimationLocked();
Craig Mautner7d8df392012-04-06 15:26:23 -07009498
9499 if (DEBUG_WINDOW_TRACE) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009500 Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: animating="
9501 + mAnimator.mAnimating);
Craig Mautner7d8df392012-04-06 15:26:23 -07009502 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009503 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009504
Jeff Brown96307042012-07-27 15:51:34 -07009505 private int toBrightnessOverride(float value) {
9506 return (int)(value * PowerManager.BRIGHTNESS_ON);
9507 }
9508
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009509 void checkDrawnWindowsLocked() {
9510 if (mWaitingForDrawn.size() > 0) {
9511 for (int j=mWaitingForDrawn.size()-1; j>=0; j--) {
9512 Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(j);
9513 WindowState win = pair.first;
9514 //Slog.i(TAG, "Waiting for drawn " + win + ": removed="
9515 // + win.mRemoved + " visible=" + win.isVisibleLw()
9516 // + " shown=" + win.mSurfaceShown);
Craig Mautner4e8a19c2013-10-08 17:26:08 -07009517 if (win.mRemoved) {
9518 // Window has been removed; no draw will now happen, so stop waiting.
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009519 Slog.w(TAG, "Aborted waiting for drawn: " + pair.first);
9520 try {
9521 pair.second.sendResult(null);
9522 } catch (RemoteException e) {
9523 }
9524 mWaitingForDrawn.remove(pair);
9525 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009526 } else if (win.mWinAnimator.mSurfaceShown) {
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009527 // Window is now drawn (and shown).
9528 try {
9529 pair.second.sendResult(null);
9530 } catch (RemoteException e) {
9531 }
9532 mWaitingForDrawn.remove(pair);
9533 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9534 }
9535 }
9536 }
9537 }
9538
Craig Mautner2268e7e2012-12-13 15:40:00 -08009539 @Override
Jeff Brownc38c9be2012-10-04 13:16:19 -07009540 public boolean waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
9541 if (token != null && callback != null) {
9542 synchronized (mWindowMap) {
9543 WindowState win = windowForClientLocked(null, token, true);
9544 if (win != null) {
9545 Pair<WindowState, IRemoteCallback> pair =
9546 new Pair<WindowState, IRemoteCallback>(win, callback);
9547 Message m = mH.obtainMessage(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9548 mH.sendMessageDelayed(m, 2000);
9549 mWaitingForDrawn.add(pair);
9550 checkDrawnWindowsLocked();
9551 return true;
9552 }
Craig Mautner4e8a19c2013-10-08 17:26:08 -07009553 Slog.i(TAG, "waitForWindowDrawn: win null");
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009554 }
9555 }
Jeff Brownc38c9be2012-10-04 13:16:19 -07009556 return false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009557 }
9558
Craig Mautner259328c2012-08-21 19:30:58 -07009559 void setHoldScreenLocked(final Session newHoldScreen) {
9560 final boolean hold = newHoldScreen != null;
9561
9562 if (hold && mHoldingScreenOn != newHoldScreen) {
9563 mHoldingScreenWakeLock.setWorkSource(new WorkSource(newHoldScreen.mUid));
9564 }
9565 mHoldingScreenOn = newHoldScreen;
9566
9567 final boolean state = mHoldingScreenWakeLock.isHeld();
9568 if (hold != state) {
9569 if (hold) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07009570 mHoldingScreenWakeLock.acquire();
Jeff Brownc38c9be2012-10-04 13:16:19 -07009571 mPolicy.keepScreenOnStartedLw();
Jeff Brown46b9ac02010-04-22 18:58:52 -07009572 } else {
Jeff Brownc38c9be2012-10-04 13:16:19 -07009573 mPolicy.keepScreenOnStoppedLw();
Jeff Brown46b9ac02010-04-22 18:58:52 -07009574 mHoldingScreenWakeLock.release();
9575 }
9576 }
9577 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009578
Jeff Brown4ccb8232014-01-16 22:16:42 -08009579 void requestTraversal() {
Jeff Brown4ed8fe72012-08-30 18:18:29 -07009580 synchronized (mWindowMap) {
9581 requestTraversalLocked();
9582 }
9583 }
9584
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08009585 void requestTraversalLocked() {
9586 if (!mTraversalScheduled) {
9587 mTraversalScheduled = true;
9588 mH.sendEmptyMessage(H.DO_TRAVERSAL);
9589 }
9590 }
9591
Craig Mautner711f90a2012-07-03 18:43:52 -07009592 /** Note that Locked in this case is on mLayoutToAnim */
Jeff Brown4a06c802012-02-15 15:06:01 -08009593 void scheduleAnimationLocked() {
Craig Mautner96868332012-12-04 14:29:11 -08009594 if (!mAnimationScheduled) {
9595 mAnimationScheduled = true;
Craig Mautner711f90a2012-07-03 18:43:52 -07009596 mChoreographer.postCallback(
9597 Choreographer.CALLBACK_ANIMATION, mAnimator.mAnimationRunnable, null);
9598 }
9599 }
9600
Craig Mautner19d59bc2012-09-04 11:15:56 -07009601 private boolean needsLayout() {
Craig Mautnerf8924152013-07-16 09:10:55 -07009602 final int numDisplays = mDisplayContents.size();
9603 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9604 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
9605 if (displayContent.layoutNeeded) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009606 return true;
9607 }
9608 }
9609 return false;
9610 }
9611
Craig Mautner96868332012-12-04 14:29:11 -08009612 boolean copyAnimToLayoutParamsLocked() {
Craig Mautner322e4032012-07-13 13:35:20 -07009613 boolean doRequest = false;
Craig Mautner322e4032012-07-13 13:35:20 -07009614
Craig Mautner96868332012-12-04 14:29:11 -08009615 final int bulkUpdateParams = mAnimator.mBulkUpdateParams;
Craig Mautner96868332012-12-04 14:29:11 -08009616 if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) {
9617 mInnerFields.mUpdateRotation = true;
9618 doRequest = true;
Craig Mautner322e4032012-07-13 13:35:20 -07009619 }
Craig Mautner96868332012-12-04 14:29:11 -08009620 if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
9621 mInnerFields.mWallpaperMayChange = true;
9622 doRequest = true;
9623 }
9624 if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
9625 mInnerFields.mWallpaperForceHidingChanged = true;
9626 doRequest = true;
9627 }
9628 if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
9629 mInnerFields.mOrientationChangeComplete = false;
9630 } else {
9631 mInnerFields.mOrientationChangeComplete = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009632 mInnerFields.mLastWindowFreezeSource = mAnimator.mLastWindowFreezeSource;
Craig Mautner96868332012-12-04 14:29:11 -08009633 if (mWindowsFreezingScreen) {
9634 doRequest = true;
9635 }
9636 }
9637 if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
9638 mTurnOnScreen = true;
9639 }
9640 if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_ACTION_PENDING) != 0) {
9641 mInnerFields.mWallpaperActionPending = true;
9642 }
9643
Craig Mautner322e4032012-07-13 13:35:20 -07009644 return doRequest;
9645 }
9646
Craig Mautner6201c2a2013-08-09 18:48:48 -07009647 /** If a window that has an animation specifying a colored background and the current wallpaper
9648 * is visible, then the color goes *below* the wallpaper so we don't cause the wallpaper to
Craig Mautner05d29032013-05-03 13:40:13 -07009649 * suddenly disappear. */
9650 int adjustAnimationBackground(WindowStateAnimator winAnimator) {
Craig Mautner6201c2a2013-08-09 18:48:48 -07009651 WindowList windows = winAnimator.mWin.getWindowList();
9652 for (int i = windows.size() - 1; i >= 0; --i) {
9653 WindowState testWin = windows.get(i);
9654 if (testWin.mIsWallpaper && testWin.isVisibleNow()) {
9655 return testWin.mWinAnimator.mAnimLayer;
Craig Mautner05d29032013-05-03 13:40:13 -07009656 }
9657 }
9658 return winAnimator.mAnimLayer;
9659 }
9660
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009661 boolean reclaimSomeSurfaceMemoryLocked(WindowStateAnimator winAnimator, String operation,
9662 boolean secure) {
Mathias Agopian29479eb2013-02-14 14:36:04 -08009663 final SurfaceControl surface = winAnimator.mSurfaceControl;
Dianne Hackborn64825172011-03-02 21:32:58 -08009664 boolean leakedSurface = false;
9665 boolean killedApps = false;
Romain Guy06882f82009-06-10 13:36:04 -07009666
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009667 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
9668 winAnimator.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -07009669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009670 if (mForceRemoves == null) {
9671 mForceRemoves = new ArrayList<WindowState>();
9672 }
Romain Guy06882f82009-06-10 13:36:04 -07009673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009674 long callingIdentity = Binder.clearCallingIdentity();
9675 try {
9676 // There was some problem... first, do a sanity check of the
9677 // window list to make sure we haven't left any dangling surfaces
9678 // around.
Craig Mautner59c00972012-07-30 12:10:24 -07009679
Joe Onorato8a9b2202010-02-26 18:56:32 -08009680 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
Craig Mautnerf8924152013-07-16 09:10:55 -07009681 final int numDisplays = mDisplayContents.size();
9682 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9683 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
9684 final int numWindows = windows.size();
9685 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
9686 final WindowState ws = windows.get(winNdx);
9687 WindowStateAnimator wsa = ws.mWinAnimator;
9688 if (wsa.mSurfaceControl != null) {
9689 if (!mSessions.contains(wsa.mSession)) {
9690 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
9691 + ws + " surface=" + wsa.mSurfaceControl
9692 + " token=" + ws.mToken
9693 + " pid=" + ws.mSession.mPid
9694 + " uid=" + ws.mSession.mUid);
9695 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
9696 wsa.mSurfaceControl.destroy();
9697 wsa.mSurfaceShown = false;
9698 wsa.mSurfaceControl = null;
9699 ws.mHasSurface = false;
9700 mForceRemoves.add(ws);
9701 leakedSurface = true;
9702 } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
9703 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
9704 + ws + " surface=" + wsa.mSurfaceControl
9705 + " token=" + ws.mAppToken);
9706 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
9707 wsa.mSurfaceControl.destroy();
9708 wsa.mSurfaceShown = false;
9709 wsa.mSurfaceControl = null;
9710 ws.mHasSurface = false;
9711 leakedSurface = true;
9712 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009713 }
9714 }
9715 }
Romain Guy06882f82009-06-10 13:36:04 -07009716
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009717 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009718 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009719 SparseIntArray pidCandidates = new SparseIntArray();
Craig Mautnerf8924152013-07-16 09:10:55 -07009720 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9721 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
9722 final int numWindows = windows.size();
9723 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
9724 final WindowState ws = windows.get(winNdx);
9725 if (mForceRemoves.contains(ws)) {
9726 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009727 }
Craig Mautnerf8924152013-07-16 09:10:55 -07009728 WindowStateAnimator wsa = ws.mWinAnimator;
9729 if (wsa.mSurfaceControl != null) {
9730 pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
9731 }
9732 }
9733 if (pidCandidates.size() > 0) {
9734 int[] pids = new int[pidCandidates.size()];
9735 for (int i=0; i<pids.length; i++) {
9736 pids[i] = pidCandidates.keyAt(i);
9737 }
9738 try {
9739 if (mActivityManager.killPids(pids, "Free memory", secure)) {
9740 killedApps = true;
9741 }
9742 } catch (RemoteException e) {
9743 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009744 }
9745 }
9746 }
Romain Guy06882f82009-06-10 13:36:04 -07009747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009748 if (leakedSurface || killedApps) {
9749 // We managed to reclaim some memory, so get rid of the trouble
9750 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -08009751 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009752 if (surface != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009753 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
Dianne Hackborn5fd21692011-06-07 14:09:47 -07009754 "RECOVER DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009755 surface.destroy();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009756 winAnimator.mSurfaceShown = false;
Mathias Agopian29479eb2013-02-14 14:36:04 -08009757 winAnimator.mSurfaceControl = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009758 winAnimator.mWin.mHasSurface = false;
Craig Mautner68cc2412013-10-01 10:39:43 -07009759 scheduleRemoveStartingWindow(winAnimator.mWin.mAppToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009760 }
Romain Guy06882f82009-06-10 13:36:04 -07009761
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009762 try {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009763 winAnimator.mWin.mClient.dispatchGetNewSurface();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009764 } catch (RemoteException e) {
9765 }
9766 }
9767 } finally {
9768 Binder.restoreCallingIdentity(callingIdentity);
9769 }
Dianne Hackborn64825172011-03-02 21:32:58 -08009770
9771 return leakedSurface || killedApps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009772 }
Romain Guy06882f82009-06-10 13:36:04 -07009773
Jeff Brown3a22cd92011-01-21 13:59:04 -08009774 private boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009775 WindowState newFocus = computeFocusedWindowLocked();
9776 if (mCurrentFocus != newFocus) {
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07009777 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009778 // This check makes sure that we don't already have the focus
9779 // change message pending.
9780 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
9781 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Satoshi Kataoka02679f62013-05-20 16:13:44 +09009782 // TODO(multidisplay): Focused windows on default display only.
9783 final DisplayContent displayContent = getDefaultDisplayContentLocked();
9784 final boolean imWindowChanged = moveInputMethodWindowsIfNeededLocked(
9785 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS
9786 && mode != UPDATE_FOCUS_WILL_PLACE_SURFACES);
9787 if (imWindowChanged) {
9788 displayContent.layoutNeeded = true;
9789 newFocus = computeFocusedWindowLocked();
9790 }
9791
Craig Mautnera7f2bd42013-10-15 16:13:50 -07009792 if (DEBUG_FOCUS_LIGHT || localLOGV) Slog.v(TAG, "Changing focus from " +
Craig Mautnerb3370ce2013-09-19 12:02:09 -07009793 mCurrentFocus + " to " + newFocus + " Callers=" + Debug.getCallers(4));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009794 final WindowState oldFocus = mCurrentFocus;
9795 mCurrentFocus = newFocus;
9796 mLosingFocus.remove(newFocus);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009797 int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus);
Romain Guy06882f82009-06-10 13:36:04 -07009798
Satoshi Kataoka12afe142013-05-21 06:19:27 +09009799 if (imWindowChanged && oldFocus != mInputMethodWindow) {
Satoshi Kataoka02679f62013-05-20 16:13:44 +09009800 // Focus of the input method window changed. Perform layout if needed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009801 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Craig Mautner59c00972012-07-30 12:10:24 -07009802 performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009803 focusChanged &= ~WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009804 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
9805 // Client will do the layout, but we need to assign layers
9806 // for handleNewWindowLocked() below.
Craig Mautner59c00972012-07-30 12:10:24 -07009807 assignLayersLocked(displayContent.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009808 }
9809 }
Dianne Hackborndf89e652011-10-06 22:35:11 -07009810
Craig Mautner39834192012-09-02 07:47:24 -07009811 if ((focusChanged & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07009812 // The change in focus caused us to need to do a layout. Okay.
Jeff Brown20337632012-09-24 14:25:54 -07009813 displayContent.layoutNeeded = true;
Dianne Hackborndf89e652011-10-06 22:35:11 -07009814 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Craig Mautner59c00972012-07-30 12:10:24 -07009815 performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009816 }
9817 }
9818
Jeff Brown349703e2010-06-22 01:27:15 -07009819 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
9820 // If we defer assigning layers, then the caller is responsible for
9821 // doing this part.
Jeff Brown3a22cd92011-01-21 13:59:04 -08009822 finishUpdateFocusedWindowAfterAssignLayersLocked(updateInputWindows);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009823 }
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07009824
9825 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009826 return true;
9827 }
9828 return false;
9829 }
Craig Mautner66f78d72012-12-04 16:46:50 -08009830
Jeff Brown3a22cd92011-01-21 13:59:04 -08009831 private void finishUpdateFocusedWindowAfterAssignLayersLocked(boolean updateInputWindows) {
9832 mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows);
Jeff Brown349703e2010-06-22 01:27:15 -07009833 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009834
9835 private WindowState computeFocusedWindowLocked() {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07009836 if (mAnimator.mUniverseBackground != null
9837 && mAnimator.mUniverseBackground.mWin.canReceiveKeys()) {
9838 return mAnimator.mUniverseBackground.mWin;
9839 }
9840
Jeff Brown20337632012-09-24 14:25:54 -07009841 final int displayCount = mDisplayContents.size();
9842 for (int i = 0; i < displayCount; i++) {
9843 final DisplayContent displayContent = mDisplayContents.valueAt(i);
9844 WindowState win = findFocusedWindowLocked(displayContent);
9845 if (win != null) {
9846 return win;
9847 }
9848 }
9849 return null;
9850 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009851
Jeff Brown20337632012-09-24 14:25:54 -07009852 private WindowState findFocusedWindowLocked(DisplayContent displayContent) {
Jeff Brown20337632012-09-24 14:25:54 -07009853 final WindowList windows = displayContent.getWindowList();
Craig Mautner59c00972012-07-30 12:10:24 -07009854 for (int i = windows.size() - 1; i >= 0; i--) {
Jeff Brown20337632012-09-24 14:25:54 -07009855 final WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009856
Joe Onorato8a9b2202010-02-26 18:56:32 -08009857 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009858 TAG, "Looking for focus: " + i
9859 + " = " + win
9860 + ", flags=" + win.mAttrs.flags
9861 + ", canReceive=" + win.canReceiveKeys());
9862
Craig Mautnerac565142013-09-23 17:37:09 -07009863 AppWindowToken wtoken = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -07009864
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009865 // If this window's application has been removed, just skip it.
Craig Mautnerac565142013-09-23 17:37:09 -07009866 if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) {
9867 if (DEBUG_FOCUS) Slog.v(TAG, "Skipping " + wtoken + " because "
9868 + (wtoken.removed ? "removed" : "sendingToBottom"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009869 continue;
9870 }
Romain Guy06882f82009-06-10 13:36:04 -07009871
Craig Mautnerac565142013-09-23 17:37:09 -07009872 if (!win.canReceiveKeys()) {
9873 continue;
9874 }
9875
9876 // Descend through all of the app tokens and find the first that either matches
9877 // win.mAppToken (return win) or mFocusedApp (return null).
9878 if (wtoken != null && win.mAttrs.type != TYPE_APPLICATION_STARTING &&
9879 mFocusedApp != null) {
9880 ArrayList<Task> tasks = displayContent.getTasks();
9881 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
9882 AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
9883 int tokenNdx = tokens.size() - 1;
Craig Mautnerf81b90872013-02-26 13:02:43 -08009884 for ( ; tokenNdx >= 0; --tokenNdx) {
Craig Mautnerac565142013-09-23 17:37:09 -07009885 final AppWindowToken token = tokens.get(tokenNdx);
9886 if (wtoken == token) {
Craig Mautnerf81b90872013-02-26 13:02:43 -08009887 break;
9888 }
Craig Mautnerac565142013-09-23 17:37:09 -07009889 if (mFocusedApp == token) {
9890 // Whoops, we are below the focused app... no focus for you!
9891 if (localLOGV || DEBUG_FOCUS_LIGHT) Slog.v(TAG,
9892 "findFocusedWindow: Reached focused app=" + mFocusedApp);
9893 return null;
9894 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009895 }
Craig Mautnerac565142013-09-23 17:37:09 -07009896 if (tokenNdx >= 0) {
9897 // Early exit from loop, must have found the matching token.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009898 break;
9899 }
9900 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009901 }
9902
Craig Mautnerac565142013-09-23 17:37:09 -07009903 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "findFocusedWindow: Found new focus @ " + i +
9904 " = " + win);
9905 return win;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009906 }
Craig Mautnerac565142013-09-23 17:37:09 -07009907
Craig Mautner58458122013-09-14 14:59:50 -07009908 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "findFocusedWindow: No focusable windows.");
Jeff Brown20337632012-09-24 14:25:54 -07009909 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009910 }
9911
Craig Mautner3c174372013-02-21 17:54:37 -08009912 private void startFreezingDisplayLocked(boolean inTransaction, int exitAnim, int enterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009913 if (mDisplayFrozen) {
9914 return;
9915 }
Romain Guy06882f82009-06-10 13:36:04 -07009916
Jeff Browne215f262012-09-10 16:01:14 -07009917 if (!mDisplayReady || !mPolicy.isScreenOnFully()) {
Dianne Hackborn8e8d65f2011-08-11 19:36:18 -07009918 // No need to freeze the screen before the system is ready or if
9919 // the screen is off.
9920 return;
9921 }
9922
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009923 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -07009924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009925 mDisplayFrozen = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009926 mDisplayFreezeTime = SystemClock.elapsedRealtime();
9927 mLastFinishedFreezeSource = null;
Craig Mautner7d8df392012-04-06 15:26:23 -07009928
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009929 mInputMonitor.freezeInputDispatchingLw();
Craig Mautner7d8df392012-04-06 15:26:23 -07009930
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07009931 // Clear the last input window -- that is just used for
9932 // clean transitions between IMEs, and if we are freezing
9933 // the screen then the whole world is changing behind the scenes.
9934 mPolicy.setLastInputMethodWindowLw(null, null);
9935
Craig Mautner164d4bb2012-11-26 13:51:23 -08009936 if (mAppTransition.isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08009937 mAppTransition.freeze();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009938 }
Romain Guy06882f82009-06-10 13:36:04 -07009939
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009940 if (PROFILE_ORIENTATION) {
9941 File file = new File("/data/system/frozen");
9942 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
9943 }
Dianne Hackborna1111872010-11-23 20:55:11 -08009944
9945 if (CUSTOM_SCREEN_ROTATION) {
Craig Mautner3c174372013-02-21 17:54:37 -08009946 mExitAnimId = exitAnim;
9947 mEnterAnimId = enterAnim;
Craig Mautnera91f9e22012-09-14 16:22:08 -07009948 final DisplayContent displayContent = getDefaultDisplayContentLocked();
9949 final int displayId = displayContent.getDisplayId();
9950 ScreenRotationAnimation screenRotationAnimation =
9951 mAnimator.getScreenRotationAnimationLocked(displayId);
9952 if (screenRotationAnimation != null) {
9953 screenRotationAnimation.kill();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08009954 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07009955
Craig Mautner59c00972012-07-30 12:10:24 -07009956 // TODO(multidisplay): rotation on main screen only.
Craig Mautner46ac6fa2013-08-01 10:06:34 -07009957 screenRotationAnimation = new ScreenRotationAnimation(mContext, displayContent,
9958 mFxSession, inTransaction, mPolicy.isDefaultOrientationForced());
Craig Mautnera91f9e22012-09-14 16:22:08 -07009959 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackborna1111872010-11-23 20:55:11 -08009960 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009961 }
Romain Guy06882f82009-06-10 13:36:04 -07009962
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009963 private void stopFreezingDisplayLocked() {
9964 if (!mDisplayFrozen) {
9965 return;
9966 }
Romain Guy06882f82009-06-10 13:36:04 -07009967
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009968 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen
9969 || mClientFreezingScreen) {
Craig Mautnerd87946b2012-03-29 18:00:19 -07009970 if (DEBUG_ORIENTATION) Slog.d(TAG,
9971 "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + mWaitingForConfig
9972 + ", mAppsFreezingScreen=" + mAppsFreezingScreen
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009973 + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen
9974 + ", mClientFreezingScreen=" + mClientFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009975 return;
9976 }
Craig Mautner66f78d72012-12-04 16:46:50 -08009977
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009978 mDisplayFrozen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009979 mLastDisplayFreezeDuration = (int)(SystemClock.elapsedRealtime() - mDisplayFreezeTime);
9980 StringBuilder sb = new StringBuilder(128);
9981 sb.append("Screen frozen for ");
9982 TimeUtils.formatDuration(mLastDisplayFreezeDuration, sb);
9983 if (mLastFinishedFreezeSource != null) {
9984 sb.append(" due to ");
9985 sb.append(mLastFinishedFreezeSource);
9986 }
9987 Slog.i(TAG, sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009988 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009989 mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009990 if (PROFILE_ORIENTATION) {
9991 Debug.stopMethodTracing();
9992 }
Dianne Hackborna1111872010-11-23 20:55:11 -08009993
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009994 boolean updateRotation = false;
Craig Mautner59c00972012-07-30 12:10:24 -07009995
Craig Mautnera91f9e22012-09-14 16:22:08 -07009996 final DisplayContent displayContent = getDefaultDisplayContentLocked();
9997 final int displayId = displayContent.getDisplayId();
9998 ScreenRotationAnimation screenRotationAnimation =
9999 mAnimator.getScreenRotationAnimationLocked(displayId);
10000 if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
10001 && screenRotationAnimation.hasScreenshot()) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -070010002 if (DEBUG_ORIENTATION) Slog.i(TAG, "**** Dismissing screen rotation animation");
Craig Mautner59c00972012-07-30 12:10:24 -070010003 // TODO(multidisplay): rotation on main screen only.
Craig Mautnera91f9e22012-09-14 16:22:08 -070010004 DisplayInfo displayInfo = displayContent.getDisplayInfo();
Craig Mautner3c174372013-02-21 17:54:37 -080010005 // Get rotation animation again, with new top window
Craig Mautner05d29032013-05-03 13:40:13 -070010006 boolean isDimming = displayContent.isDimming();
Craig Mautner3c174372013-02-21 17:54:37 -080010007 if (!mPolicy.validateRotationAnimationLw(mExitAnimId, mEnterAnimId, isDimming)) {
10008 mExitAnimId = mEnterAnimId = 0;
10009 }
Craig Mautnera91f9e22012-09-14 16:22:08 -070010010 if (screenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
Craig Mautner59c00972012-07-30 12:10:24 -070010011 mTransitionAnimationScale, displayInfo.logicalWidth,
Craig Mautner3c174372013-02-21 17:54:37 -080010012 displayInfo.logicalHeight, mExitAnimId, mEnterAnimId)) {
Craig Mautner96868332012-12-04 14:29:11 -080010013 scheduleAnimationLocked();
Dianne Hackbornde75cb42011-03-02 17:11:21 -080010014 } else {
Craig Mautnera91f9e22012-09-14 16:22:08 -070010015 screenRotationAnimation.kill();
10016 screenRotationAnimation = null;
10017 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -080010018 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -080010019 }
10020 } else {
Craig Mautnera91f9e22012-09-14 16:22:08 -070010021 if (screenRotationAnimation != null) {
10022 screenRotationAnimation.kill();
10023 screenRotationAnimation = null;
10024 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -080010025 }
10026 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -080010027 }
Romain Guy06882f82009-06-10 13:36:04 -070010028
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010029 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010030
Dianne Hackborn420829e2011-01-28 11:30:35 -080010031 boolean configChanged;
Craig Mautner0bf6ec92012-12-18 08:33:27 -080010032
Christopher Tateb696aee2010-04-02 19:08:30 -070010033 // While the display is frozen we don't re-compute the orientation
10034 // to avoid inconsistent states. However, something interesting
10035 // could have actually changed during that time so re-evaluate it
10036 // now to catch that.
Dianne Hackborn420829e2011-01-28 11:30:35 -080010037 configChanged = updateOrientationFromAppTokensLocked(false);
Christopher Tateb696aee2010-04-02 19:08:30 -070010038
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010039 // A little kludge: a lot could have happened while the
10040 // display was frozen, so now that we are coming back we
10041 // do a gc so that any remote references the system
10042 // processes holds on others can be released if they are
10043 // no longer needed.
10044 mH.removeMessages(H.FORCE_GC);
You Kimcb6291c2012-12-04 23:22:28 +090010045 mH.sendEmptyMessageDelayed(H.FORCE_GC, 2000);
Romain Guy06882f82009-06-10 13:36:04 -070010046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010047 mScreenFrozenLock.release();
Craig Mautner6cfa7292013-01-15 09:05:42 -080010048
Dianne Hackborn89ba6752011-01-23 16:51:16 -080010049 if (updateRotation) {
10050 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Jeff Brown01a98dd2011-09-20 15:08:29 -070010051 configChanged |= updateRotationUncheckedLocked(false);
Dianne Hackborn420829e2011-01-28 11:30:35 -080010052 }
Craig Mautner6cfa7292013-01-15 09:05:42 -080010053
Dianne Hackborn420829e2011-01-28 11:30:35 -080010054 if (configChanged) {
10055 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackborn89ba6752011-01-23 16:51:16 -080010056 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010057 }
Romain Guy06882f82009-06-10 13:36:04 -070010058
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010059 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
10060 DisplayMetrics dm) {
10061 if (index < tokens.length) {
10062 String str = tokens[index];
10063 if (str != null && str.length() > 0) {
10064 try {
10065 int val = Integer.parseInt(str);
10066 return val;
10067 } catch (Exception e) {
10068 }
10069 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010070 }
10071 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
10072 return defDps;
10073 }
10074 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
10075 return val;
10076 }
10077
Jeff Brown4ed8fe72012-08-30 18:18:29 -070010078 void createWatermarkInTransaction() {
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010079 if (mWatermark != null) {
10080 return;
10081 }
10082
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010083 File file = new File("/system/etc/setup.conf");
10084 FileInputStream in = null;
Craig Mautner2268e7e2012-12-13 15:40:00 -080010085 DataInputStream ind = null;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010086 try {
10087 in = new FileInputStream(file);
Craig Mautner2268e7e2012-12-13 15:40:00 -080010088 ind = new DataInputStream(in);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010089 String line = ind.readLine();
10090 if (line != null) {
10091 String[] toks = line.split("%");
10092 if (toks != null && toks.length > 0) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010093 mWatermark = new Watermark(getDefaultDisplayContentLocked().getDisplay(),
Jeff Browne215f262012-09-10 16:01:14 -070010094 mRealDisplayMetrics, mFxSession, toks);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010095 }
10096 }
10097 } catch (FileNotFoundException e) {
10098 } catch (IOException e) {
10099 } finally {
Craig Mautner2268e7e2012-12-13 15:40:00 -080010100 if (ind != null) {
10101 try {
10102 ind.close();
10103 } catch (IOException e) {
10104 }
Craig Mautner0bf6ec92012-12-18 08:33:27 -080010105 } else if (in != null) {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010106 try {
10107 in.close();
10108 } catch (IOException e) {
10109 }
10110 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010111 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010112 }
10113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010114 @Override
Joe Onorato664644d2011-01-23 17:53:23 -080010115 public void statusBarVisibilityChanged(int visibility) {
Dianne Hackborndf89e652011-10-06 22:35:11 -070010116 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
10117 != PackageManager.PERMISSION_GRANTED) {
10118 throw new SecurityException("Caller does not hold permission "
10119 + android.Manifest.permission.STATUS_BAR);
10120 }
Dianne Hackborn9a230e02011-10-06 11:51:27 -070010121
Joe Onorato664644d2011-01-23 17:53:23 -080010122 synchronized (mWindowMap) {
Dianne Hackborndf89e652011-10-06 22:35:11 -070010123 mLastStatusBarVisibility = visibility;
10124 visibility = mPolicy.adjustSystemUiVisibilityLw(visibility);
10125 updateStatusBarVisibilityLocked(visibility);
10126 }
10127 }
10128
Craig Mautner59c00972012-07-30 12:10:24 -070010129 // TOOD(multidisplay): StatusBar on multiple screens?
Dianne Hackborndf89e652011-10-06 22:35:11 -070010130 void updateStatusBarVisibilityLocked(int visibility) {
10131 mInputManager.setSystemUiVisibility(visibility);
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010132 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -070010133 final int N = windows.size();
Dianne Hackborndf89e652011-10-06 22:35:11 -070010134 for (int i = 0; i < N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -070010135 WindowState ws = windows.get(i);
Dianne Hackborndf89e652011-10-06 22:35:11 -070010136 try {
10137 int curValue = ws.mSystemUiVisibility;
10138 int diff = curValue ^ visibility;
10139 // We are only interested in differences of one of the
10140 // clearable flags...
10141 diff &= View.SYSTEM_UI_CLEARABLE_FLAGS;
10142 // ...if it has actually been cleared.
10143 diff &= ~visibility;
10144 int newValue = (curValue&~diff) | (visibility&diff);
10145 if (newValue != curValue) {
10146 ws.mSeq++;
10147 ws.mSystemUiVisibility = newValue;
10148 }
10149 if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) {
10150 ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq,
10151 visibility, newValue, diff);
10152 }
10153 } catch (RemoteException e) {
10154 // so sorry
10155 }
10156 }
10157 }
Craig Mautner6cfa7292013-01-15 09:05:42 -080010158
Dianne Hackborndf89e652011-10-06 22:35:11 -070010159 @Override
10160 public void reevaluateStatusBarVisibility() {
10161 synchronized (mWindowMap) {
10162 int visibility = mPolicy.adjustSystemUiVisibilityLw(mLastStatusBarVisibility);
10163 updateStatusBarVisibilityLocked(visibility);
10164 performLayoutAndPlaceSurfacesLocked();
10165 }
10166 }
10167
10168 @Override
Jeff Brown32cbc38552011-12-01 14:01:49 -080010169 public FakeWindow addFakeWindow(Looper looper,
10170 InputEventReceiver.Factory inputEventReceiverFactory,
Adam Lesinski95c42972013-10-02 10:13:27 -070010171 String name, int windowType, int layoutParamsFlags, int layoutParamsPrivateFlags,
10172 boolean canReceiveKeys, boolean hasFocus, boolean touchFullscreen) {
Dianne Hackborndf89e652011-10-06 22:35:11 -070010173 synchronized (mWindowMap) {
Jeff Brown32cbc38552011-12-01 14:01:49 -080010174 FakeWindowImpl fw = new FakeWindowImpl(this, looper, inputEventReceiverFactory,
10175 name, windowType,
Adam Lesinski95c42972013-10-02 10:13:27 -070010176 layoutParamsFlags, layoutParamsPrivateFlags, canReceiveKeys,
10177 hasFocus, touchFullscreen);
Dianne Hackborndf89e652011-10-06 22:35:11 -070010178 int i=0;
10179 while (i<mFakeWindows.size()) {
10180 if (mFakeWindows.get(i).mWindowLayer <= fw.mWindowLayer) {
10181 break;
Joe Onorato664644d2011-01-23 17:53:23 -080010182 }
10183 }
Dianne Hackborndf89e652011-10-06 22:35:11 -070010184 mFakeWindows.add(i, fw);
10185 mInputMonitor.updateInputWindowsLw(true);
10186 return fw;
10187 }
10188 }
10189
10190 boolean removeFakeWindowLocked(FakeWindow window) {
10191 synchronized (mWindowMap) {
10192 if (mFakeWindows.remove(window)) {
10193 mInputMonitor.updateInputWindowsLw(true);
10194 return true;
10195 }
10196 return false;
Joe Onorato664644d2011-01-23 17:53:23 -080010197 }
10198 }
10199
satoke0a99412012-05-10 02:22:58 +090010200 // It is assumed that this method is called only by InputMethodManagerService.
10201 public void saveLastInputMethodWindowForTransition() {
10202 synchronized (mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -070010203 // TODO(multidisplay): Pass in the displayID.
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010204 DisplayContent displayContent = getDefaultDisplayContentLocked();
satoke0a99412012-05-10 02:22:58 +090010205 if (mInputMethodWindow != null) {
10206 mPolicy.setLastInputMethodWindowLw(mInputMethodWindow, mInputMethodTarget);
10207 }
10208 }
10209 }
10210
Daniel Sandler0c4ccff2011-10-19 16:39:14 -040010211 @Override
10212 public boolean hasNavigationBar() {
10213 return mPolicy.hasNavigationBar();
10214 }
10215
Craig Mautner96868332012-12-04 14:29:11 -080010216 @Override
Adam Cohenf7522022012-10-03 20:03:18 -070010217 public void lockNow(Bundle options) {
10218 mPolicy.lockNow(options);
Jim Miller93c518e2012-01-17 15:55:31 -080010219 }
Craig Mautner6cfa7292013-01-15 09:05:42 -080010220
Craig Mautner96868332012-12-04 14:29:11 -080010221 @Override
Jim Millerbfec0a82012-11-05 20:05:22 -080010222 public boolean isSafeModeEnabled() {
10223 return mSafeMode;
10224 }
Jim Miller93c518e2012-01-17 15:55:31 -080010225
Jeff Brownd7a04de2012-06-17 14:17:52 -070010226 void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010227 pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010228 mPolicy.dump(" ", pw, args);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010229 }
10230
Dianne Hackborn529e7442012-11-01 14:22:28 -070010231 void dumpAnimatorLocked(PrintWriter pw, String[] args, boolean dumpAll) {
10232 pw.println("WINDOW MANAGER ANIMATOR STATE (dumpsys window animator)");
10233 mAnimator.dumpLocked(pw, " ", dumpAll);
10234 }
10235
Jeff Brownd7a04de2012-06-17 14:17:52 -070010236 void dumpTokensLocked(PrintWriter pw, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010237 pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
10238 if (mTokenMap.size() > 0) {
10239 pw.println(" All tokens:");
10240 Iterator<WindowToken> it = mTokenMap.values().iterator();
10241 while (it.hasNext()) {
10242 WindowToken token = it.next();
Dianne Hackbornef03a7f2012-10-29 18:46:52 -070010243 pw.print(" "); pw.print(token);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010244 if (dumpAll) {
10245 pw.println(':');
10246 token.dump(pw, " ");
10247 } else {
10248 pw.println();
10249 }
10250 }
10251 }
10252 if (mWallpaperTokens.size() > 0) {
10253 pw.println();
10254 pw.println(" Wallpaper tokens:");
10255 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
10256 WindowToken token = mWallpaperTokens.get(i);
10257 pw.print(" Wallpaper #"); pw.print(i);
10258 pw.print(' '); pw.print(token);
10259 if (dumpAll) {
10260 pw.println(':');
10261 token.dump(pw, " ");
10262 } else {
10263 pw.println();
10264 }
10265 }
10266 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010267 if (mFinishedStarting.size() > 0) {
10268 pw.println();
10269 pw.println(" Finishing start of application tokens:");
10270 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
10271 WindowToken token = mFinishedStarting.get(i);
10272 pw.print(" Finished Starting #"); pw.print(i);
10273 pw.print(' '); pw.print(token);
10274 if (dumpAll) {
10275 pw.println(':');
10276 token.dump(pw, " ");
10277 } else {
10278 pw.println();
10279 }
10280 }
10281 }
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010282 if (mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
10283 pw.println();
10284 if (mOpeningApps.size() > 0) {
10285 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
10286 }
10287 if (mClosingApps.size() > 0) {
10288 pw.print(" mClosingApps="); pw.println(mClosingApps);
10289 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010290 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010291 }
10292
Jeff Brownd7a04de2012-06-17 14:17:52 -070010293 void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010294 pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
10295 if (mSessions.size() > 0) {
10296 Iterator<Session> it = mSessions.iterator();
10297 while (it.hasNext()) {
10298 Session s = it.next();
10299 pw.print(" Session "); pw.print(s); pw.println(':');
10300 s.dump(pw, " ");
10301 }
10302 }
10303 }
10304
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010305 void dumpDisplayContentsLocked(PrintWriter pw, boolean dumpAll) {
10306 pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)");
10307 if (mDisplayReady) {
Craig Mautnerf8924152013-07-16 09:10:55 -070010308 final int numDisplays = mDisplayContents.size();
10309 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10310 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
10311 displayContent.dump(" ", pw);
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010312 }
10313 } else {
10314 pw.println(" NO DISPLAY");
10315 }
10316 }
10317
Jeff Brownd7a04de2012-06-17 14:17:52 -070010318 void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010319 ArrayList<WindowState> windows) {
10320 pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010321 dumpWindowsNoHeaderLocked(pw, dumpAll, windows);
10322 }
10323
10324 void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll,
10325 ArrayList<WindowState> windows) {
Craig Mautnerf8924152013-07-16 09:10:55 -070010326 final int numDisplays = mDisplayContents.size();
10327 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10328 final WindowList windowList = mDisplayContents.valueAt(displayNdx).getWindowList();
10329 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
10330 final WindowState w = windowList.get(winNdx);
10331 if (windows == null || windows.contains(w)) {
Craig Mautnerb1885b852013-09-16 22:50:50 -070010332 pw.print(" Window #"); pw.print(winNdx); pw.print(' ');
Craig Mautnerf8924152013-07-16 09:10:55 -070010333 pw.print(w); pw.println(":");
10334 w.dump(pw, " ", dumpAll || windows != null);
10335 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010336 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010337 }
10338 if (mInputMethodDialogs.size() > 0) {
10339 pw.println();
10340 pw.println(" Input method dialogs:");
10341 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
10342 WindowState w = mInputMethodDialogs.get(i);
10343 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010344 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010345 }
10346 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010347 }
10348 if (mPendingRemove.size() > 0) {
10349 pw.println();
10350 pw.println(" Remove pending for:");
10351 for (int i=mPendingRemove.size()-1; i>=0; i--) {
10352 WindowState w = mPendingRemove.get(i);
10353 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010354 pw.print(" Remove #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010355 pw.print(w);
10356 if (dumpAll) {
10357 pw.println(":");
10358 w.dump(pw, " ", true);
10359 } else {
10360 pw.println();
10361 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010362 }
10363 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010364 }
10365 if (mForceRemoves != null && mForceRemoves.size() > 0) {
10366 pw.println();
10367 pw.println(" Windows force removing:");
10368 for (int i=mForceRemoves.size()-1; i>=0; i--) {
10369 WindowState w = mForceRemoves.get(i);
10370 pw.print(" Removing #"); pw.print(i); pw.print(' ');
10371 pw.print(w);
10372 if (dumpAll) {
10373 pw.println(":");
10374 w.dump(pw, " ", true);
10375 } else {
10376 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010377 }
10378 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010379 }
10380 if (mDestroySurface.size() > 0) {
10381 pw.println();
10382 pw.println(" Windows waiting to destroy their surface:");
10383 for (int i=mDestroySurface.size()-1; i>=0; i--) {
10384 WindowState w = mDestroySurface.get(i);
10385 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010386 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010387 pw.print(w);
10388 if (dumpAll) {
10389 pw.println(":");
10390 w.dump(pw, " ", true);
10391 } else {
10392 pw.println();
10393 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010394 }
10395 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010396 }
10397 if (mLosingFocus.size() > 0) {
10398 pw.println();
10399 pw.println(" Windows losing focus:");
10400 for (int i=mLosingFocus.size()-1; i>=0; i--) {
10401 WindowState w = mLosingFocus.get(i);
10402 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010403 pw.print(" Losing #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010404 pw.print(w);
10405 if (dumpAll) {
10406 pw.println(":");
10407 w.dump(pw, " ", true);
10408 } else {
10409 pw.println();
10410 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010411 }
10412 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010413 }
10414 if (mResizingWindows.size() > 0) {
10415 pw.println();
10416 pw.println(" Windows waiting to resize:");
10417 for (int i=mResizingWindows.size()-1; i>=0; i--) {
10418 WindowState w = mResizingWindows.get(i);
10419 if (windows == null || windows.contains(w)) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010420 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010421 pw.print(w);
10422 if (dumpAll) {
10423 pw.println(":");
10424 w.dump(pw, " ", true);
10425 } else {
10426 pw.println();
10427 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010428 }
10429 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010430 }
Dianne Hackborn38e29a62011-09-18 14:43:08 -070010431 if (mWaitingForDrawn.size() > 0) {
10432 pw.println();
10433 pw.println(" Clients waiting for these windows to be drawn:");
10434 for (int i=mWaitingForDrawn.size()-1; i>=0; i--) {
10435 Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(i);
10436 pw.print(" Waiting #"); pw.print(i); pw.print(' '); pw.print(pair.first);
10437 pw.print(": "); pw.println(pair.second);
10438 }
10439 }
Dianne Hackborn77119bc2012-10-23 14:32:48 -070010440 pw.println();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010441 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
10442 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
10443 if (mLastFocus != mCurrentFocus) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010444 pw.print(" mLastFocus="); pw.println(mLastFocus);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010445 }
10446 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
10447 if (mInputMethodTarget != null) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010448 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010449 }
10450 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
10451 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborna57c6952013-03-29 14:46:40 -070010452 pw.print(" mLastDisplayFreezeDuration=");
10453 TimeUtils.formatDuration(mLastDisplayFreezeDuration, pw);
10454 if ( mLastFinishedFreezeSource != null) {
10455 pw.print(" due to ");
10456 pw.print(mLastFinishedFreezeSource);
10457 }
10458 pw.println();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010459 if (dumpAll) {
Craig Mautner28816302013-10-10 20:31:00 -070010460 pw.print(" mSystemDecorLayer="); pw.print(mSystemDecorLayer);
Dianne Hackbornc652de82013-02-15 16:32:56 -080010461 pw.print(" mScreenRect="); pw.println(mScreenRect.toShortString());
Dianne Hackborndf89e652011-10-06 22:35:11 -070010462 if (mLastStatusBarVisibility != 0) {
10463 pw.print(" mLastStatusBarVisibility=0x");
10464 pw.println(Integer.toHexString(mLastStatusBarVisibility));
10465 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010466 if (mInputMethodWindow != null) {
10467 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
10468 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -070010469 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn529e7442012-11-01 14:22:28 -070010470 if (mLowerWallpaperTarget != null || mUpperWallpaperTarget != null) {
Dianne Hackborn284ac932009-08-28 10:34:25 -070010471 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
10472 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
10473 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010474 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
10475 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
10476 if (mInputMethodAnimLayerAdjustment != 0 ||
10477 mWallpaperAnimLayerAdjustment != 0) {
10478 pw.print(" mInputMethodAnimLayerAdjustment=");
10479 pw.print(mInputMethodAnimLayerAdjustment);
10480 pw.print(" mWallpaperAnimLayerAdjustment=");
10481 pw.println(mWallpaperAnimLayerAdjustment);
10482 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010483 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
10484 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
Craig Mautner19d59bc2012-09-04 11:15:56 -070010485 if (needsLayout()) {
10486 pw.print(" layoutNeeded on displays=");
Craig Mautnerf8924152013-07-16 09:10:55 -070010487 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10488 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautner19d59bc2012-09-04 11:15:56 -070010489 if (displayContent.layoutNeeded) {
10490 pw.print(displayContent.getDisplayId());
10491 }
10492 }
10493 pw.println();
10494 }
Craig Mautner69b08182012-09-05 13:07:13 -070010495 pw.print(" mTransactionSequence="); pw.println(mTransactionSequence);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010496 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -070010497 pw.print(" windows="); pw.print(mWindowsFreezingScreen);
10498 pw.print(" client="); pw.print(mClientFreezingScreen);
10499 pw.print(" apps="); pw.print(mAppsFreezingScreen);
10500 pw.print(" waitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010501 pw.print(" mRotation="); pw.print(mRotation);
Dianne Hackborndacea8c2011-04-21 17:26:39 -070010502 pw.print(" mAltOrientation="); pw.println(mAltOrientation);
Craig Mautnerf20588f2012-04-11 17:06:21 -070010503 pw.print(" mLastWindowForcedOrientation="); pw.print(mLastWindowForcedOrientation);
Dianne Hackbornbc7386c2011-06-06 17:27:54 -070010504 pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation);
Jeff Brown01a98dd2011-09-20 15:08:29 -070010505 pw.print(" mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
Dianne Hackborn4dcece82012-02-10 14:50:32 -080010506 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
10507 pw.print(" mTransitionWindowAnimationScale="); pw.print(mTransitionAnimationScale);
Chet Haasec38fa1f2012-02-01 16:37:46 -080010508 pw.print(" mAnimatorDurationScale="); pw.println(mAnimatorDurationScale);
Craig Mautner164d4bb2012-11-26 13:51:23 -080010509 pw.print(" mTraversalScheduled="); pw.println(mTraversalScheduled);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010510 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010511 pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Dianne Hackborn529e7442012-11-01 14:22:28 -070010512 pw.println(" mLayoutToAnim:");
Craig Mautner164d4bb2012-11-26 13:51:23 -080010513 mAppTransition.dump(pw);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010514 }
10515 }
10516
Jeff Brownd7a04de2012-06-17 14:17:52 -070010517 boolean dumpWindows(PrintWriter pw, String name, String[] args,
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010518 int opti, boolean dumpAll) {
Craig Mautner722285e2012-09-07 13:55:58 -070010519 WindowList windows = new WindowList();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010520 if ("visible".equals(name)) {
10521 synchronized(mWindowMap) {
Craig Mautnerf8924152013-07-16 09:10:55 -070010522 final int numDisplays = mDisplayContents.size();
10523 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10524 final WindowList windowList =
10525 mDisplayContents.valueAt(displayNdx).getWindowList();
10526 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
10527 final WindowState w = windowList.get(winNdx);
10528 if (w.mWinAnimator.mSurfaceShown) {
10529 windows.add(w);
10530 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010531 }
10532 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010533 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010534 } else {
10535 int objectId = 0;
10536 // See if this is an object ID.
10537 try {
10538 objectId = Integer.parseInt(name, 16);
10539 name = null;
10540 } catch (RuntimeException e) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010541 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010542 synchronized(mWindowMap) {
Craig Mautnerf8924152013-07-16 09:10:55 -070010543 final int numDisplays = mDisplayContents.size();
10544 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10545 final WindowList windowList =
10546 mDisplayContents.valueAt(displayNdx).getWindowList();
10547 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
10548 final WindowState w = windowList.get(winNdx);
10549 if (name != null) {
10550 if (w.mAttrs.getTitle().toString().contains(name)) {
10551 windows.add(w);
10552 }
10553 } else if (System.identityHashCode(w) == objectId) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010554 windows.add(w);
10555 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010556 }
10557 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010558 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010559 }
10560
10561 if (windows.size() <= 0) {
10562 return false;
10563 }
10564
10565 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010566 dumpWindowsLocked(pw, dumpAll, windows);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010567 }
10568 return true;
10569 }
10570
Jeff Brownd7a04de2012-06-17 14:17:52 -070010571 void dumpLastANRLocked(PrintWriter pw) {
10572 pw.println("WINDOW MANAGER LAST ANR (dumpsys window lastanr)");
10573 if (mLastANRState == null) {
10574 pw.println(" <no ANR has occurred since boot>");
10575 } else {
10576 pw.println(mLastANRState);
10577 }
10578 }
10579
10580 /**
10581 * Saves information about the state of the window manager at
10582 * the time an ANR occurred before anything else in the system changes
10583 * in response.
10584 *
Jeff Brownee172412012-06-18 12:58:03 -070010585 * @param appWindowToken The application that ANR'd, may be null.
Jeff Brownd7a04de2012-06-17 14:17:52 -070010586 * @param windowState The window that ANR'd, may be null.
Jeff Brownbd181bb2013-09-10 16:44:24 -070010587 * @param reason The reason for the ANR, may be null.
Jeff Brownd7a04de2012-06-17 14:17:52 -070010588 */
Jeff Brownbd181bb2013-09-10 16:44:24 -070010589 public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState,
10590 String reason) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010591 StringWriter sw = new StringWriter();
Dianne Hackborn8c841092013-06-24 13:46:13 -070010592 PrintWriter pw = new FastPrintWriter(sw, false, 1024);
Jeff Brownd7a04de2012-06-17 14:17:52 -070010593 pw.println(" ANR time: " + DateFormat.getInstance().format(new Date()));
Jeff Brownee172412012-06-18 12:58:03 -070010594 if (appWindowToken != null) {
10595 pw.println(" Application at fault: " + appWindowToken.stringName);
10596 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010597 if (windowState != null) {
10598 pw.println(" Window at fault: " + windowState.mAttrs.getTitle());
10599 }
Jeff Brownbd181bb2013-09-10 16:44:24 -070010600 if (reason != null) {
10601 pw.println(" Reason: " + reason);
10602 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010603 pw.println();
10604 dumpWindowsNoHeaderLocked(pw, true, null);
10605 pw.close();
10606 mLastANRState = sw.toString();
10607 }
10608
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010609 @Override
10610 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10611 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
10612 != PackageManager.PERMISSION_GRANTED) {
10613 pw.println("Permission Denial: can't dump WindowManager from from pid="
10614 + Binder.getCallingPid()
10615 + ", uid=" + Binder.getCallingUid());
10616 return;
10617 }
10618
10619 boolean dumpAll = false;
10620
10621 int opti = 0;
10622 while (opti < args.length) {
10623 String opt = args[opti];
10624 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10625 break;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010626 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010627 opti++;
10628 if ("-a".equals(opt)) {
10629 dumpAll = true;
10630 } else if ("-h".equals(opt)) {
10631 pw.println("Window manager dump options:");
10632 pw.println(" [-a] [-h] [cmd] ...");
10633 pw.println(" cmd may be one of:");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010634 pw.println(" l[astanr]: last ANR information");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010635 pw.println(" p[policy]: policy state");
Dianne Hackborn529e7442012-11-01 14:22:28 -070010636 pw.println(" a[animator]: animator state");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010637 pw.println(" s[essions]: active sessions");
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010638 pw.println(" d[isplays]: active display contents");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010639 pw.println(" t[okens]: token list");
10640 pw.println(" w[indows]: window list");
10641 pw.println(" cmd may also be a NAME to dump windows. NAME may");
10642 pw.println(" be a partial substring in a window name, a");
10643 pw.println(" Window hex object identifier, or");
10644 pw.println(" \"all\" for all windows, or");
10645 pw.println(" \"visible\" for the visible windows.");
10646 pw.println(" -a: include all available server state.");
10647 return;
Dianne Hackborn87fc3082010-12-03 13:09:12 -080010648 } else {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010649 pw.println("Unknown argument: " + opt + "; use -h for help");
Dianne Hackborn87fc3082010-12-03 13:09:12 -080010650 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010651 }
10652
10653 // Is the caller requesting to dump a particular piece of data?
10654 if (opti < args.length) {
10655 String cmd = args[opti];
10656 opti++;
Jeff Brownd7a04de2012-06-17 14:17:52 -070010657 if ("lastanr".equals(cmd) || "l".equals(cmd)) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010658 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010659 dumpLastANRLocked(pw);
10660 }
10661 return;
10662 } else if ("policy".equals(cmd) || "p".equals(cmd)) {
10663 synchronized(mWindowMap) {
10664 dumpPolicyLocked(pw, args, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010665 }
10666 return;
Dianne Hackborn529e7442012-11-01 14:22:28 -070010667 } else if ("animator".equals(cmd) || "a".equals(cmd)) {
10668 synchronized(mWindowMap) {
10669 dumpAnimatorLocked(pw, args, true);
10670 }
10671 return;
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010672 } else if ("sessions".equals(cmd) || "s".equals(cmd)) {
10673 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010674 dumpSessionsLocked(pw, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010675 }
10676 return;
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010677 } else if ("displays".equals(cmd) || "d".equals(cmd)) {
10678 synchronized(mWindowMap) {
10679 dumpDisplayContentsLocked(pw, true);
10680 }
10681 return;
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010682 } else if ("tokens".equals(cmd) || "t".equals(cmd)) {
10683 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010684 dumpTokensLocked(pw, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010685 }
10686 return;
10687 } else if ("windows".equals(cmd) || "w".equals(cmd)) {
10688 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010689 dumpWindowsLocked(pw, true, null);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010690 }
10691 return;
10692 } else if ("all".equals(cmd) || "a".equals(cmd)) {
10693 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010694 dumpWindowsLocked(pw, true, null);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010695 }
10696 return;
10697 } else {
10698 // Dumping a single name?
Jeff Brownd7a04de2012-06-17 14:17:52 -070010699 if (!dumpWindows(pw, cmd, args, opti, dumpAll)) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010700 pw.println("Bad window command, or no windows match: " + cmd);
10701 pw.println("Use -h for help.");
10702 }
10703 return;
10704 }
10705 }
10706
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010707 synchronized(mWindowMap) {
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010708 pw.println();
10709 if (dumpAll) {
10710 pw.println("-------------------------------------------------------------------------------");
10711 }
10712 dumpLastANRLocked(pw);
10713 pw.println();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010714 if (dumpAll) {
10715 pw.println("-------------------------------------------------------------------------------");
10716 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010717 dumpPolicyLocked(pw, args, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010718 pw.println();
10719 if (dumpAll) {
10720 pw.println("-------------------------------------------------------------------------------");
10721 }
Dianne Hackborn529e7442012-11-01 14:22:28 -070010722 dumpAnimatorLocked(pw, args, dumpAll);
10723 pw.println();
10724 if (dumpAll) {
10725 pw.println("-------------------------------------------------------------------------------");
10726 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010727 dumpSessionsLocked(pw, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010728 pw.println();
10729 if (dumpAll) {
10730 pw.println("-------------------------------------------------------------------------------");
10731 }
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010732 dumpDisplayContentsLocked(pw, dumpAll);
10733 pw.println();
10734 if (dumpAll) {
10735 pw.println("-------------------------------------------------------------------------------");
10736 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010737 dumpTokensLocked(pw, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010738 pw.println();
10739 if (dumpAll) {
10740 pw.println("-------------------------------------------------------------------------------");
10741 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010742 dumpWindowsLocked(pw, dumpAll, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010743 }
10744 }
10745
Jeff Brown349703e2010-06-22 01:27:15 -070010746 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
Craig Mautner96868332012-12-04 14:29:11 -080010747 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010748 public void monitor() {
10749 synchronized (mWindowMap) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070010750 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010751
Jeff Brown2992ea72011-01-28 22:04:14 -080010752 public interface OnHardKeyboardStatusChangeListener {
10753 public void onHardKeyboardStatusChange(boolean available, boolean enabled);
10754 }
Craig Mautnera2c77052012-03-26 12:14:43 -070010755
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070010756 void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
Craig Mautnercf8cbbe2012-03-25 21:54:36 -070010757 if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070010758 Slog.v(TAG, "Layouts looping: " + msg + ", mPendingLayoutChanges = 0x" +
10759 Integer.toHexString(pendingLayoutChanges));
Craig Mautnercf8cbbe2012-03-25 21:54:36 -070010760 }
10761 }
Craig Mautner59c00972012-07-30 12:10:24 -070010762
Dianne Hackbornc652de82013-02-15 16:32:56 -080010763 private DisplayContent newDisplayContentLocked(final Display display) {
Craig Mautner9d808b12013-08-06 18:00:25 -070010764 DisplayContent displayContent = new DisplayContent(display, this);
Craig Mautnercf910b02013-04-23 11:23:27 -070010765 final int displayId = display.getDisplayId();
10766 mDisplayContents.put(displayId, displayContent);
Jeff Brownef981a42013-08-07 14:13:37 -070010767
10768 DisplayInfo displayInfo = displayContent.getDisplayInfo();
Dianne Hackbornc652de82013-02-15 16:32:56 -080010769 final Rect rect = new Rect();
Jeff Brownef981a42013-08-07 14:13:37 -070010770 mDisplaySettings.getOverscanLocked(displayInfo.name, rect);
10771 synchronized (displayContent.mDisplaySizeLock) {
10772 displayInfo.overscanLeft = rect.left;
10773 displayInfo.overscanTop = rect.top;
10774 displayInfo.overscanRight = rect.right;
10775 displayInfo.overscanBottom = rect.bottom;
Jeff Brown4ccb8232014-01-16 22:16:42 -080010776 mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
Jeff Brownef981a42013-08-07 14:13:37 -070010777 displayId, displayInfo);
10778 }
10779 configureDisplayPolicyLocked(displayContent);
Craig Mautnercf910b02013-04-23 11:23:27 -070010780
10781 // TODO: Create an input channel for each display with touch capability.
10782 if (displayId == Display.DEFAULT_DISPLAY) {
Craig Mautner037aa8d2013-06-07 10:35:44 -070010783 displayContent.mTapDetector = new StackTapPointerEventListener(this, displayContent);
10784 registerPointerEventListener(displayContent.mTapDetector);
Craig Mautnercf910b02013-04-23 11:23:27 -070010785 }
10786
Dianne Hackbornc652de82013-02-15 16:32:56 -080010787 return displayContent;
10788 }
10789
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010790 public void createDisplayContentLocked(final Display display) {
Craig Mautner722285e2012-09-07 13:55:58 -070010791 if (display == null) {
10792 throw new IllegalArgumentException("getDisplayContent: display must not be null");
10793 }
keunyoung1eb06372013-08-09 14:32:36 -070010794 getDisplayContentLocked(display.getDisplayId());
Craig Mautner722285e2012-09-07 13:55:58 -070010795 }
10796
Craig Mautner2d5618c2012-10-18 13:55:47 -070010797 /**
10798 * Retrieve the DisplayContent for the specified displayId. Will create a new DisplayContent if
10799 * there is a Display for the displayId.
10800 * @param displayId The display the caller is interested in.
10801 * @return The DisplayContent associated with displayId or null if there is no Display for it.
10802 */
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010803 public DisplayContent getDisplayContentLocked(final int displayId) {
Craig Mautner59c00972012-07-30 12:10:24 -070010804 DisplayContent displayContent = mDisplayContents.get(displayId);
10805 if (displayContent == null) {
Craig Mautner2d5618c2012-10-18 13:55:47 -070010806 final Display display = mDisplayManager.getDisplay(displayId);
10807 if (display != null) {
Dianne Hackbornc652de82013-02-15 16:32:56 -080010808 displayContent = newDisplayContentLocked(display);
Craig Mautner2d5618c2012-10-18 13:55:47 -070010809 }
Craig Mautner59c00972012-07-30 12:10:24 -070010810 }
10811 return displayContent;
10812 }
10813
Craig Mautner2d5618c2012-10-18 13:55:47 -070010814 // There is an inherent assumption that this will never return null.
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010815 public DisplayContent getDefaultDisplayContentLocked() {
10816 return getDisplayContentLocked(Display.DEFAULT_DISPLAY);
Craig Mautner59c00972012-07-30 12:10:24 -070010817 }
10818
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010819 public WindowList getDefaultWindowListLocked() {
10820 return getDefaultDisplayContentLocked().getWindowList();
Craig Mautner59c00972012-07-30 12:10:24 -070010821 }
10822
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010823 public DisplayInfo getDefaultDisplayInfoLocked() {
10824 return getDefaultDisplayContentLocked().getDisplayInfo();
Craig Mautner59c00972012-07-30 12:10:24 -070010825 }
10826
Craig Mautner2d5618c2012-10-18 13:55:47 -070010827 /**
10828 * Return the list of WindowStates associated on the passed display.
10829 * @param display The screen to return windows from.
10830 * @return The list of WindowStates on the screen, or null if the there is no screen.
10831 */
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010832 public WindowList getWindowListLocked(final Display display) {
Craig Mautner96868332012-12-04 14:29:11 -080010833 return getWindowListLocked(display.getDisplayId());
10834 }
10835
10836 /**
10837 * Return the list of WindowStates associated on the passed display.
10838 * @param displayId The screen to return windows from.
10839 * @return The list of WindowStates on the screen, or null if the there is no screen.
10840 */
10841 public WindowList getWindowListLocked(final int displayId) {
10842 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -070010843 return displayContent != null ? displayContent.getWindowList() : null;
Craig Mautner39834192012-09-02 07:47:24 -070010844 }
Craig Mautner722285e2012-09-07 13:55:58 -070010845
Craig Mautner722285e2012-09-07 13:55:58 -070010846 public void onDisplayAdded(int displayId) {
10847 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_ADDED, displayId, 0));
10848 }
10849
Craig Mautnerad25fa32014-01-12 21:19:06 -080010850 public void handleDisplayAdded(int displayId) {
10851 synchronized (mWindowMap) {
10852 final Display display = mDisplayManager.getDisplay(displayId);
10853 if (display != null) {
10854 createDisplayContentLocked(display);
10855 displayReady(displayId);
10856 }
Craig Mautner2d5618c2012-10-18 13:55:47 -070010857 }
Craig Mautner722285e2012-09-07 13:55:58 -070010858 }
10859
Craig Mautner722285e2012-09-07 13:55:58 -070010860 public void onDisplayRemoved(int displayId) {
10861 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_REMOVED, displayId, 0));
10862 }
10863
10864 private void handleDisplayRemovedLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010865 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -070010866 if (displayContent != null) {
Craig Mautner1bf2b872014-02-05 15:37:40 -080010867 if ((displayContent.mDeferredActions & DisplayContent.DEFER_DETACH) != 0) {
10868 displayContent.mDeferredActions |= DisplayContent.DEFER_REMOVAL;
10869 return;
10870 }
Craig Mautner2d5618c2012-10-18 13:55:47 -070010871 mDisplayContents.delete(displayId);
Craig Mautner2eb15342013-08-07 13:13:35 -070010872 displayContent.close();
Craig Mautner037aa8d2013-06-07 10:35:44 -070010873 if (displayId == Display.DEFAULT_DISPLAY) {
10874 unregisterPointerEventListener(displayContent.mTapDetector);
Andreas Huberb551c6d2013-04-26 11:54:53 -070010875 }
Craig Mautner722285e2012-09-07 13:55:58 -070010876 }
Craig Mautnera91f9e22012-09-14 16:22:08 -070010877 mAnimator.removeDisplayLocked(displayId);
Craig Mautner722285e2012-09-07 13:55:58 -070010878 }
10879
Craig Mautner722285e2012-09-07 13:55:58 -070010880 public void onDisplayChanged(int displayId) {
10881 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_CHANGED, displayId, 0));
10882 }
10883
10884 private void handleDisplayChangedLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010885 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner722285e2012-09-07 13:55:58 -070010886 if (displayContent != null) {
10887 displayContent.updateDisplayInfo();
10888 }
10889 }
John Spurlock04db1762013-05-13 12:46:41 -040010890
10891 @Override
10892 public Object getWindowManagerLock() {
10893 return mWindowMap;
10894 }
Jeff Brown4ccb8232014-01-16 22:16:42 -080010895
10896 private final class LocalService extends WindowManagerInternal {
10897 @Override
10898 public void requestTraversalFromDisplayManager() {
10899 requestTraversal();
10900 }
10901 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010902}