blob: dcf58802150201122f1efbd520dbddd034e05f46 [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;
Dianne Hackbornc2293022013-02-06 23:14:49 -080022import android.app.AppOpsManager;
Craig Mautner9ef471f2014-02-07 13:11:47 -080023import android.util.ArraySet;
Dianne Hackborna57c6952013-03-29 14:46:40 -070024import android.util.TimeUtils;
Dianne Hackborne3f23a32013-03-01 13:25:35 -080025import android.view.IWindowId;
Craig Mautner5eda9b32013-07-02 11:58:16 -070026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import com.android.internal.app.IBatteryStats;
28import com.android.internal.policy.PolicyManager;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080029import com.android.internal.policy.impl.PhoneWindowManager;
Dianne Hackborn8c841092013-06-24 13:46:13 -070030import com.android.internal.util.FastPrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import com.android.internal.view.IInputContext;
32import com.android.internal.view.IInputMethodClient;
33import com.android.internal.view.IInputMethodManager;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080034import com.android.internal.view.WindowManagerPolicyThread;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080035import com.android.server.AttributeCache;
Jeff Brown4ccb8232014-01-16 22:16:42 -080036import com.android.server.DisplayThread;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080037import com.android.server.EventLogTags;
Jeff Brown6f357d32014-01-15 20:40:55 -080038import com.android.server.LocalServices;
Dianne Hackborn8d044e82013-04-30 17:24:15 -070039import com.android.server.UiThread;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080040import com.android.server.Watchdog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import com.android.server.am.BatteryStatsService;
Jeff Brown4532e612012-04-05 14:27:12 -070042import com.android.server.input.InputManagerService;
Jeff Brown4f8ecd82012-06-18 18:29:13 -070043import com.android.server.power.ShutdownThread;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044
45import android.Manifest;
46import android.app.ActivityManagerNative;
47import android.app.IActivityManager;
Joe Onoratoac0ee892011-01-30 15:38:30 -080048import android.app.StatusBarManager;
Jim Millerd6b57052010-06-07 17:52:42 -070049import android.app.admin.DevicePolicyManager;
Jeff Brownff7e6ef2012-08-15 02:05:18 -070050import android.animation.ValueAnimator;
Jim Miller284b62e2010-06-08 14:27:42 -070051import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052import android.content.Context;
Jim Miller284b62e2010-06-08 14:27:42 -070053import android.content.Intent;
54import android.content.IntentFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055import android.content.pm.ActivityInfo;
56import android.content.pm.PackageManager;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070057import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import android.content.res.Configuration;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080059import android.graphics.Bitmap;
John Reck172e87c2013-10-02 16:55:16 -070060import android.graphics.Bitmap.Config;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070061import android.graphics.Canvas;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import android.graphics.Matrix;
63import android.graphics.PixelFormat;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -070064import android.graphics.Point;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import android.graphics.Rect;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070066import android.graphics.RectF;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import android.graphics.Region;
Craig Mautnerb47bbc32012-08-22 17:41:48 -070068import android.hardware.display.DisplayManager;
Jeff Brown4ccb8232014-01-16 22:16:42 -080069import android.hardware.display.DisplayManagerInternal;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070import android.os.Binder;
Dianne Hackborn75804932009-10-20 20:15:20 -070071import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072import android.os.Debug;
73import android.os.Handler;
74import android.os.IBinder;
Dianne Hackborn38e29a62011-09-18 14:43:08 -070075import android.os.IRemoteCallback;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076import android.os.Looper;
77import android.os.Message;
78import android.os.Parcel;
79import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.os.PowerManager;
Jeff Brown6f357d32014-01-15 20:40:55 -080081import android.os.PowerManagerInternal;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082import android.os.Process;
83import android.os.RemoteException;
84import android.os.ServiceManager;
Brad Fitzpatrickec062f62010-11-03 09:56:54 -070085import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086import android.os.SystemClock;
87import android.os.SystemProperties;
Dianne Hackborn1ded0b12012-04-26 14:14:50 -070088import android.os.Trace;
Craig Mautner259328c2012-08-21 19:30:58 -070089import android.os.WorkSource;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.provider.Settings;
Dianne Hackborn723738c2009-06-25 19:48:04 -070091import android.util.DisplayMetrics;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import android.util.EventLog;
Michael Jurka4accb6a2012-03-26 09:18:46 -070093import android.util.FloatMath;
Jim Millerd6b57052010-06-07 17:52:42 -070094import android.util.Log;
Craig Mautner59c00972012-07-30 12:10:24 -070095import android.util.SparseArray;
Dianne Hackborn38e29a62011-09-18 14:43:08 -070096import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -080097import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098import android.util.SparseIntArray;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070099import android.util.TypedValue;
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800100import android.view.Choreographer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101import android.view.Display;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700102import android.view.DisplayInfo;
Adam Powelldfee59a2011-08-05 20:48:30 -0700103import android.view.Gravity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104import android.view.IApplicationToken;
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -0700105import android.view.IInputFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106import android.view.IOnKeyguardExitResult;
107import android.view.IRotationWatcher;
108import android.view.IWindow;
109import android.view.IWindowManager;
110import android.view.IWindowSession;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700111import android.view.InputChannel;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700112import android.view.InputDevice;
Jeff Brownbbda99d2010-07-28 15:48:59 -0700113import android.view.InputEvent;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800114import android.view.InputEventReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115import android.view.KeyEvent;
Svetoslav Ganov545252f2012-12-10 18:29:24 -0800116import android.view.MagnificationSpec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117import android.view.MotionEvent;
Jeff Brown4ccb8232014-01-16 22:16:42 -0800118import android.view.WindowManagerInternal;
Igor Murashkina86ab6402013-08-30 12:58:36 -0700119import android.view.Surface.OutOfResourcesException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120import android.view.Surface;
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800121import android.view.SurfaceControl;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122import android.view.SurfaceSession;
123import android.view.View;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700124import android.view.ViewTreeObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125import android.view.WindowManager;
Jeff Brown98365d72012-08-19 20:30:52 -0700126import android.view.WindowManagerGlobal;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127import android.view.WindowManagerPolicy;
128import android.view.WindowManager.LayoutParams;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700129import android.view.WindowManagerPolicy.FakeWindow;
Craig Mautner037aa8d2013-06-07 10:35:44 -0700130import android.view.WindowManagerPolicy.PointerEventListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131import android.view.animation.Animation;
132import android.view.animation.AnimationUtils;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700133import android.view.animation.Transformation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134
135import java.io.BufferedWriter;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700136import java.io.DataInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137import java.io.File;
138import java.io.FileDescriptor;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700139import java.io.FileInputStream;
140import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141import java.io.IOException;
142import java.io.OutputStream;
143import java.io.OutputStreamWriter;
144import java.io.PrintWriter;
145import java.io.StringWriter;
146import java.net.Socket;
Jeff Brownd7a04de2012-06-17 14:17:52 -0700147import java.text.DateFormat;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148import java.util.ArrayList;
Jeff Brownd7a04de2012-06-17 14:17:52 -0700149import java.util.Date;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150import java.util.HashMap;
151import java.util.HashSet;
152import java.util.Iterator;
153import java.util.List;
154
155/** {@hide} */
Dianne Hackbornddca3ee2009-07-23 19:01:31 -0700156public class WindowManagerService extends IWindowManager.Stub
Craig Mautnerdf88d732014-01-27 09:21:32 -0800157 implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 static final String TAG = "WindowManager";
159 static final boolean DEBUG = false;
Craig Mautnerac565142013-09-23 17:37:09 -0700160 static final boolean DEBUG_ADD_REMOVE = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800161 static final boolean DEBUG_FOCUS = false;
Craig Mautnerb3370ce2013-09-19 12:02:09 -0700162 static final boolean DEBUG_FOCUS_LIGHT = DEBUG_FOCUS || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 static final boolean DEBUG_ANIM = false;
Dianne Hackborn9b52a212009-12-11 14:51:35 -0800164 static final boolean DEBUG_LAYOUT = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800165 static final boolean DEBUG_RESIZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 static final boolean DEBUG_LAYERS = false;
167 static final boolean DEBUG_INPUT = false;
168 static final boolean DEBUG_INPUT_METHOD = false;
169 static final boolean DEBUG_VISIBILITY = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700170 static final boolean DEBUG_WINDOW_MOVEMENT = false;
Craig Mautnerd9a22882013-03-16 15:00:36 -0700171 static final boolean DEBUG_TOKEN_MOVEMENT = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 static final boolean DEBUG_ORIENTATION = false;
Dianne Hackbornbc7386c2011-06-06 17:27:54 -0700173 static final boolean DEBUG_APP_ORIENTATION = false;
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700174 static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175 static final boolean DEBUG_APP_TRANSITIONS = false;
176 static final boolean DEBUG_STARTING_WINDOW = false;
177 static final boolean DEBUG_REORDER = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800178 static final boolean DEBUG_WALLPAPER = false;
Dianne Hackborn98129732012-11-01 16:28:16 -0700179 static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER;
Christopher Tate994ef922011-01-12 20:06:07 -0800180 static final boolean DEBUG_DRAG = false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700181 static final boolean DEBUG_SCREEN_ON = false;
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -0700182 static final boolean DEBUG_SCREENSHOT = false;
Dianne Hackborn38cc8962011-10-13 11:33:55 -0700183 static final boolean DEBUG_BOOT = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700184 static final boolean DEBUG_LAYOUT_REPEATS = true;
Craig Mautner7358fbf2012-04-12 21:06:33 -0700185 static final boolean DEBUG_SURFACE_TRACE = false;
Craig Mautner7d8df392012-04-06 15:26:23 -0700186 static final boolean DEBUG_WINDOW_TRACE = false;
Craig Mautner926f3832013-02-13 11:56:07 -0800187 static final boolean DEBUG_TASK_MOVEMENT = false;
Craig Mautner58004432013-10-14 12:58:42 -0700188 static final boolean DEBUG_STACK = false;
Craig Mautner95da1082014-02-24 17:54:35 -0800189 static final boolean DEBUG_DISPLAY = false;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700190 static final boolean SHOW_SURFACE_ALLOC = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800191 static final boolean SHOW_TRANSACTIONS = false;
Dianne Hackborn36991742011-10-11 21:35:26 -0700192 static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700193 static final boolean HIDE_STACK_CRAWLS = true;
Craig Mautnercf8cbbe2012-03-25 21:54:36 -0700194 static final int LAYOUT_REPEAT_THRESHOLD = 4;
Michael Chan53071d62009-05-13 17:29:48 -0700195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196 static final boolean PROFILE_ORIENTATION = false;
Dave Bortcfe65242009-04-09 14:51:04 -0700197 static final boolean localLOGV = DEBUG;
Romain Guy06882f82009-06-10 13:36:04 -0700198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199 /** How much to multiply the policy's type layer, to reserve room
200 * for multiple windows of the same type and Z-ordering adjustment
201 * with TYPE_LAYER_OFFSET. */
202 static final int TYPE_LAYER_MULTIPLIER = 10000;
Romain Guy06882f82009-06-10 13:36:04 -0700203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
205 * or below others in the same layer. */
206 static final int TYPE_LAYER_OFFSET = 1000;
Romain Guy06882f82009-06-10 13:36:04 -0700207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208 /** How much to increment the layer for each window, to reserve room
209 * for effect surfaces between them.
210 */
211 static final int WINDOW_LAYER_MULTIPLIER = 5;
Romain Guy06882f82009-06-10 13:36:04 -0700212
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800213 /**
214 * Dim surface layer is immediately below target window.
215 */
216 static final int LAYER_OFFSET_DIM = 1;
217
218 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700219 * Blur surface layer is immediately below dim layer.
220 */
221 static final int LAYER_OFFSET_BLUR = 2;
222
223 /**
Craig Mautnerf7666462013-04-28 08:58:21 -0700224 * FocusedStackFrame layer is immediately above focused window.
225 */
226 static final int LAYER_OFFSET_FOCUSED_STACK = 1;
227
228 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700229 * Animation thumbnail is as far as possible below the window above
230 * the thumbnail (or in other words as far as possible above the window
231 * below it).
232 */
233 static final int LAYER_OFFSET_THUMBNAIL = WINDOW_LAYER_MULTIPLIER-1;
234
235 /**
Dianne Hackborn7916ac62011-05-16 20:45:48 -0700236 * Layer at which to put the rotation freeze snapshot.
237 */
238 static final int FREEZE_LAYER = (TYPE_LAYER_MULTIPLIER * 200) + 1;
239
240 /**
241 * Layer at which to put the mask for emulated screen sizes.
242 */
243 static final int MASK_LAYER = TYPE_LAYER_MULTIPLIER * 200;
244
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245 /** The maximum length we will accept for a loaded animation duration:
246 * this is 10 seconds.
247 */
248 static final int MAX_ANIMATION_DURATION = 10*1000;
249
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700250 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
251 * compatible windows.
252 */
253 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
254
Craig Mautner7dfcb012012-10-10 10:24:47 -0700255 /** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */
Craig Mautnera4942c92012-10-16 09:06:53 -0700256 static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000;
Craig Mautner7dfcb012012-10-10 10:24:47 -0700257
Dianne Hackborna1111872010-11-23 20:55:11 -0800258 /**
259 * If true, the window manager will do its own custom freezing and general
260 * management of the screen during rotation.
261 */
262 static final boolean CUSTOM_SCREEN_ROTATION = true;
263
Jeff Brownb09abc12011-01-13 21:08:27 -0800264 // Maximum number of milliseconds to wait for input devices to be enumerated before
265 // proceding with safe mode detection.
266 private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
Jim Miller28637ba2011-07-06 19:57:05 -0700267
Jeff Brown349703e2010-06-22 01:27:15 -0700268 // Default input dispatching timeout in nanoseconds.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800269 static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
Romain Guy06882f82009-06-10 13:36:04 -0700270
Craig Mautnerdf88d732014-01-27 09:21:32 -0800271 /** Minimum value for attachStack and resizeStack weight value */
Craig Mautner967212c2013-04-13 21:10:58 -0700272 public static final float STACK_WEIGHT_MIN = 0.2f;
273
Craig Mautnerdf88d732014-01-27 09:21:32 -0800274 /** Maximum value for attachStack and resizeStack weight value */
Craig Mautner967212c2013-04-13 21:10:58 -0700275 public static final float STACK_WEIGHT_MAX = 0.8f;
276
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 static final int UPDATE_FOCUS_NORMAL = 0;
278 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
279 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
280 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800282 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700283 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284
Colin Crossef96fd92013-07-18 17:09:56 -0700285 private static final String DENSITY_OVERRIDE = "ro.config.density_override";
286 private static final String SIZE_OVERRIDE = "ro.config.size_override";
287
Craig Mautner24d887472013-03-20 15:40:36 -0700288 private static final int MAX_SCREENSHOT_RETRIES = 3;
289
Craig Mautner5642a482012-08-23 12:16:53 -0700290 final private KeyguardDisableHandler mKeyguardDisableHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291
Jim Miller284b62e2010-06-08 14:27:42 -0700292 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
293 @Override
294 public void onReceive(Context context, Intent intent) {
Craig Mautner9dc52bc2012-08-06 14:15:42 -0700295 final String action = intent.getAction();
296 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
Craig Mautner5642a482012-08-23 12:16:53 -0700297 mKeyguardDisableHandler.sendEmptyMessage(
298 KeyguardDisableHandler.KEYGUARD_POLICY_CHANGED);
Jim Miller284b62e2010-06-08 14:27:42 -0700299 }
300 }
301 };
302
Amith Yamasani734983f2014-03-04 16:48:05 -0800303 /**
304 * Current user when multi-user is enabled. Don't show windows of
305 * non-current user. Also see mRelatedUserIds.
306 */
Craig Mautner9dc52bc2012-08-06 14:15:42 -0700307 int mCurrentUserId;
Amith Yamasani734983f2014-03-04 16:48:05 -0800308 /**
309 * Users related to the current user. These are also allowed to show windows
310 * on the current user.
311 */
312 int[] mRelatedUserIds = new int[0];
Craig Mautner9dc52bc2012-08-06 14:15:42 -0700313
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314 final Context mContext;
315
316 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700317
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700318 final boolean mAllowBootMessages;
319
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
323
324 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700327
Dianne Hackbornc2293022013-02-06 23:14:49 -0800328 final AppOpsManager mAppOps;
329
Dianne Hackbornc652de82013-02-15 16:32:56 -0800330 final DisplaySettings mDisplaySettings;
331
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800332 /**
333 * All currently active sessions with clients.
334 */
335 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 /**
338 * Mapping from an IWindow IBinder to the server's Window object.
339 * This is also used as the lock for all of our state.
Craig Mautner58106812012-12-28 12:27:40 -0800340 * NOTE: Never call into methods that lock ActivityManagerService while holding this object.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341 */
342 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
343
344 /**
345 * Mapping from a token IBinder to a WindowToken object.
346 */
Craig Mautner05d62722013-02-11 09:39:27 -0800347 final HashMap<IBinder, WindowToken> mTokenMap = new HashMap<IBinder, WindowToken>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800348
349 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800350 * List of window tokens that have finished starting their application,
351 * and now need to have the policy remove their windows.
352 */
353 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
354
355 /**
Dianne Hackborndf89e652011-10-06 22:35:11 -0700356 * Fake windows added to the window manager. Note: ordered from top to
357 * bottom, opposite of mWindows.
358 */
359 final ArrayList<FakeWindowImpl> mFakeWindows = new ArrayList<FakeWindowImpl>();
360
361 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800362 * Windows that are being resized. Used so we can tell the client about
363 * the resize after closing the transaction in which we resized the
364 * underlying surface.
365 */
366 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
367
368 /**
369 * Windows whose animations have ended and now must be removed.
370 */
371 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
372
373 /**
Craig Mautner9ef471f2014-02-07 13:11:47 -0800374 * Stacks whose animations have ended and whose tasks, apps, selves may now be removed.
375 */
376 final ArraySet<TaskStack> mPendingStacksRemove = new ArraySet<TaskStack>();
377
378 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800379 * Used when processing mPendingRemove to avoid working on the original array.
380 */
381 WindowState[] mPendingRemoveTmp = new WindowState[20];
382
383 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384 * Windows whose surface should be destroyed.
385 */
386 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
387
388 /**
389 * Windows that have lost input focus and are waiting for the new
390 * focus window to be displayed before they are told about this.
391 */
392 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
393
394 /**
395 * This is set when we have run out of memory, and will either be an empty
396 * list or contain windows that need to be force removed.
397 */
398 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700399
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800400 /**
Dianne Hackborn38e29a62011-09-18 14:43:08 -0700401 * Windows that clients are waiting to have drawn.
402 */
403 ArrayList<Pair<WindowState, IRemoteCallback>> mWaitingForDrawn
404 = new ArrayList<Pair<WindowState, IRemoteCallback>>();
405
406 /**
Dianne Hackborn12d3a942012-04-27 14:16:30 -0700407 * Windows that have called relayout() while we were running animations,
408 * so we need to tell when the animation is done.
409 */
410 final ArrayList<WindowState> mRelayoutWhileAnimating = new ArrayList<WindowState>();
411
412 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800413 * Used when rebuilding window list to keep track of windows that have
414 * been removed.
415 */
416 WindowState[] mRebuildTmp = new WindowState[20];
417
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700419
Svetoslav8e3feb12014-02-24 13:46:47 -0800420 AccessibilityController mAccessibilityController;
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -0700421
Craig Mautner7358fbf2012-04-12 21:06:33 -0700422 final SurfaceSession mFxSession;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700423 Watermark mWatermark;
Brad Fitzpatrick68044332010-11-22 18:19:48 -0800424 StrictModeFlash mStrictModeFlash;
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700425 FocusedStackFrame mFocusedStackFrame;
Romain Guy06882f82009-06-10 13:36:04 -0700426
Craig Mautnerf7666462013-04-28 08:58:21 -0700427 int mFocusedStackLayer;
428
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800429 final float[] mTmpFloats = new float[9];
John Spurlock4e92a7c2013-09-24 17:09:05 -0400430 final Rect mTmpContentRect = new Rect();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431
Jeff Browne215f262012-09-10 16:01:14 -0700432 boolean mDisplayReady;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800433 boolean mSafeMode;
434 boolean mDisplayEnabled = false;
435 boolean mSystemBooted = false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700436 boolean mForceDisplayEnabled = false;
Dianne Hackborn661cd522011-08-22 00:26:20 -0700437 boolean mShowingBootMessages = false;
Dianne Hackborn1fbee792011-11-30 11:29:58 -0800438
Jeff Brownd7a04de2012-06-17 14:17:52 -0700439 String mLastANRState;
440
Craig Mautnerb1fd65c2013-02-05 13:34:57 -0800441 /** All DisplayContents in the world, kept here */
Craig Mautnerf8924152013-07-16 09:10:55 -0700442 SparseArray<DisplayContent> mDisplayContents = new SparseArray<DisplayContent>(2);
Craig Mautner343ad712013-02-13 22:37:26 -0800443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800444 int mRotation = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800445 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborndacea8c2011-04-21 17:26:39 -0700446 boolean mAltOrientation = false;
Jim Miller7267ed12013-12-09 17:38:05 -0800447 class RotationWatcher {
448 IRotationWatcher watcher;
449 IBinder.DeathRecipient deathRecipient;
450 RotationWatcher(IRotationWatcher w, IBinder.DeathRecipient d) {
451 watcher = w;
452 deathRecipient = d;
453 }
454 }
455 ArrayList<RotationWatcher> mRotationWatchers = new ArrayList<RotationWatcher>();
Jeff Brown01a98dd2011-09-20 15:08:29 -0700456 int mDeferredRotationPauseCount;
Romain Guy06882f82009-06-10 13:36:04 -0700457
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700458 int mSystemDecorLayer = 0;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700459 final Rect mScreenRect = new Rect();
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700460
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800461 boolean mTraversalScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462 boolean mDisplayFrozen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -0700463 long mDisplayFreezeTime = 0;
464 int mLastDisplayFreezeDuration = 0;
465 Object mLastFinishedFreezeSource = null;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800466 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800467 boolean mWindowsFreezingScreen = false;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700468 boolean mClientFreezingScreen = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800469 int mAppsFreezingScreen = 0;
Dianne Hackbornbc7386c2011-06-06 17:27:54 -0700470 int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800472 int mLayoutSeq = 0;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700473
474 int mLastStatusBarVisibility = 0;
475
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800476 // State while inside of layoutAndPlaceSurfacesLocked().
477 boolean mFocusMayChange;
Craig Mautner01cd0e72012-06-18 10:19:11 -0700478
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800479 Configuration mCurConfiguration = new Configuration();
Craig Mautner01cd0e72012-06-18 10:19:11 -0700480
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800481 // This is held as long as we have the screen frozen, to give us time to
482 // perform a rotation animation when turning off shows the lock screen which
483 // changes the orientation.
Igor Murashkina86ab6402013-08-30 12:58:36 -0700484 private final PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700485
Craig Mautner164d4bb2012-11-26 13:51:23 -0800486 final AppTransition mAppTransition;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800487 boolean mStartingIconInTransition = false;
488 boolean mSkipAppTransitionAnimation = false;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
491 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700492
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700493 boolean mIsTouchDevice;
494
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700495 final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Jeff Brownbc68a592011-07-25 12:58:12 -0700496 final DisplayMetrics mRealDisplayMetrics = new DisplayMetrics();
Dianne Hackborn48a76512011-06-08 21:51:44 -0700497 final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics();
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700498 final DisplayMetrics mCompatDisplayMetrics = new DisplayMetrics();
499
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800500 final H mH = new H();
501
502 final Choreographer mChoreographer = Choreographer.getInstance();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800503
504 WindowState mCurrentFocus = null;
505 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700506
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800507 /** This just indicates the window the input method is on top of, not
508 * necessarily the window its input is going to. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 WindowState mInputMethodTarget = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800510
511 /** If true hold off on modifying the animation layer of mInputMethodTarget */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512 boolean mInputMethodTargetWaitingAnim;
513 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800515 WindowState mInputMethodWindow = null;
516 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
517
Jeff Brown2992ea72011-01-28 22:04:14 -0800518 boolean mHardKeyboardAvailable;
519 boolean mHardKeyboardEnabled;
520 OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
521
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700522 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800523
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700524 // If non-null, this is the currently visible window that is associated
525 // with the wallpaper.
526 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700527 // If non-null, we are in the middle of animating from one wallpaper target
528 // to another, and this is the lower one in Z-order.
Dianne Hackborn98129732012-11-01 16:28:16 -0700529 WindowState mLowerWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700530 // If non-null, we are in the middle of animating from one wallpaper target
531 // to another, and this is the higher one in Z-order.
Craig Mautner96868332012-12-04 14:29:11 -0800532 WindowState mUpperWallpaperTarget = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700533 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700534 float mLastWallpaperX = -1;
535 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800536 float mLastWallpaperXStep = -1;
537 float mLastWallpaperYStep = -1;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700538 // This is set when we are waiting for a wallpaper to tell us it is done
539 // changing its scroll position.
540 WindowState mWaitingOnWallpaper;
541 // The last time we had a timeout when waiting for a wallpaper.
542 long mLastWallpaperTimeoutTime;
543 // We give a wallpaper up to 150ms to finish scrolling.
544 static final long WALLPAPER_TIMEOUT = 150;
545 // Time we wait after a timeout before trying to wait again.
546 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Craig Mautner798adef2013-10-22 14:29:01 -0700547 boolean mAnimateWallpaperWithTarget;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800548
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 AppWindowToken mFocusedApp = null;
550
Jeff Brown6f357d32014-01-15 20:40:55 -0800551 PowerManager mPowerManager;
552 PowerManagerInternal mPowerManagerInternal;
Romain Guy06882f82009-06-10 13:36:04 -0700553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554 float mWindowAnimationScale = 1.0f;
555 float mTransitionAnimationScale = 1.0f;
Chet Haasec38fa1f2012-02-01 16:37:46 -0800556 float mAnimatorDurationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700557
Jeff Brown4532e612012-04-05 14:27:12 -0700558 final InputManagerService mInputManager;
Jeff Brown4ccb8232014-01-16 22:16:42 -0800559 final DisplayManagerInternal mDisplayManagerInternal;
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700560 final DisplayManager mDisplayManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800561
562 // Who is holding the screen on.
563 Session mHoldingScreenOn;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700564 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700565
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700566 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800567
Christopher Tatea53146c2010-09-07 11:57:52 -0700568 DragState mDragState = null;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800569
Craig Mautner3c174372013-02-21 17:54:37 -0800570 // For frozen screen animations.
571 int mExitAnimId, mEnterAnimId;
572
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800573 /** Pulled out of performLayoutAndPlaceSurfacesLockedInner in order to refactor into multiple
574 * methods. */
Craig Mautnera608b882012-03-30 13:03:49 -0700575 class LayoutFields {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700576 static final int SET_UPDATE_ROTATION = 1 << 0;
577 static final int SET_WALLPAPER_MAY_CHANGE = 1 << 1;
578 static final int SET_FORCE_HIDING_CHANGED = 1 << 2;
Craig Mautner2639da52012-07-09 09:39:06 -0700579 static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3;
Craig Mautner7d8df392012-04-06 15:26:23 -0700580 static final int SET_TURN_ON_SCREEN = 1 << 4;
Craig Mautner96868332012-12-04 14:29:11 -0800581 static final int SET_WALLPAPER_ACTION_PENDING = 1 << 5;
Craig Mautnera608b882012-03-30 13:03:49 -0700582
Craig Mautner764983d2012-03-22 11:37:36 -0700583 boolean mWallpaperForceHidingChanged = false;
584 boolean mWallpaperMayChange = false;
Craig Mautner764983d2012-03-22 11:37:36 -0700585 boolean mOrientationChangeComplete = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -0700586 Object mLastWindowFreezeSource = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800587 private Session mHoldScreen = null;
588 private boolean mObscured = false;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800589 private boolean mSyswin = false;
590 private float mScreenBrightness = -1;
591 private float mButtonBrightness = -1;
Jeff Brown1e3b98d2012-09-30 18:58:59 -0700592 private long mUserActivityTimeout = -1;
Craig Mautnera608b882012-03-30 13:03:49 -0700593 private boolean mUpdateRotation = false;
Craig Mautner96868332012-12-04 14:29:11 -0800594 boolean mWallpaperActionPending = false;
Craig Mautner65d11b32012-10-01 13:59:52 -0700595
Jeff Brown4fd79172013-11-07 17:58:15 -0800596 // Set to true when the display contains content to show the user.
597 // When false, the display manager may choose to mirror or blank the display.
598 boolean mDisplayHasContent = false;
599
600 // Only set while traversing the default display based on its content.
601 // Affects the behavior of mirroring on secondary displays.
602 boolean mObscureApplicationContentOnSecondaryDisplays = false;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800603 }
Craig Mautner01cd0e72012-06-18 10:19:11 -0700604 final LayoutFields mInnerFields = new LayoutFields();
605
Craig Mautner96868332012-12-04 14:29:11 -0800606 boolean mAnimationScheduled;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800607
Craig Mautner6fbda632012-07-03 09:26:39 -0700608 /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
609 * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
610 private int mTransactionSequence;
611
Craig Mautnerbb1449b2012-03-23 16:11:14 -0700612 /** Only do a maximum of 6 repeated layouts. After that quit */
613 private int mLayoutRepeatCount;
614
Craig Mautner764983d2012-03-22 11:37:36 -0700615 final WindowAnimator mAnimator;
Jeff Brown4a06c802012-02-15 15:06:01 -0800616
Craig Mautnerc00204b2013-03-05 15:02:14 -0800617 SparseArray<Task> mTaskIdToTask = new SparseArray<Task>();
Craig Mautnerdc548482014-02-05 13:35:24 -0800618
619 /** All of the TaskStacks in the window manager, unordered. For an ordered list call
620 * DisplayContent.getStacks(). */
Craig Mautnerc00204b2013-03-05 15:02:14 -0800621 SparseArray<TaskStack> mStackIdToStack = new SparseArray<TaskStack>();
622
Craig Mautner037aa8d2013-06-07 10:35:44 -0700623 private final PointerEventDispatcher mPointerEventDispatcher;
624
Jeff Brown32cbc38552011-12-01 14:01:49 -0800625 final class DragInputEventReceiver extends InputEventReceiver {
626 public DragInputEventReceiver(InputChannel inputChannel, Looper looper) {
627 super(inputChannel, looper);
628 }
629
Christopher Tatea53146c2010-09-07 11:57:52 -0700630 @Override
Jeff Brown32cbc38552011-12-01 14:01:49 -0800631 public void onInputEvent(InputEvent event) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700632 boolean handled = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700633 try {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800634 if (event instanceof MotionEvent
635 && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
Jeff Brown3915bb82010-11-05 15:02:16 -0700636 && mDragState != null) {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800637 final MotionEvent motionEvent = (MotionEvent)event;
Jeff Brown3915bb82010-11-05 15:02:16 -0700638 boolean endDrag = false;
Jeff Brown4952dfd2011-11-30 19:23:22 -0800639 final float newX = motionEvent.getRawX();
640 final float newY = motionEvent.getRawY();
Jeff Brown3915bb82010-11-05 15:02:16 -0700641
Jeff Brown4952dfd2011-11-30 19:23:22 -0800642 switch (motionEvent.getAction()) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700643 case MotionEvent.ACTION_DOWN: {
644 if (DEBUG_DRAG) {
645 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
646 }
647 } break;
648
649 case MotionEvent.ACTION_MOVE: {
650 synchronized (mWindowMap) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700651 // move the surface and tell the involved window(s) where we are
Christopher Tatea53146c2010-09-07 11:57:52 -0700652 mDragState.notifyMoveLw(newX, newY);
653 }
654 } break;
655
656 case MotionEvent.ACTION_UP: {
657 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
658 + newX + "," + newY);
659 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700660 endDrag = mDragState.notifyDropLw(newX, newY);
Christopher Tatea53146c2010-09-07 11:57:52 -0700661 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700662 } break;
663
664 case MotionEvent.ACTION_CANCEL: {
665 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
666 endDrag = true;
667 } break;
668 }
669
670 if (endDrag) {
671 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
672 // tell all the windows that the drag has ended
Chris Tate59943592010-10-11 20:33:44 -0700673 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700674 mDragState.endDragLw();
Chris Tate59943592010-10-11 20:33:44 -0700675 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700676 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700677
678 handled = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700679 }
680 } catch (Exception e) {
681 Slog.e(TAG, "Exception caught by drag handleMotion", e);
682 } finally {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800683 finishInputEvent(event, handled);
Christopher Tatea53146c2010-09-07 11:57:52 -0700684 }
685 }
Jeff Brown32cbc38552011-12-01 14:01:49 -0800686 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700687
688 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800689 * Whether the UI is currently running in touch mode (not showing
690 * navigational focus because the user is directly pressing the screen).
691 */
Michael Jurkae99adc72011-08-11 18:28:01 -0700692 boolean mInTouchMode = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800693
694 private ViewServer mViewServer;
Igor Murashkina86ab6402013-08-30 12:58:36 -0700695 private final ArrayList<WindowChangeListener> mWindowChangeListeners =
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700696 new ArrayList<WindowChangeListener>();
697 private boolean mWindowsChanged = false;
698
699 public interface WindowChangeListener {
700 public void windowsChanged();
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -0700701 public void focusChanged();
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700702 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800703
Dianne Hackbornc485a602009-03-24 22:39:49 -0700704 final Configuration mTempConfiguration = new Configuration();
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700705
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700706 // The desired scaling factor for compatible apps.
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400707 float mCompatibleScreenScale;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700708
Jeff Brown780c46f2012-06-24 12:15:38 -0700709 // If true, only the core apps and services are being launched because the device
710 // is in a special boot mode, such as being encrypted or waiting for a decryption password.
711 // For example, when this flag is true, there will be no wallpaper service.
712 final boolean mOnlyCore;
713
Jeff Brownbd6e1502012-08-28 03:27:37 -0700714 public static WindowManagerService main(final Context context,
Jeff Brown4ccb8232014-01-16 22:16:42 -0800715 final InputManagerService im,
Jeff Brownbd6e1502012-08-28 03:27:37 -0700716 final boolean haveInputMethods, final boolean showBootMsgs,
717 final boolean onlyCore) {
718 final WindowManagerService[] holder = new WindowManagerService[1];
Jeff Brown4ccb8232014-01-16 22:16:42 -0800719 DisplayThread.getHandler().runWithScissors(new Runnable() {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700720 @Override
721 public void run() {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800722 holder[0] = new WindowManagerService(context, im,
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700723 haveInputMethods, showBootMsgs, onlyCore);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800724 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700725 }, 0);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700726 return holder[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800727 }
Romain Guy06882f82009-06-10 13:36:04 -0700728
Jeff Brown4ccb8232014-01-16 22:16:42 -0800729 private void initPolicy() {
730 UiThread.getHandler().runWithScissors(new Runnable() {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700731 @Override
732 public void run() {
733 WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
Romain Guy06882f82009-06-10 13:36:04 -0700734
Jeff Brownbd6e1502012-08-28 03:27:37 -0700735 mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
736 mAnimator.mAboveUniverseLayer = mPolicy.getAboveUniverseLayer()
737 * TYPE_LAYER_MULTIPLIER
738 + TYPE_LAYER_OFFSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800739 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700740 }, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800741 }
742
Jeff Brown4ccb8232014-01-16 22:16:42 -0800743 private WindowManagerService(Context context, InputManagerService inputManager,
Jeff Brown780c46f2012-06-24 12:15:38 -0700744 boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800745 mContext = context;
746 mHaveInputMethods = haveInputMethods;
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700747 mAllowBootMessages = showBootMsgs;
Jeff Brown780c46f2012-06-24 12:15:38 -0700748 mOnlyCore = onlyCore;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800749 mLimitedAlphaCompositing = context.getResources().getBoolean(
750 com.android.internal.R.bool.config_sf_limitedAlpha);
Craig Mautnercf910b02013-04-23 11:23:27 -0700751 mInputManager = inputManager; // Must be before createDisplayContentLocked.
Jeff Brown4ccb8232014-01-16 22:16:42 -0800752 mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800753 mDisplaySettings = new DisplaySettings(context);
754 mDisplaySettings.readSettingsLocked();
Romain Guy06882f82009-06-10 13:36:04 -0700755
Craig Mautner037aa8d2013-06-07 10:35:44 -0700756 mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG));
757
Craig Mautnerdee8bf02013-08-07 09:24:11 -0700758 mFxSession = new SurfaceSession();
Craig Mautner722285e2012-09-07 13:55:58 -0700759 mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
Craig Mautner722285e2012-09-07 13:55:58 -0700760 Display[] displays = mDisplayManager.getDisplays();
761 for (Display display : displays) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -0700762 createDisplayContentLocked(display);
Craig Mautner722285e2012-09-07 13:55:58 -0700763 }
764
Craig Mautner5642a482012-08-23 12:16:53 -0700765 mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);
766
Jeff Brown6f357d32014-01-15 20:40:55 -0800767 mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
768 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
769 mPowerManagerInternal.setPolicy(mPolicy); // TODO: register as local service instead
770 mScreenFrozenLock = mPowerManager.newWakeLock(
771 PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800772 mScreenFrozenLock.setReferenceCounted(false);
773
Craig Mautner164d4bb2012-11-26 13:51:23 -0800774 mAppTransition = new AppTransition(context, mH);
775
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776 mActivityManager = ActivityManagerNative.getDefault();
777 mBatteryStats = BatteryStatsService.getService();
Dianne Hackbornc2293022013-02-06 23:14:49 -0800778 mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -0800779 mAppOps.startWatchingMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, null,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700780 new AppOpsManager.OnOpChangedInternalListener() {
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -0800781 @Override
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700782 public void onOpChanged(int op, String packageName) {
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -0800783 updateAppOpsState();
784 }
785 }
786 );
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800787
788 // Get persisted window scale setting
Jeff Sharkey6e2bee72012-10-01 13:39:08 -0700789 mWindowAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
790 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
791 mTransitionAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
792 Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
793 setAnimatorDurationScale(Settings.Global.getFloat(context.getContentResolver(),
Craig Mautnera7233fe2012-11-15 14:25:14 -0800794 Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale));
Romain Guy06882f82009-06-10 13:36:04 -0700795
Jim Miller284b62e2010-06-08 14:27:42 -0700796 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
797 IntentFilter filter = new IntentFilter();
798 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
799 mContext.registerReceiver(mBroadcastReceiver, filter);
800
Jeff Brown6f357d32014-01-15 20:40:55 -0800801 mHoldingScreenWakeLock = mPowerManager.newWakeLock(
802 PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700803 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800804
Craig Mautner918b53b2012-07-09 14:15:54 -0700805 mAnimator = new WindowAnimator(this);
Romain Guy06882f82009-06-10 13:36:04 -0700806
Jeff Brown4ccb8232014-01-16 22:16:42 -0800807 initPolicy();
Romain Guy06882f82009-06-10 13:36:04 -0700808
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800809 // Add ourself to the Watchdog monitors.
810 Watchdog.getInstance().addMonitor(this);
Craig Mautner7358fbf2012-04-12 21:06:33 -0700811
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800812 SurfaceControl.openTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700813 try {
814 createWatermarkInTransaction();
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700815 mFocusedStackFrame = new FocusedStackFrame(
816 getDefaultDisplayContentLocked().getDisplay(), mFxSession);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700817 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800818 SurfaceControl.closeTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700819 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800820
821 LocalServices.addService(WindowManagerInternal.class, new LocalService());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800822 }
823
Jeff Browna9d131c2012-09-20 16:48:17 -0700824 public InputMonitor getInputMonitor() {
825 return mInputMonitor;
Jeff Brown4532e612012-04-05 14:27:12 -0700826 }
827
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800828 @Override
829 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
830 throws RemoteException {
831 try {
832 return super.onTransact(code, data, reply, flags);
833 } catch (RuntimeException e) {
834 // The window manager only throws security exceptions, so let's
835 // log all others.
836 if (!(e instanceof SecurityException)) {
Dianne Hackborn164371f2013-10-01 19:10:13 -0700837 Slog.wtf(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800838 }
839 throw e;
840 }
841 }
842
Jeff Browne33348b2010-07-15 23:54:05 -0700843 private void placeWindowAfter(WindowState pos, WindowState window) {
Craig Mautner59c00972012-07-30 12:10:24 -0700844 final WindowList windows = pos.getWindowList();
845 final int i = windows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800846 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847 TAG, "Adding window " + window + " at "
Craig Mautner59c00972012-07-30 12:10:24 -0700848 + (i+1) + " of " + windows.size() + " (after " + pos + ")");
849 windows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700850 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800851 }
852
Jeff Browne33348b2010-07-15 23:54:05 -0700853 private void placeWindowBefore(WindowState pos, WindowState window) {
Craig Mautner59c00972012-07-30 12:10:24 -0700854 final WindowList windows = pos.getWindowList();
Craig Mautnerf81b90872013-02-26 13:02:43 -0800855 int i = windows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800856 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800857 TAG, "Adding window " + window + " at "
Craig Mautner59c00972012-07-30 12:10:24 -0700858 + i + " of " + windows.size() + " (before " + pos + ")");
Craig Mautnerf81b90872013-02-26 13:02:43 -0800859 if (i < 0) {
860 Slog.w(TAG, "placeWindowBefore: Unable to find " + pos + " in " + windows);
861 i = 0;
862 }
Craig Mautner59c00972012-07-30 12:10:24 -0700863 windows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700864 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800865 }
866
867 //This method finds out the index of a window that has the same app token as
868 //win. used for z ordering the windows in mWindows
869 private int findIdxBasedOnAppTokens(WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -0700870 WindowList windows = win.getWindowList();
871 for(int j = windows.size() - 1; j >= 0; j--) {
872 WindowState wentry = windows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800873 if(wentry.mAppToken == win.mAppToken) {
874 return j;
875 }
876 }
877 return -1;
878 }
Romain Guy06882f82009-06-10 13:36:04 -0700879
Craig Mautnerefb735d2012-09-07 15:40:24 -0700880 /**
881 * Return the list of Windows from the passed token on the given Display.
882 * @param token The token with all the windows.
883 * @param displayContent The display we are interested in.
884 * @return List of windows from token that are on displayContent.
885 */
Craig Mautner69b08182012-09-05 13:07:13 -0700886 WindowList getTokenWindowsOnDisplay(WindowToken token, DisplayContent displayContent) {
887 final WindowList windowList = new WindowList();
888 final int count = token.windows.size();
889 for (int i = 0; i < count; i++) {
890 final WindowState win = token.windows.get(i);
Craig Mautnerdf88d732014-01-27 09:21:32 -0800891 if (win.getDisplayContent() == displayContent) {
Craig Mautner69b08182012-09-05 13:07:13 -0700892 windowList.add(win);
893 }
894 }
895 return windowList;
896 }
897
Craig Mautner7b1aa772012-11-30 16:14:45 -0800898 /**
899 * Recursive search through a WindowList and all of its windows' children.
900 * @param targetWin The window to search for.
901 * @param windows The list to search.
902 * @return The index of win in windows or of the window that is an ancestor of win.
903 */
904 private int indexOfWinInWindowList(WindowState targetWin, WindowList windows) {
905 for (int i = windows.size() - 1; i >= 0; i--) {
906 final WindowState w = windows.get(i);
907 if (w == targetWin) {
908 return i;
909 }
910 if (!w.mChildWindows.isEmpty()) {
911 if (indexOfWinInWindowList(targetWin, w.mChildWindows) >= 0) {
912 return i;
913 }
914 }
915 }
916 return -1;
917 }
918
Craig Mautnera5eed0b2013-03-16 12:41:54 -0700919 private int addAppWindowToListLocked(final WindowState win) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800920 final IWindow client = win.mClient;
921 final WindowToken token = win.mToken;
Craig Mautnerdf88d732014-01-27 09:21:32 -0800922 final DisplayContent displayContent = win.getDisplayContent();
Craig Mautnerd3849f52014-03-27 13:19:29 -0700923 if (displayContent == null) {
924 // It doesn't matter this display is going away.
925 return 0;
926 }
Romain Guy06882f82009-06-10 13:36:04 -0700927
Craig Mautner59c00972012-07-30 12:10:24 -0700928 final WindowList windows = win.getWindowList();
929 final int N = windows.size();
Craig Mautner69b08182012-09-05 13:07:13 -0700930 WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent);
Craig Mautnera5eed0b2013-03-16 12:41:54 -0700931 int tokenWindowsPos = 0;
932 int windowListPos = tokenWindowList.size();
933 if (!tokenWindowList.isEmpty()) {
934 // If this application has existing windows, we
935 // simply place the new window on top of them... but
936 // keep the starting window on top.
937 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
938 // Base windows go behind everything else.
939 WindowState lowestWindow = tokenWindowList.get(0);
940 placeWindowBefore(lowestWindow, win);
941 tokenWindowsPos = indexOfWinInWindowList(lowestWindow, token.windows);
942 } else {
943 AppWindowToken atoken = win.mAppToken;
944 WindowState lastWindow = tokenWindowList.get(windowListPos - 1);
945 if (atoken != null && lastWindow == atoken.startingWindow) {
946 placeWindowBefore(lastWindow, win);
947 tokenWindowsPos = indexOfWinInWindowList(lastWindow, token.windows);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800948 } else {
Craig Mautnera5eed0b2013-03-16 12:41:54 -0700949 int newIdx = findIdxBasedOnAppTokens(win);
950 //there is a window above this one associated with the same
951 //apptoken note that the window could be a floating window
952 //that was created later or a window at the top of the list of
953 //windows associated with this token.
Craig Mautner58458122013-09-14 14:59:50 -0700954 if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
Craig Mautnerb1885b82013-09-16 22:50:50 -0700955 "not Base app: Adding window " + win + " at " + (newIdx + 1) + " of " +
956 N);
Craig Mautnera5eed0b2013-03-16 12:41:54 -0700957 windows.add(newIdx + 1, win);
958 if (newIdx < 0) {
959 // No window from token found on win's display.
960 tokenWindowsPos = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800961 } else {
Craig Mautnera5eed0b2013-03-16 12:41:54 -0700962 tokenWindowsPos = indexOfWinInWindowList(
963 windows.get(newIdx), token.windows) + 1;
964 }
965 mWindowsChanged = true;
966 }
967 }
968 return tokenWindowsPos;
969 }
970
971 // No windows from this token on this display
972 if (localLOGV) Slog.v(TAG, "Figuring out where to add app window " + client.asBinder()
973 + " (token=" + token + ")");
974 // Figure out where the window should go, based on the
975 // order of applications.
976 WindowState pos = null;
977
Craig Mautner018be3d2013-08-27 13:25:17 -0700978 final ArrayList<Task> tasks = displayContent.getTasks();
Craig Mautnera5eed0b2013-03-16 12:41:54 -0700979 int taskNdx;
980 int tokenNdx = -1;
981 for (taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
982 AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
983 for (tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
984 final AppWindowToken t = tokens.get(tokenNdx);
985 if (t == token) {
986 --tokenNdx;
987 if (tokenNdx < 0) {
988 --taskNdx;
989 if (taskNdx >= 0) {
990 tokenNdx = tasks.get(taskNdx).mAppTokens.size() - 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800991 }
992 }
Craig Mautnera5eed0b2013-03-16 12:41:54 -0700993 break;
994 }
995
996 // We haven't reached the token yet; if this token
997 // is not going to the bottom and has windows on this display, we can
998 // use it as an anchor for when we do reach the token.
999 tokenWindowList = getTokenWindowsOnDisplay(t, displayContent);
1000 if (!t.sendingToBottom && tokenWindowList.size() > 0) {
1001 pos = tokenWindowList.get(0);
1002 }
1003 }
1004 if (tokenNdx >= 0) {
1005 // early exit
1006 break;
1007 }
1008 }
1009
1010 // We now know the index into the apps. If we found
1011 // an app window above, that gives us the position; else
1012 // we need to look some more.
1013 if (pos != null) {
1014 // Move behind any windows attached to this one.
1015 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
1016 if (atoken != null) {
1017 tokenWindowList =
1018 getTokenWindowsOnDisplay(atoken, displayContent);
1019 final int NC = tokenWindowList.size();
1020 if (NC > 0) {
1021 WindowState bottom = tokenWindowList.get(0);
1022 if (bottom.mSubLayer < 0) {
1023 pos = bottom;
1024 }
1025 }
1026 }
1027 placeWindowBefore(pos, win);
1028 return tokenWindowsPos;
1029 }
1030
1031 // Continue looking down until we find the first
1032 // token that has windows on this display.
1033 for ( ; taskNdx >= 0; --taskNdx) {
1034 AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
1035 for ( ; tokenNdx >= 0; --tokenNdx) {
1036 final AppWindowToken t = tokens.get(tokenNdx);
1037 tokenWindowList = getTokenWindowsOnDisplay(t, displayContent);
1038 final int NW = tokenWindowList.size();
1039 if (NW > 0) {
1040 pos = tokenWindowList.get(NW-1);
1041 break;
1042 }
1043 }
1044 if (tokenNdx >= 0) {
1045 // found
1046 break;
1047 }
1048 }
1049
1050 if (pos != null) {
1051 // Move in front of any windows attached to this
1052 // one.
1053 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
1054 if (atoken != null) {
1055 final int NC = atoken.windows.size();
1056 if (NC > 0) {
1057 WindowState top = atoken.windows.get(NC-1);
1058 if (top.mSubLayer >= 0) {
1059 pos = top;
1060 }
1061 }
1062 }
1063 placeWindowAfter(pos, win);
1064 return tokenWindowsPos;
1065 }
1066
1067 // Just search for the start of this layer.
1068 final int myLayer = win.mBaseLayer;
1069 int i;
1070 for (i = 0; i < N; i++) {
1071 WindowState w = windows.get(i);
1072 if (w.mBaseLayer > myLayer) {
1073 break;
1074 }
1075 }
Craig Mautner58458122013-09-14 14:59:50 -07001076 if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
Craig Mautnerb1885b82013-09-16 22:50:50 -07001077 "Based on layer: Adding window " + win + " at " + i + " of " + N);
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001078 windows.add(i, win);
1079 mWindowsChanged = true;
1080 return tokenWindowsPos;
1081 }
1082
1083 private void addFreeWindowToListLocked(final WindowState win) {
1084 final WindowList windows = win.getWindowList();
1085
1086 // Figure out where window should go, based on layer.
1087 final int myLayer = win.mBaseLayer;
1088 int i;
1089 for (i = windows.size() - 1; i >= 0; i--) {
1090 if (windows.get(i).mBaseLayer <= myLayer) {
1091 break;
1092 }
1093 }
1094 i++;
Craig Mautner58458122013-09-14 14:59:50 -07001095 if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
Craig Mautnerb1885b82013-09-16 22:50:50 -07001096 "Free window: Adding window " + win + " at " + i + " of " + windows.size());
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001097 windows.add(i, win);
1098 mWindowsChanged = true;
1099 }
1100
1101 private void addAttachedWindowToListLocked(final WindowState win, boolean addToToken) {
1102 final WindowToken token = win.mToken;
Craig Mautnerdf88d732014-01-27 09:21:32 -08001103 final DisplayContent displayContent = win.getDisplayContent();
Craig Mautnerd3849f52014-03-27 13:19:29 -07001104 if (displayContent == null) {
1105 return;
1106 }
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001107 final WindowState attached = win.mAttachedWindow;
1108
1109 WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent);
1110
1111 // Figure out this window's ordering relative to the window
1112 // it is attached to.
1113 final int NA = tokenWindowList.size();
1114 final int sublayer = win.mSubLayer;
1115 int largestSublayer = Integer.MIN_VALUE;
1116 WindowState windowWithLargestSublayer = null;
1117 int i;
1118 for (i = 0; i < NA; i++) {
1119 WindowState w = tokenWindowList.get(i);
1120 final int wSublayer = w.mSubLayer;
1121 if (wSublayer >= largestSublayer) {
1122 largestSublayer = wSublayer;
1123 windowWithLargestSublayer = w;
1124 }
1125 if (sublayer < 0) {
1126 // For negative sublayers, we go below all windows
1127 // in the same sublayer.
1128 if (wSublayer >= sublayer) {
1129 if (addToToken) {
1130 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
1131 token.windows.add(i, win);
1132 }
1133 placeWindowBefore(wSublayer >= 0 ? attached : w, win);
1134 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001135 }
1136 } else {
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001137 // For positive sublayers, we go above all windows
1138 // in the same sublayer.
1139 if (wSublayer > sublayer) {
1140 if (addToToken) {
1141 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
1142 token.windows.add(i, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001143 }
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001144 placeWindowBefore(w, win);
1145 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001146 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001147 }
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001148 }
1149 if (i >= NA) {
1150 if (addToToken) {
1151 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
1152 token.windows.add(win);
1153 }
1154 if (sublayer < 0) {
1155 placeWindowBefore(attached, win);
1156 } else {
1157 placeWindowAfter(largestSublayer >= 0
1158 ? windowWithLargestSublayer
1159 : attached,
1160 win);
1161 }
1162 }
1163 }
Craig Mautner59c00972012-07-30 12:10:24 -07001164
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001165 private void addWindowToListInOrderLocked(final WindowState win, boolean addToToken) {
Craig Mautnerb1885b82013-09-16 22:50:50 -07001166 if (DEBUG_FOCUS_LIGHT) Slog.d(TAG, "addWindowToListInOrderLocked: win=" + win +
1167 " Callers=" + Debug.getCallers(4));
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001168 if (win.mAttachedWindow == null) {
1169 final WindowToken token = win.mToken;
1170 int tokenWindowsPos = 0;
1171 if (token.appWindowToken != null) {
1172 tokenWindowsPos = addAppWindowToListLocked(win);
1173 } else {
1174 addFreeWindowToListLocked(win);
1175 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001176 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001177 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001178 token.windows.add(tokenWindowsPos, win);
1179 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001180 } else {
Craig Mautnera5eed0b2013-03-16 12:41:54 -07001181 addAttachedWindowToListLocked(win, addToToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001182 }
Romain Guy06882f82009-06-10 13:36:04 -07001183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001184 if (win.mAppToken != null && addToToken) {
1185 win.mAppToken.allAppWindows.add(win);
1186 }
1187 }
Romain Guy06882f82009-06-10 13:36:04 -07001188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001189 static boolean canBeImeTarget(WindowState w) {
1190 final int fl = w.mAttrs.flags
1191 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
Dianne Hackborne75d8722011-01-27 19:37:40 -08001192 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)
Craig Mautner65d11b32012-10-01 13:59:52 -07001193 || w.mAttrs.type == TYPE_APPLICATION_STARTING) {
Dianne Hackborne75d8722011-01-27 19:37:40 -08001194 if (DEBUG_INPUT_METHOD) {
1195 Slog.i(TAG, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
1196 if (!w.isVisibleOrAdding()) {
Mathias Agopian29479eb2013-02-14 14:36:04 -08001197 Slog.i(TAG, " mSurface=" + w.mWinAnimator.mSurfaceControl
Dianne Hackborne75d8722011-01-27 19:37:40 -08001198 + " relayoutCalled=" + w.mRelayoutCalled + " viewVis=" + w.mViewVisibility
Dianne Hackbornac920872012-05-22 11:49:49 -07001199 + " policyVis=" + w.mPolicyVisibility
1200 + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim
1201 + " attachHid=" + w.mAttachedHidden
Dianne Hackborne75d8722011-01-27 19:37:40 -08001202 + " exiting=" + w.mExiting + " destroying=" + w.mDestroying);
1203 if (w.mAppToken != null) {
1204 Slog.i(TAG, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
1205 }
1206 }
1207 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001208 return w.isVisibleOrAdding();
1209 }
1210 return false;
1211 }
Romain Guy06882f82009-06-10 13:36:04 -07001212
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001213 /**
1214 * Dig through the WindowStates and find the one that the Input Method will target.
1215 * @param willMove
1216 * @return The index+1 in mWindows of the discovered target.
1217 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001218 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001219 // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
1220 // same display. Or even when the current IME/target are not on the same screen as the next
1221 // IME/target. For now only look for input windows on the main screen.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001222 WindowList windows = getDefaultWindowListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001223 WindowState w = null;
Craig Mautner22b9a5e2013-09-17 14:50:56 -07001224 int i;
1225 for (i = windows.size() - 1; i >= 0; --i) {
1226 WindowState win = windows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -07001227
Dianne Hackborne75d8722011-01-27 19:37:40 -08001228 if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG, "Checking window @" + i
Craig Mautner22b9a5e2013-09-17 14:50:56 -07001229 + " " + win + " fl=0x" + Integer.toHexString(win.mAttrs.flags));
1230 if (canBeImeTarget(win)) {
1231 w = win;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001232 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -07001233
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001234 // Yet more tricksyness! If this window is a "starting"
1235 // window, we do actually want to be on top of it, but
1236 // it is not -really- where input will go. So if the caller
1237 // is not actually looking to move the IME, look down below
1238 // for a real window to target...
1239 if (!willMove
Craig Mautner65d11b32012-10-01 13:59:52 -07001240 && w.mAttrs.type == TYPE_APPLICATION_STARTING
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001241 && i > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001242 WindowState wb = windows.get(i-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001243 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1244 i--;
1245 w = wb;
1246 }
1247 }
1248 break;
1249 }
1250 }
Romain Guy06882f82009-06-10 13:36:04 -07001251
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001252 // Now w is either mWindows[0] or an IME (or null if mWindows is empty).
1253
Dianne Hackborne75d8722011-01-27 19:37:40 -08001254 if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG, "Proposed new IME target: " + w);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001255
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001256 // Now, a special case -- if the last target's window is in the
1257 // process of exiting, and is above the new target, keep on the
1258 // last target to avoid flicker. Consider for example a Dialog with
1259 // the IME shown: when the Dialog is dismissed, we want to keep
1260 // the IME above it until it is completely gone so it doesn't drop
1261 // behind the dialog or its full-screen scrim.
Craig Mautner59c00972012-07-30 12:10:24 -07001262 final WindowState curTarget = mInputMethodTarget;
Craig Mautnerae879622013-10-03 14:07:45 -07001263 if (curTarget != null
Craig Mautner59c00972012-07-30 12:10:24 -07001264 && curTarget.isDisplayedLw()
Craig Mautnera987d432012-10-11 14:07:58 -07001265 && curTarget.isClosing()
Craig Mautnerae879622013-10-03 14:07:45 -07001266 && (w == null || curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) {
Craig Mautnere6f7d502012-10-08 10:34:17 -07001267 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Current target higher, not changing");
1268 return windows.indexOf(curTarget) + 1;
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001269 }
Romain Guy06882f82009-06-10 13:36:04 -07001270
Joe Onorato8a9b2202010-02-26 18:56:32 -08001271 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001272 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -07001273
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001274 if (willMove && w != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07001275 AppWindowToken token = curTarget == null ? null : curTarget.mAppToken;
1276 if (token != null) {
Romain Guy06882f82009-06-10 13:36:04 -07001277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001278 // Now some fun for dealing with window animations that
1279 // modify the Z order. We need to look at all windows below
1280 // the current target that are in this app, finding the highest
1281 // visible one in layering.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001282 WindowState highestTarget = null;
1283 int highestPos = 0;
Craig Mautner59431632012-04-04 11:56:44 -07001284 if (token.mAppAnimator.animating || token.mAppAnimator.animation != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07001285 WindowList curWindows = curTarget.getWindowList();
1286 int pos = curWindows.indexOf(curTarget);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001287 while (pos >= 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001288 WindowState win = curWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001289 if (win.mAppToken != token) {
1290 break;
1291 }
1292 if (!win.mRemoved) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001293 if (highestTarget == null || win.mWinAnimator.mAnimLayer >
1294 highestTarget.mWinAnimator.mAnimLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001295 highestTarget = win;
1296 highestPos = pos;
1297 }
1298 }
1299 pos--;
1300 }
1301 }
Romain Guy06882f82009-06-10 13:36:04 -07001302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001303 if (highestTarget != null) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08001304 if (DEBUG_INPUT_METHOD) Slog.v(TAG, mAppTransition + " " + highestTarget
Craig Mautnera2c77052012-03-26 12:14:43 -07001305 + " animating=" + highestTarget.mWinAnimator.isAnimating()
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001306 + " layer=" + highestTarget.mWinAnimator.mAnimLayer
1307 + " new layer=" + w.mWinAnimator.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001308
Craig Mautner164d4bb2012-11-26 13:51:23 -08001309 if (mAppTransition.isTransitionSet()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001310 // If we are currently setting up for an animation,
1311 // hold everything until we can find out what will happen.
1312 mInputMethodTargetWaitingAnim = true;
1313 mInputMethodTarget = highestTarget;
1314 return highestPos + 1;
Craig Mautnera2c77052012-03-26 12:14:43 -07001315 } else if (highestTarget.mWinAnimator.isAnimating() &&
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001316 highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001317 // If the window we are currently targeting is involved
1318 // with an animation, and it is on top of the next target
1319 // we will be over, then hold off on moving until
1320 // that is done.
Dianne Hackborne75d8722011-01-27 19:37:40 -08001321 mInputMethodTargetWaitingAnim = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001322 mInputMethodTarget = highestTarget;
1323 return highestPos + 1;
1324 }
1325 }
1326 }
1327 }
Romain Guy06882f82009-06-10 13:36:04 -07001328
Joe Onorato8a9b2202010-02-26 18:56:32 -08001329 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001330 if (w != null) {
1331 if (willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001332 if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to "
1333 + w + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001334 mInputMethodTarget = w;
Dianne Hackborne75d8722011-01-27 19:37:40 -08001335 mInputMethodTargetWaitingAnim = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001336 if (w.mAppToken != null) {
Craig Mautner59431632012-04-04 11:56:44 -07001337 setInputMethodAnimLayerAdjustment(w.mAppToken.mAppAnimator.animLayerAdjustment);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001338 } else {
1339 setInputMethodAnimLayerAdjustment(0);
1340 }
1341 }
1342 return i+1;
1343 }
1344 if (willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001345 if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to null."
1346 + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001347 mInputMethodTarget = null;
1348 setInputMethodAnimLayerAdjustment(0);
1349 }
1350 return -1;
1351 }
Romain Guy06882f82009-06-10 13:36:04 -07001352
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001353 void addInputMethodWindowToListLocked(WindowState win) {
1354 int pos = findDesiredInputMethodWindowIndexLocked(true);
1355 if (pos >= 0) {
1356 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001357 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001358 TAG, "Adding input method window " + win + " at " + pos);
Craig Mautner59c00972012-07-30 12:10:24 -07001359 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001360 getDefaultWindowListLocked().add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001361 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001362 moveInputMethodDialogsLocked(pos+1);
1363 return;
1364 }
1365 win.mTargetAppToken = null;
1366 addWindowToListInOrderLocked(win, true);
1367 moveInputMethodDialogsLocked(pos);
1368 }
Romain Guy06882f82009-06-10 13:36:04 -07001369
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001370 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001371 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001372 mInputMethodAnimLayerAdjustment = adj;
1373 WindowState imw = mInputMethodWindow;
1374 if (imw != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001375 imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001376 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001377 + " anim layer: " + imw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001378 int wi = imw.mChildWindows.size();
1379 while (wi > 0) {
1380 wi--;
Jeff Browne33348b2010-07-15 23:54:05 -07001381 WindowState cw = imw.mChildWindows.get(wi);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001382 cw.mWinAnimator.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001383 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001384 + " anim layer: " + cw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001385 }
1386 }
1387 int di = mInputMethodDialogs.size();
1388 while (di > 0) {
1389 di --;
1390 imw = mInputMethodDialogs.get(di);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001391 imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001392 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001393 + " anim layer: " + imw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001394 }
1395 }
Romain Guy06882f82009-06-10 13:36:04 -07001396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001397 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -07001398 WindowList windows = win.getWindowList();
1399 int wpos = windows.indexOf(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001400 if (wpos >= 0) {
1401 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001402 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
Craig Mautner59c00972012-07-30 12:10:24 -07001403 windows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001404 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001405 int NC = win.mChildWindows.size();
1406 while (NC > 0) {
1407 NC--;
Jeff Browne33348b2010-07-15 23:54:05 -07001408 WindowState cw = win.mChildWindows.get(NC);
Craig Mautner59c00972012-07-30 12:10:24 -07001409 int cpos = windows.indexOf(cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001410 if (cpos >= 0) {
1411 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001412 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001413 + cpos + ": " + cw);
Craig Mautner59c00972012-07-30 12:10:24 -07001414 windows.remove(cpos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001415 }
1416 }
1417 }
1418 return interestingPos;
1419 }
Romain Guy06882f82009-06-10 13:36:04 -07001420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001421 private void reAddWindowToListInOrderLocked(WindowState win) {
1422 addWindowToListInOrderLocked(win, false);
1423 // This is a hack to get all of the child windows added as well
1424 // at the right position. Child windows should be rare and
1425 // this case should be rare, so it shouldn't be that big a deal.
Craig Mautner59c00972012-07-30 12:10:24 -07001426 WindowList windows = win.getWindowList();
1427 int wpos = windows.indexOf(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001428 if (wpos >= 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001429 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos + ": " + win);
1430 windows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001431 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001432 reAddWindowLocked(wpos, win);
1433 }
1434 }
Romain Guy06882f82009-06-10 13:36:04 -07001435
Craig Mautner59c00972012-07-30 12:10:24 -07001436 void logWindowList(final WindowList windows, String prefix) {
1437 int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001438 while (N > 0) {
1439 N--;
Craig Mautner59c00972012-07-30 12:10:24 -07001440 Slog.v(TAG, prefix + "#" + N + ": " + windows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001441 }
1442 }
Romain Guy06882f82009-06-10 13:36:04 -07001443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001444 void moveInputMethodDialogsLocked(int pos) {
1445 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001446
Craig Mautner59c00972012-07-30 12:10:24 -07001447 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001448 WindowList windows = getDefaultWindowListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001449 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001450 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001451 for (int i=0; i<N; i++) {
1452 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1453 }
1454 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001455 Slog.v(TAG, "Window list w/pos=" + pos);
Craig Mautner59c00972012-07-30 12:10:24 -07001456 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001457 }
Romain Guy06882f82009-06-10 13:36:04 -07001458
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001459 if (pos >= 0) {
1460 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
Craig Mautner59c00972012-07-30 12:10:24 -07001461 if (pos < windows.size()) {
1462 WindowState wp = windows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001463 if (wp == mInputMethodWindow) {
1464 pos++;
1465 }
1466 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001467 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001468 for (int i=0; i<N; i++) {
1469 WindowState win = dialogs.get(i);
1470 win.mTargetAppToken = targetAppToken;
1471 pos = reAddWindowLocked(pos, win);
1472 }
1473 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001474 Slog.v(TAG, "Final window list:");
Craig Mautner59c00972012-07-30 12:10:24 -07001475 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001476 }
1477 return;
1478 }
1479 for (int i=0; i<N; i++) {
1480 WindowState win = dialogs.get(i);
1481 win.mTargetAppToken = null;
1482 reAddWindowToListInOrderLocked(win);
1483 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001484 Slog.v(TAG, "No IM target, final list:");
Craig Mautner59c00972012-07-30 12:10:24 -07001485 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001486 }
1487 }
1488 }
Romain Guy06882f82009-06-10 13:36:04 -07001489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001490 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1491 final WindowState imWin = mInputMethodWindow;
1492 final int DN = mInputMethodDialogs.size();
1493 if (imWin == null && DN == 0) {
1494 return false;
1495 }
Romain Guy06882f82009-06-10 13:36:04 -07001496
Craig Mautner59c00972012-07-30 12:10:24 -07001497 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001498 WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07001499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001500 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1501 if (imPos >= 0) {
1502 // In this case, the input method windows are to be placed
1503 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001504
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 // First check to see if the input method windows are already
1506 // located here, and contiguous.
Craig Mautner59c00972012-07-30 12:10:24 -07001507 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001508 WindowState firstImWin = imPos < N
Craig Mautner59c00972012-07-30 12:10:24 -07001509 ? windows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001510
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 // Figure out the actual input method window that should be
1512 // at the bottom of their stack.
1513 WindowState baseImWin = imWin != null
1514 ? imWin : mInputMethodDialogs.get(0);
1515 if (baseImWin.mChildWindows.size() > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001516 WindowState cw = baseImWin.mChildWindows.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001517 if (cw.mSubLayer < 0) baseImWin = cw;
1518 }
Romain Guy06882f82009-06-10 13:36:04 -07001519
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520 if (firstImWin == baseImWin) {
1521 // The windows haven't moved... but are they still contiguous?
1522 // First find the top IM window.
1523 int pos = imPos+1;
1524 while (pos < N) {
Craig Mautner59c00972012-07-30 12:10:24 -07001525 if (!(windows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001526 break;
1527 }
1528 pos++;
1529 }
1530 pos++;
1531 // Now there should be no more input method windows above.
1532 while (pos < N) {
Craig Mautner59c00972012-07-30 12:10:24 -07001533 if ((windows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001534 break;
1535 }
1536 pos++;
1537 }
1538 if (pos >= N) {
Carrie Xu5c971842012-10-30 17:28:39 +08001539 // Z order is good.
1540 // The IM target window may be changed, so update the mTargetAppToken.
1541 if (imWin != null) {
1542 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1543 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001544 return false;
1545 }
1546 }
Romain Guy06882f82009-06-10 13:36:04 -07001547
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001548 if (imWin != null) {
1549 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001550 Slog.v(TAG, "Moving IM from " + imPos);
Craig Mautner59c00972012-07-30 12:10:24 -07001551 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001552 }
1553 imPos = tmpRemoveWindowLocked(imPos, imWin);
1554 if (DEBUG_INPUT_METHOD) {
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001555 Slog.v(TAG, "List after removing with new pos " + imPos + ":");
Craig Mautner59c00972012-07-30 12:10:24 -07001556 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001557 }
1558 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1559 reAddWindowLocked(imPos, imWin);
1560 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001561 Slog.v(TAG, "List after moving IM to " + imPos + ":");
Craig Mautner59c00972012-07-30 12:10:24 -07001562 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 }
1564 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1565 } else {
1566 moveInputMethodDialogsLocked(imPos);
1567 }
Romain Guy06882f82009-06-10 13:36:04 -07001568
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001569 } else {
1570 // In this case, the input method windows go in a fixed layer,
1571 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001573 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001574 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001575 tmpRemoveWindowLocked(0, imWin);
1576 imWin.mTargetAppToken = null;
1577 reAddWindowToListInOrderLocked(imWin);
1578 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001579 Slog.v(TAG, "List with no IM target:");
Craig Mautner59c00972012-07-30 12:10:24 -07001580 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001581 }
Craig Mautner01cd0e72012-06-18 10:19:11 -07001582 if (DN > 0) moveInputMethodDialogsLocked(-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001583 } else {
Craig Mautner01cd0e72012-06-18 10:19:11 -07001584 moveInputMethodDialogsLocked(-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001585 }
Romain Guy06882f82009-06-10 13:36:04 -07001586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001587 }
Romain Guy06882f82009-06-10 13:36:04 -07001588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001589 if (needAssignLayers) {
Craig Mautner59c00972012-07-30 12:10:24 -07001590 assignLayersLocked(windows);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001591 }
Romain Guy06882f82009-06-10 13:36:04 -07001592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001593 return true;
1594 }
Romain Guy06882f82009-06-10 13:36:04 -07001595
Dianne Hackborn25994b42009-09-04 14:21:19 -07001596 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Craig Mautnerad3a9bb2012-03-09 11:31:06 -08001597 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001598 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1599 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
Craig Mautner59431632012-04-04 11:56:44 -07001600 ? wallpaperTarget.mAppToken.mAppAnimator.animation : null)
Dianne Hackborn25994b42009-09-04 14:21:19 -07001601 + " upper=" + mUpperWallpaperTarget
1602 + " lower=" + mLowerWallpaperTarget);
1603 return (wallpaperTarget != null
1604 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
Craig Mautner59431632012-04-04 11:56:44 -07001605 && wallpaperTarget.mAppToken.mAppAnimator.animation != null)))
Dianne Hackborn25994b42009-09-04 14:21:19 -07001606 || mUpperWallpaperTarget != null
1607 || mLowerWallpaperTarget != null;
1608 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001609
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001610 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1611 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001612
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001613 int adjustWallpaperWindowsLocked() {
Craig Mautnera608b882012-03-30 13:03:49 -07001614 mInnerFields.mWallpaperMayChange = false;
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001615 boolean targetChanged = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001616
Craig Mautner59c00972012-07-30 12:10:24 -07001617 // TODO(multidisplay): Wallpapers on main screen only.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001618 final DisplayInfo displayInfo = getDefaultDisplayContentLocked().getDisplayInfo();
John Spurlockef4adae2013-08-26 17:58:58 -04001619 final int dw = displayInfo.logicalWidth;
1620 final int dh = displayInfo.logicalHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001621
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001622 // First find top-most window that has asked to be on top of the
1623 // wallpaper; all wallpapers go behind it.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001624 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07001625 int N = windows.size();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001626 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001627 WindowState foundW = null;
1628 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001629 WindowState topCurW = null;
1630 int topCurI = 0;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001631 int windowDetachedI = -1;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001632 int i = N;
1633 while (i > 0) {
1634 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07001635 w = windows.get(i);
Craig Mautner65d11b32012-10-01 13:59:52 -07001636 if ((w.mAttrs.type == TYPE_WALLPAPER)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001637 if (topCurW == null) {
1638 topCurW = w;
1639 topCurI = i;
1640 }
1641 continue;
1642 }
1643 topCurW = null;
Craig Mautner96868332012-12-04 14:29:11 -08001644 if (w != mAnimator.mWindowDetachedWallpaper && w.mAppToken != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001645 // If this window's app token is hidden and not animating,
1646 // it is of no interest to us.
Craig Mautner59431632012-04-04 11:56:44 -07001647 if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001648 if (DEBUG_WALLPAPER) Slog.v(TAG,
Craig Mautner1d961d42012-05-27 12:02:11 -07001649 "Skipping hidden and not animating token: " + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001650 continue;
1651 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001652 }
Craig Mautnerae446592012-12-06 19:05:05 -08001653 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win #" + i + " " + w + ": isOnScreen="
1654 + w.isOnScreen() + " mDrawState=" + w.mWinAnimator.mDrawState);
1655 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isOnScreen()
1656 && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001657 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001658 "Found wallpaper target: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001659 foundW = w;
1660 foundI = i;
Craig Mautner4d7349b2012-04-20 14:52:47 -07001661 if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001662 // The current wallpaper target is animating, so we'll
1663 // look behind it for another possible target and figure
1664 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001665 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001666 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001667 continue;
1668 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001669 break;
Craig Mautner96868332012-12-04 14:29:11 -08001670 } else if (w == mAnimator.mWindowDetachedWallpaper) {
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001671 windowDetachedI = i;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001672 }
1673 }
1674
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001675 if (foundW == null && windowDetachedI >= 0) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001676 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001677 "Found animating detached wallpaper activity: #" + i + "=" + w);
1678 foundW = w;
1679 foundI = windowDetachedI;
1680 }
1681
Craig Mautner8863cca2012-09-18 15:04:34 -07001682 if (mWallpaperTarget != foundW
1683 && (mLowerWallpaperTarget == null || mLowerWallpaperTarget != foundW)) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001684 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001685 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001686 + " oldTarget: " + mWallpaperTarget);
1687 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001688
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001689 mLowerWallpaperTarget = null;
1690 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001691
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001692 WindowState oldW = mWallpaperTarget;
1693 mWallpaperTarget = foundW;
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001694 targetChanged = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001695
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001696 // Now what is happening... if the current and new targets are
1697 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001698 if (foundW != null && oldW != null) {
Craig Mautnerae446592012-12-06 19:05:05 -08001699 boolean oldAnim = oldW.isAnimatingLw();
1700 boolean foundAnim = foundW.isAnimatingLw();
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001701 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001702 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001703 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001704 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001705 if (foundAnim && oldAnim) {
Craig Mautner59c00972012-07-30 12:10:24 -07001706 int oldI = windows.indexOf(oldW);
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001707 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001708 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001709 }
1710 if (oldI >= 0) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001711 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001712 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001713 + "=" + oldW + "; new#" + foundI
1714 + "=" + foundW);
1715 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001716
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001717 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001718 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001719 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001720 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001721 }
1722 mWallpaperTarget = oldW;
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001723 foundW = oldW;
1724 foundI = oldI;
Craig Mautner711f90a2012-07-03 18:43:52 -07001725 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001726 // Now set the upper and lower wallpaper targets
1727 // correctly, and make sure that we are positioning
1728 // the wallpaper below the lower.
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001729 else if (foundI > oldI) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001730 // The new target is on top of the old one.
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001731 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001732 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001733 }
1734 mUpperWallpaperTarget = foundW;
1735 mLowerWallpaperTarget = oldW;
1736 foundW = oldW;
1737 foundI = oldI;
1738 } else {
1739 // The new target is below the old one.
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001740 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001741 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001742 }
1743 mUpperWallpaperTarget = oldW;
1744 mLowerWallpaperTarget = foundW;
1745 }
1746 }
1747 }
1748 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001749
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001750 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001751 // Is it time to stop animating?
Craig Mautnerae446592012-12-06 19:05:05 -08001752 if (!mLowerWallpaperTarget.isAnimatingLw() || !mUpperWallpaperTarget.isAnimatingLw()) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001753 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001754 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001755 }
1756 mLowerWallpaperTarget = null;
1757 mUpperWallpaperTarget = null;
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001758 mWallpaperTarget = foundW;
1759 targetChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001760 }
1761 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001762
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001763 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001764 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001765 // The window is visible to the compositor... but is it visible
1766 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001767 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001768 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001769
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001770 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001771 // its layer adjustment. Only do this if we are not transfering
1772 // between two wallpaper targets.
1773 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001774 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Craig Mautner59431632012-04-04 11:56:44 -07001775 ? foundW.mAppToken.mAppAnimator.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001776
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001777 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1778 * TYPE_LAYER_MULTIPLIER
1779 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001780
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001781 // Now w is the window we are supposed to be behind... but we
1782 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001783 // AND any starting window associated with it, AND below the
1784 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001785 while (foundI > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001786 WindowState wb = windows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001787 if (wb.mBaseLayer < maxLayer &&
1788 wb.mAttachedWindow != foundW &&
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001789 (foundW.mAttachedWindow == null ||
1790 wb.mAttachedWindow != foundW.mAttachedWindow) &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001791 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001792 foundW.mToken == null || wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001793 // This window is not related to the previous one in any
1794 // interesting way, so stop here.
1795 break;
1796 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001797 foundW = wb;
1798 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001799 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001800 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001801 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001802 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001803
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001804 if (foundW == null && topCurW != null) {
1805 // There is no wallpaper target, so it goes at the bottom.
1806 // We will assume it is the same place as last time, if known.
1807 foundW = topCurW;
1808 foundI = topCurI+1;
1809 } else {
1810 // Okay i is the position immediately above the wallpaper. Look at
1811 // what is below it for later.
Craig Mautner59c00972012-07-30 12:10:24 -07001812 foundW = foundI > 0 ? windows.get(foundI-1) : null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001813 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001814
Dianne Hackborn284ac932009-08-28 10:34:25 -07001815 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001816 if (mWallpaperTarget.mWallpaperX >= 0) {
1817 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001818 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001819 }
1820 if (mWallpaperTarget.mWallpaperY >= 0) {
1821 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001822 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001823 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001824 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001825
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001826 // Start stepping backwards from here, ensuring that our wallpaper windows
1827 // are correctly placed.
Craig Mautnerae446592012-12-06 19:05:05 -08001828 int changed = 0;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001829 int curTokenIndex = mWallpaperTokens.size();
1830 while (curTokenIndex > 0) {
1831 curTokenIndex--;
1832 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001833 if (token.hidden == visible) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001834 if (DEBUG_WALLPAPER_LIGHT) Slog.d(TAG,
1835 "Wallpaper token " + token + " hidden=" + !visible);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001836 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1837 token.hidden = !visible;
1838 // Need to do a layout to ensure the wallpaper now has the
1839 // correct size.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001840 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001841 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001842
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001843 int curWallpaperIndex = token.windows.size();
1844 while (curWallpaperIndex > 0) {
1845 curWallpaperIndex--;
1846 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001847
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001848 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001849 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001850 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001851
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001852 // First, make sure the client has the current visibility
1853 // state.
Craig Mautner507a2ee2012-06-13 08:39:38 -07001854 dispatchWallpaperVisibility(wallpaper, visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001855
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001856 wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001857 if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "adjustWallpaper win "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001858 + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001859
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001860 // First, if this window is at the current index, then all
1861 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001862 if (wallpaper == foundW) {
1863 foundI--;
1864 foundW = foundI > 0
Craig Mautner59c00972012-07-30 12:10:24 -07001865 ? windows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001866 continue;
1867 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001868
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001869 // The window didn't match... the current wallpaper window,
1870 // wherever it is, is in the wrong place, so make sure it is
1871 // not in the list.
Craig Mautner59c00972012-07-30 12:10:24 -07001872 int oldIndex = windows.indexOf(wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001873 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001874 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001875 + oldIndex + ": " + wallpaper);
Craig Mautner59c00972012-07-30 12:10:24 -07001876 windows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001877 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001878 if (oldIndex < foundI) {
1879 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001880 }
1881 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001882
Craig Mautner58004432013-10-14 12:58:42 -07001883 // Now stick it in. For apps over wallpaper keep the wallpaper at the bottommost
1884 // layer. For keyguard over wallpaper put the wallpaper under the keyguard.
1885 int insertionIndex = 0;
1886 if (visible && foundW != null) {
1887 final int type = foundW.mAttrs.type;
1888 if (type == TYPE_KEYGUARD || type == TYPE_KEYGUARD_SCRIM) {
1889 insertionIndex = windows.indexOf(foundW);
1890 }
1891 }
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001892 if (DEBUG_WALLPAPER_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001893 Slog.v(TAG, "Moving wallpaper " + wallpaper
Craig Mautner58004432013-10-14 12:58:42 -07001894 + " from " + oldIndex + " to " + insertionIndex);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001895 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001896
Craig Mautner58004432013-10-14 12:58:42 -07001897 windows.add(insertionIndex, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001898 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001899 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001900 }
1901 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001902
Craig Mautner5457e612013-05-10 16:25:02 -07001903 /*
Craig Mautner05d29032013-05-03 13:40:13 -07001904 final TaskStack targetStack =
1905 mWallpaperTarget == null ? null : mWallpaperTarget.getStack();
1906 if ((changed & ADJUST_WALLPAPER_LAYERS_CHANGED) != 0 &&
1907 targetStack != null && !targetStack.isHomeStack()) {
1908 // If the wallpaper target is not on the home stack then make sure that all windows
1909 // from other non-home stacks are above the wallpaper.
1910 for (i = foundI - 1; i >= 0; --i) {
1911 WindowState win = windows.get(i);
1912 if (!win.isVisibleLw()) {
1913 continue;
1914 }
1915 final TaskStack winStack = win.getStack();
1916 if (winStack != null && !winStack.isHomeStack() && winStack != targetStack) {
1917 windows.remove(i);
1918 windows.add(foundI + 1, win);
1919 }
1920 }
1921 }
Craig Mautner5457e612013-05-10 16:25:02 -07001922 */
Craig Mautner05d29032013-05-03 13:40:13 -07001923
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001924 if (targetChanged && DEBUG_WALLPAPER_LIGHT) {
1925 Slog.d(TAG, "New wallpaper: target=" + mWallpaperTarget
1926 + " lower=" + mLowerWallpaperTarget + " upper="
1927 + mUpperWallpaperTarget);
1928 }
1929
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001930 return changed;
1931 }
1932
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001933 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001934 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001935 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001936 mWallpaperAnimLayerAdjustment = adj;
1937 int curTokenIndex = mWallpaperTokens.size();
1938 while (curTokenIndex > 0) {
1939 curTokenIndex--;
1940 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1941 int curWallpaperIndex = token.windows.size();
1942 while (curWallpaperIndex > 0) {
1943 curWallpaperIndex--;
1944 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001945 wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + adj;
Craig Mautneref25d7a2012-05-15 23:01:47 -07001946 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "setWallpaper win "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001947 + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001948 }
1949 }
1950 }
1951
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001952 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
1953 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001954 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001955 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001956 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001957 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackbornffb3d932011-05-17 17:44:51 -07001958 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001959 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
1960 changed = wallpaperWin.mXOffset != offset;
1961 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001962 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001963 + wallpaperWin + " x: " + offset);
1964 wallpaperWin.mXOffset = offset;
1965 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001966 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001967 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001968 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001969 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001970 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001971
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001972 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001973 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001974 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1975 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1976 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001977 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001978 + wallpaperWin + " y: " + offset);
1979 changed = true;
1980 wallpaperWin.mYOffset = offset;
1981 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001982 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001983 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001984 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001985 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001986 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001987
Craig Mautnerbb1449b2012-03-23 16:11:14 -07001988 if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
Chet Haasea8e5a2b2011-10-28 13:18:16 -07001989 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001990 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001991 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001992 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
1993 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001994 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001995 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001996 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001997 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001998 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
1999 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002000 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002001 if (mWaitingOnWallpaper != null) {
2002 long start = SystemClock.uptimeMillis();
2003 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
2004 < start) {
2005 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002006 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07002007 "Waiting for offset complete...");
2008 mWindowMap.wait(WALLPAPER_TIMEOUT);
2009 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002010 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002011 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07002012 if ((start+WALLPAPER_TIMEOUT)
2013 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002014 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07002015 + wallpaperWin);
2016 mLastWallpaperTimeoutTime = start;
2017 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002018 }
Dianne Hackborn75804932009-10-20 20:15:20 -07002019 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002020 }
2021 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002022 } catch (RemoteException e) {
2023 }
2024 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002025
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002026 return changed;
2027 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002028
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002029 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002030 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002031 if (mWaitingOnWallpaper != null &&
2032 mWaitingOnWallpaper.mClient.asBinder() == window) {
2033 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07002034 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002035 }
2036 }
2037 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002038
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002039 void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08002040 final DisplayContent displayContent = changingTarget.getDisplayContent();
2041 if (displayContent == null) {
2042 return;
2043 }
Craig Mautner59c00972012-07-30 12:10:24 -07002044 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
John Spurlockef4adae2013-08-26 17:58:58 -04002045 final int dw = displayInfo.logicalWidth;
2046 final int dh = displayInfo.logicalHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002047
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002048 WindowState target = mWallpaperTarget;
2049 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002050 if (target.mWallpaperX >= 0) {
2051 mLastWallpaperX = target.mWallpaperX;
2052 } else if (changingTarget.mWallpaperX >= 0) {
2053 mLastWallpaperX = changingTarget.mWallpaperX;
2054 }
2055 if (target.mWallpaperY >= 0) {
2056 mLastWallpaperY = target.mWallpaperY;
2057 } else if (changingTarget.mWallpaperY >= 0) {
2058 mLastWallpaperY = changingTarget.mWallpaperY;
2059 }
2060 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002061
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002062 int curTokenIndex = mWallpaperTokens.size();
2063 while (curTokenIndex > 0) {
2064 curTokenIndex--;
2065 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2066 int curWallpaperIndex = token.windows.size();
2067 while (curWallpaperIndex > 0) {
2068 curWallpaperIndex--;
2069 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2070 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002071 WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
2072 winAnimator.computeShownFrameLocked();
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002073 // No need to lay out the windows - we can just set the wallpaper position
2074 // directly.
Craig Mautner58106812012-12-28 12:27:40 -08002075 winAnimator.setWallpaperOffset(wallpaper.mShownFrame);
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002076 // We only want to be synchronous with one wallpaper.
2077 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002078 }
2079 }
2080 }
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002081 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002082
Craig Mautner507a2ee2012-06-13 08:39:38 -07002083 /**
2084 * Check wallpaper for visiblity change and notify window if so.
2085 * @param wallpaper The wallpaper to test and notify.
2086 * @param visible Current visibility.
2087 */
2088 void dispatchWallpaperVisibility(final WindowState wallpaper, final boolean visible) {
2089 if (wallpaper.mWallpaperVisible != visible) {
2090 wallpaper.mWallpaperVisible = visible;
2091 try {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07002092 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
2093 "Updating vis of wallpaper " + wallpaper
2094 + ": " + visible + " from:\n" + Debug.getCallers(4, " "));
Craig Mautner507a2ee2012-06-13 08:39:38 -07002095 wallpaper.mClient.dispatchAppVisibility(visible);
2096 } catch (RemoteException e) {
2097 }
2098 }
2099 }
2100
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002101 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07002102 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Craig Mautnerdf88d732014-01-27 09:21:32 -08002103 final DisplayContent displayContent = mWallpaperTarget.getDisplayContent();
2104 if (displayContent == null) {
2105 return;
2106 }
Craig Mautner59c00972012-07-30 12:10:24 -07002107 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
John Spurlockef4adae2013-08-26 17:58:58 -04002108 final int dw = displayInfo.logicalWidth;
2109 final int dh = displayInfo.logicalHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002110
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002111 int curTokenIndex = mWallpaperTokens.size();
2112 while (curTokenIndex > 0) {
2113 curTokenIndex--;
2114 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002115 if (token.hidden == visible) {
2116 token.hidden = !visible;
2117 // Need to do a layout to ensure the wallpaper now has the
2118 // correct size.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07002119 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002120 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002121
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002122 int curWallpaperIndex = token.windows.size();
2123 while (curWallpaperIndex > 0) {
2124 curWallpaperIndex--;
2125 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2126 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002127 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002128 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002129
Craig Mautner507a2ee2012-06-13 08:39:38 -07002130 dispatchWallpaperVisibility(wallpaper, visible);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002131 }
2132 }
2133 }
Craig Mautner711f90a2012-07-03 18:43:52 -07002134
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002135 public int addWindow(Session session, IWindow client, int seq,
Craig Mautner6881a102012-07-27 13:04:51 -07002136 WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002137 Rect outContentInsets, InputChannel outInputChannel) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08002138 int[] appOp = new int[1];
2139 int res = mPolicy.checkAddPermission(attrs, appOp);
Jeff Brown98365d72012-08-19 20:30:52 -07002140 if (res != WindowManagerGlobal.ADD_OKAY) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002141 return res;
2142 }
Romain Guy06882f82009-06-10 13:36:04 -07002143
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002144 boolean reportNewConfig = false;
2145 WindowState attachedWindow = null;
2146 WindowState win = null;
Dianne Hackborn5132b372010-07-29 12:51:35 -07002147 long origId;
Craig Mautner88400d32012-09-30 12:35:45 -07002148 final int type = attrs.type;
Romain Guy06882f82009-06-10 13:36:04 -07002149
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002150 synchronized(mWindowMap) {
Jeff Browne215f262012-09-10 16:01:14 -07002151 if (!mDisplayReady) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07002152 throw new IllegalStateException("Display has not been initialialized");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002153 }
Romain Guy06882f82009-06-10 13:36:04 -07002154
Craig Mautner2d5618c2012-10-18 13:55:47 -07002155 final DisplayContent displayContent = getDisplayContentLocked(displayId);
2156 if (displayContent == null) {
Jeff Browna506a6e2013-06-04 00:02:38 -07002157 Slog.w(TAG, "Attempted to add window to a display that does not exist: "
2158 + displayId + ". Aborting.");
2159 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
2160 }
2161 if (!displayContent.hasAccess(session.mUid)) {
2162 Slog.w(TAG, "Attempted to add window to a display for which the application "
2163 + "does not have access: " + displayId + ". Aborting.");
Craig Mautner2d5618c2012-10-18 13:55:47 -07002164 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
2165 }
2166
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002167 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002168 Slog.w(TAG, "Window " + client + " is already added");
Jeff Brown98365d72012-08-19 20:30:52 -07002169 return WindowManagerGlobal.ADD_DUPLICATE_ADD;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002170 }
2171
Craig Mautner88400d32012-09-30 12:35:45 -07002172 if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002173 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002174 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002175 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002176 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002177 return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002178 }
2179 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
2180 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002181 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002182 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002183 return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002184 }
2185 }
2186
keunyounga446bf02013-06-21 19:07:57 -07002187 if (type == TYPE_PRIVATE_PRESENTATION && !displayContent.isPrivate()) {
2188 Slog.w(TAG, "Attempted to add private presentation window to a non-private display. Aborting.");
2189 return WindowManagerGlobal.ADD_PERMISSION_DENIED;
2190 }
2191
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002192 boolean addToken = false;
2193 WindowToken token = mTokenMap.get(attrs.token);
2194 if (token == null) {
Craig Mautner88400d32012-09-30 12:35:45 -07002195 if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002196 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002197 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002198 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002199 }
Craig Mautner88400d32012-09-30 12:35:45 -07002200 if (type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002201 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002202 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002203 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002204 }
Craig Mautner88400d32012-09-30 12:35:45 -07002205 if (type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002206 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002207 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002208 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002209 }
Craig Mautner88400d32012-09-30 12:35:45 -07002210 if (type == TYPE_DREAM) {
Daniel Sandler7d276c32012-01-30 14:33:52 -05002211 Slog.w(TAG, "Attempted to add Dream window with unknown token "
2212 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002213 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Daniel Sandler7d276c32012-01-30 14:33:52 -05002214 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002215 token = new WindowToken(this, attrs.token, -1, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002216 addToken = true;
Craig Mautner88400d32012-09-30 12:35:45 -07002217 } else if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002218 AppWindowToken atoken = token.appWindowToken;
2219 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002220 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002221 + token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002222 return WindowManagerGlobal.ADD_NOT_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002223 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002224 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002225 + token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002226 return WindowManagerGlobal.ADD_APP_EXITING;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002227 }
Craig Mautner88400d32012-09-30 12:35:45 -07002228 if (type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002229 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002230 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002231 TAG, "**** NO NEED TO START: " + attrs.getTitle());
Jeff Brown98365d72012-08-19 20:30:52 -07002232 return WindowManagerGlobal.ADD_STARTING_NOT_NEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002233 }
Craig Mautner88400d32012-09-30 12:35:45 -07002234 } else if (type == TYPE_INPUT_METHOD) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002235 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002236 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002237 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002238 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002239 }
Craig Mautner88400d32012-09-30 12:35:45 -07002240 } else if (type == TYPE_WALLPAPER) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002241 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002242 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002243 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002244 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002245 }
Craig Mautner88400d32012-09-30 12:35:45 -07002246 } else if (type == TYPE_DREAM) {
Daniel Sandler7d276c32012-01-30 14:33:52 -05002247 if (token.windowType != TYPE_DREAM) {
2248 Slog.w(TAG, "Attempted to add Dream window with bad token "
2249 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002250 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Daniel Sandler7d276c32012-01-30 14:33:52 -05002251 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002252 }
2253
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002254 win = new WindowState(this, session, client, token,
Dianne Hackbornc2293022013-02-06 23:14:49 -08002255 attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002256 if (win.mDeathRecipient == null) {
2257 // Client has apparently died, so there is no reason to
2258 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002259 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002260 + " that is dead, aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002261 return WindowManagerGlobal.ADD_APP_EXITING;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002262 }
2263
Craig Mautnerd3849f52014-03-27 13:19:29 -07002264 if (win.getDisplayContent() == null) {
2265 Slog.w(TAG, "Adding window to Display that has been removed.");
2266 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
2267 }
2268
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002269 mPolicy.adjustWindowParamsLw(win.mAttrs);
Craig Mautner88400d32012-09-30 12:35:45 -07002270 win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));
Romain Guy06882f82009-06-10 13:36:04 -07002271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002272 res = mPolicy.prepareAddWindowLw(win, attrs);
Jeff Brown98365d72012-08-19 20:30:52 -07002273 if (res != WindowManagerGlobal.ADD_OKAY) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002274 return res;
2275 }
Craig Mautner918b53b2012-07-09 14:15:54 -07002276
Jeff Browncc4f7db2011-08-30 20:34:48 -07002277 if (outInputChannel != null && (attrs.inputFeatures
2278 & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002279 String name = win.makeInputChannelName();
2280 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
Jeff Browncc4f7db2011-08-30 20:34:48 -07002281 win.setInputChannel(inputChannels[0]);
Jeff Brown0a0ab122011-08-12 18:08:08 -07002282 inputChannels[1].transferTo(outInputChannel);
Craig Mautner918b53b2012-07-09 14:15:54 -07002283
Jeff Brown928e0542011-01-10 11:17:36 -08002284 mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002285 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002286
2287 // From now on, no exceptions or errors allowed!
2288
Jeff Brown98365d72012-08-19 20:30:52 -07002289 res = WindowManagerGlobal.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002290
Dianne Hackborn5132b372010-07-29 12:51:35 -07002291 origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002292
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002293 if (addToken) {
2294 mTokenMap.put(attrs.token, token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002295 }
2296 win.attach();
2297 mWindowMap.put(client.asBinder(), win);
Dianne Hackbornc2293022013-02-06 23:14:49 -08002298 if (win.mAppOp != AppOpsManager.OP_NONE) {
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002299 if (mAppOps.startOpNoThrow(win.mAppOp, win.getOwningUid(), win.getOwningPackage())
2300 != AppOpsManager.MODE_ALLOWED) {
2301 win.setAppOpVisibilityLw(false);
2302 }
Dianne Hackbornc2293022013-02-06 23:14:49 -08002303 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002304
Craig Mautner88400d32012-09-30 12:35:45 -07002305 if (type == TYPE_APPLICATION_STARTING && token.appWindowToken != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002306 token.appWindowToken.startingWindow = win;
Craig Mautner38b24782012-07-02 16:21:28 -07002307 if (DEBUG_STARTING_WINDOW) Slog.v (TAG, "addWindow: " + token.appWindowToken
2308 + " startingWindow=" + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002309 }
2310
2311 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002312
Craig Mautner88400d32012-09-30 12:35:45 -07002313 if (type == TYPE_INPUT_METHOD) {
satok1bc0a492012-04-25 22:47:12 +09002314 win.mGivenInsetsPending = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002315 mInputMethodWindow = win;
2316 addInputMethodWindowToListLocked(win);
2317 imMayMove = false;
Craig Mautner88400d32012-09-30 12:35:45 -07002318 } else if (type == TYPE_INPUT_METHOD_DIALOG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002319 mInputMethodDialogs.add(win);
2320 addWindowToListInOrderLocked(win, true);
Craig Mautnerc00204b2013-03-05 15:02:14 -08002321 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002322 imMayMove = false;
2323 } else {
2324 addWindowToListInOrderLocked(win, true);
Craig Mautner88400d32012-09-30 12:35:45 -07002325 if (type == TYPE_WALLPAPER) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002326 mLastWallpaperTimeoutTime = 0;
Craig Mautnerae446592012-12-06 19:05:05 -08002327 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002328 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Craig Mautnerae446592012-12-06 19:05:05 -08002329 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborn7ad44382012-10-18 17:46:00 -07002330 } else if (mWallpaperTarget != null
2331 && mWallpaperTarget.mLayer >= win.mBaseLayer) {
2332 // If there is currently a wallpaper being shown, and
2333 // the base layer of the new window is below the current
2334 // layer of the target window, then adjust the wallpaper.
2335 // This is to avoid a new window being placed between the
2336 // wallpaper and its target.
Craig Mautnerae446592012-12-06 19:05:05 -08002337 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002338 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002339 }
Romain Guy06882f82009-06-10 13:36:04 -07002340
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002341 win.mWinAnimator.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002342
Craig Mautner69b08182012-09-05 13:07:13 -07002343 if (displayContent.isDefaultDisplay) {
2344 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
2345 } else {
2346 outContentInsets.setEmpty();
2347 }
Romain Guy06882f82009-06-10 13:36:04 -07002348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002349 if (mInTouchMode) {
Jeff Brown98365d72012-08-19 20:30:52 -07002350 res |= WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002351 }
Craig Mautner764983d2012-03-22 11:37:36 -07002352 if (win.mAppToken == null || !win.mAppToken.clientHidden) {
Jeff Brown98365d72012-08-19 20:30:52 -07002353 res |= WindowManagerGlobal.ADD_FLAG_APP_VISIBLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002354 }
Romain Guy06882f82009-06-10 13:36:04 -07002355
Jeff Brown2e44b072011-01-24 15:21:56 -08002356 mInputMonitor.setUpdateInputWindowsNeededLw();
2357
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002358 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002359 if (win.canReceiveKeys()) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002360 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
2361 false /*updateInputWindows*/);
Jeff Brown349703e2010-06-22 01:27:15 -07002362 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002363 imMayMove = false;
2364 }
2365 }
Romain Guy06882f82009-06-10 13:36:04 -07002366
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002367 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002368 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002369 }
Romain Guy06882f82009-06-10 13:36:04 -07002370
Craig Mautner59c00972012-07-30 12:10:24 -07002371 assignLayersLocked(displayContent.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002372 // Don't do layout here, the window must call
2373 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002374
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002375 if (focusChanged) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002376 finishUpdateFocusedWindowAfterAssignLayersLocked(false /*updateInputWindows*/);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002377 }
Jeff Brown2e44b072011-01-24 15:21:56 -08002378 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08002379
Joe Onorato8a9b2202010-02-26 18:56:32 -08002380 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002381 TAG, "New client " + client.asBinder()
2382 + ": window=" + win);
Craig Mautner9e809442012-06-22 17:13:04 -07002383
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002384 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002385 reportNewConfig = true;
2386 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002387 }
2388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002389 if (reportNewConfig) {
2390 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002391 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07002392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002393 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002394
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002395 return res;
2396 }
Romain Guy06882f82009-06-10 13:36:04 -07002397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002398 public void removeWindow(Session session, IWindow client) {
2399 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002400 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002401 if (win == null) {
2402 return;
2403 }
2404 removeWindowLocked(session, win);
2405 }
2406 }
Romain Guy06882f82009-06-10 13:36:04 -07002407
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002408 public void removeWindowLocked(Session session, WindowState win) {
Craig Mautner68cc2412013-10-01 10:39:43 -07002409 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
2410 if (DEBUG_STARTING_WINDOW) Slog.d(TAG, "Starting window removed " + win);
Craig Mautner68cc2412013-10-01 10:39:43 -07002411 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002412
Craig Mautner58458122013-09-14 14:59:50 -07002413 if (localLOGV || DEBUG_FOCUS || DEBUG_FOCUS_LIGHT && win==mCurrentFocus) Slog.v(
Craig Mautnere2dd83a2013-10-07 17:01:41 -07002414 TAG, "Remove " + win + " client="
2415 + Integer.toHexString(System.identityHashCode(win.mClient.asBinder()))
2416 + ", surface=" + win.mWinAnimator.mSurfaceControl + " Callers="
2417 + Debug.getCallers(4));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002418
2419 final long origId = Binder.clearCallingIdentity();
Craig Mautner764983d2012-03-22 11:37:36 -07002420
Jeff Brownc5ed5912010-07-14 18:48:53 -07002421 win.disposeInputChannel();
Romain Guy06882f82009-06-10 13:36:04 -07002422
Joe Onorato8a9b2202010-02-26 18:56:32 -08002423 if (DEBUG_APP_TRANSITIONS) Slog.v(
Mathias Agopian29479eb2013-02-14 14:36:04 -08002424 TAG, "Remove " + win + ": mSurface=" + win.mWinAnimator.mSurfaceControl
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002425 + " mExiting=" + win.mExiting
Craig Mautnera2c77052012-03-26 12:14:43 -07002426 + " isAnimating=" + win.mWinAnimator.isAnimating()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002427 + " app-animation="
Craig Mautner59431632012-04-04 11:56:44 -07002428 + (win.mAppToken != null ? win.mAppToken.mAppAnimator.animation : null)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002429 + " inPendingTransaction="
2430 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2431 + " mDisplayFrozen=" + mDisplayFrozen);
2432 // Visibility of the removed window. Will be used later to update orientation later on.
2433 boolean wasVisible = false;
2434 // First, see if we need to run an animation. If we do, we have
2435 // to hold off on removing the window until the animation is done.
2436 // If the display is frozen, just remove immediately, since the
2437 // animation wouldn't be seen.
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002438 if (win.mHasSurface && okToDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002439 // If we are not currently running the exit animation, we
2440 // need to see about starting one.
Craig Mautner764983d2012-03-22 11:37:36 -07002441 wasVisible = win.isWinVisibleLw();
2442 if (wasVisible) {
Romain Guy06882f82009-06-10 13:36:04 -07002443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002444 int transit = WindowManagerPolicy.TRANSIT_EXIT;
Craig Mautnerbb1449b2012-03-23 16:11:14 -07002445 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002446 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2447 }
2448 // Try starting an animation.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002449 if (win.mWinAnimator.applyAnimationLocked(transit, false)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002450 win.mExiting = true;
2451 }
Svetoslav Ganov545252f2012-12-10 18:29:24 -08002452 //TODO (multidisplay): Magnification is supported only for the default display.
Svetoslav8e3feb12014-02-24 13:46:47 -08002453 if (mAccessibilityController != null
Svetoslav Ganov545252f2012-12-10 18:29:24 -08002454 && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
Svetoslav8e3feb12014-02-24 13:46:47 -08002455 mAccessibilityController.onWindowTransitionLocked(win, transit);
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07002456 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002457 }
Craig Mautnera2c77052012-03-26 12:14:43 -07002458 if (win.mExiting || win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002459 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002460 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002461 win.mExiting = true;
2462 win.mRemoveOnExit = true;
Craig Mautnerdf88d732014-01-27 09:21:32 -08002463 final DisplayContent displayContent = win.getDisplayContent();
2464 if (displayContent != null) {
2465 displayContent.layoutNeeded = true;
2466 }
Jeff Brown3a22cd92011-01-21 13:59:04 -08002467 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2468 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002469 performLayoutAndPlaceSurfacesLocked();
2470 if (win.mAppToken != null) {
2471 win.mAppToken.updateReportedVisibilityLocked();
2472 }
2473 //dump();
2474 Binder.restoreCallingIdentity(origId);
2475 return;
2476 }
2477 }
2478
2479 removeWindowInnerLocked(session, win);
2480 // Removing a visible window will effect the computed orientation
2481 // So just update orientation if needed.
Craig Mautner2268e7e2012-12-13 15:40:00 -08002482 if (wasVisible && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002483 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002484 }
Jeff Brown3a22cd92011-01-21 13:59:04 -08002485 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002486 Binder.restoreCallingIdentity(origId);
2487 }
Romain Guy06882f82009-06-10 13:36:04 -07002488
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002489 private void removeWindowInnerLocked(Session session, WindowState win) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002490 if (win.mRemoved) {
2491 // Nothing to do.
2492 return;
2493 }
2494
2495 for (int i=win.mChildWindows.size()-1; i>=0; i--) {
2496 WindowState cwin = win.mChildWindows.get(i);
2497 Slog.w(TAG, "Force-removing child win " + cwin + " from container "
2498 + win);
2499 removeWindowInnerLocked(cwin.mSession, cwin);
2500 }
2501
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002502 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002503
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002504 if (mInputMethodTarget == win) {
2505 moveInputMethodWindowsIfNeededLocked(false);
2506 }
Romain Guy06882f82009-06-10 13:36:04 -07002507
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002508 if (false) {
2509 RuntimeException e = new RuntimeException("here");
2510 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002511 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002512 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002514 mPolicy.removeWindowLw(win);
2515 win.removeLocked();
2516
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002517 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002518 mWindowMap.remove(win.mClient.asBinder());
Dianne Hackbornc2293022013-02-06 23:14:49 -08002519 if (win.mAppOp != AppOpsManager.OP_NONE) {
2520 mAppOps.finishOp(win.mAppOp, win.getOwningUid(), win.getOwningPackage());
2521 }
Craig Mautner59c00972012-07-30 12:10:24 -07002522
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002523 mPendingRemove.remove(win);
Craig Mautner860f6602012-10-18 09:38:10 -07002524 mResizingWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002525 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002526 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002527
2528 if (mInputMethodWindow == win) {
2529 mInputMethodWindow = null;
2530 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2531 mInputMethodDialogs.remove(win);
2532 }
Romain Guy06882f82009-06-10 13:36:04 -07002533
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002534 final WindowToken token = win.mToken;
2535 final AppWindowToken atoken = win.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002536 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + win + " from " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002537 token.windows.remove(win);
2538 if (atoken != null) {
2539 atoken.allAppWindows.remove(win);
2540 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002541 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002542 TAG, "**** Removing window " + win + ": count="
2543 + token.windows.size());
2544 if (token.windows.size() == 0) {
2545 if (!token.explicit) {
2546 mTokenMap.remove(token.token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002547 } else if (atoken != null) {
2548 atoken.firstWindowDrawn = false;
2549 }
2550 }
2551
2552 if (atoken != null) {
2553 if (atoken.startingWindow == win) {
Craig Mautner38b24782012-07-02 16:21:28 -07002554 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling startingWindow " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002555 atoken.startingWindow = null;
2556 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2557 // If this is the last window and we had requested a starting
2558 // transition window, well there is no point now.
Craig Mautner38b24782012-07-02 16:21:28 -07002559 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling last startingWindow");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002560 atoken.startingData = null;
2561 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2562 // If this is the last window except for a starting transition
2563 // window, we need to get rid of the starting transition.
Craig Mautner68cc2412013-10-01 10:39:43 -07002564 scheduleRemoveStartingWindow(atoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002565 }
2566 }
Romain Guy06882f82009-06-10 13:36:04 -07002567
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002568 if (win.mAttrs.type == TYPE_WALLPAPER) {
2569 mLastWallpaperTimeoutTime = 0;
Craig Mautnerae446592012-12-06 19:05:05 -08002570 getDefaultDisplayContentLocked().pendingLayoutChanges |=
2571 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002572 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Craig Mautnerae446592012-12-06 19:05:05 -08002573 getDefaultDisplayContentLocked().pendingLayoutChanges |=
2574 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002575 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002576
Craig Mautnerdf88d732014-01-27 09:21:32 -08002577 final WindowList windows = win.getWindowList();
2578 if (windows != null) {
2579 windows.remove(win);
2580 if (!mInLayout) {
2581 assignLayersLocked(windows);
2582 final DisplayContent displayContent = win.getDisplayContent();
2583 if (displayContent != null) {
2584 displayContent.layoutNeeded = true;
2585 }
2586 performLayoutAndPlaceSurfacesLocked();
2587 if (win.mAppToken != null) {
2588 win.mAppToken.updateReportedVisibilityLocked();
2589 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002590 }
2591 }
Craig Mautner9e809442012-06-22 17:13:04 -07002592
Jeff Brown2e44b072011-01-24 15:21:56 -08002593 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002594 }
2595
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002596 public void updateAppOpsState() {
2597 synchronized(mWindowMap) {
Craig Mautnerf8924152013-07-16 09:10:55 -07002598 final int numDisplays = mDisplayContents.size();
2599 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
2600 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
2601 final int numWindows = windows.size();
2602 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
2603 final WindowState win = windows.get(winNdx);
2604 if (win.mAppOp != AppOpsManager.OP_NONE) {
2605 final int mode = mAppOps.checkOpNoThrow(win.mAppOp, win.getOwningUid(),
2606 win.getOwningPackage());
2607 win.setAppOpVisibilityLw(mode == AppOpsManager.MODE_ALLOWED);
2608 }
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002609 }
2610 }
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002611 }
2612 }
2613
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002614 static void logSurface(WindowState w, String msg, RuntimeException where) {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002615 String str = " SURFACE " + msg + ": " + w;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002616 if (where != null) {
2617 Slog.i(TAG, str, where);
2618 } else {
2619 Slog.i(TAG, str);
2620 }
2621 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002622
Mathias Agopian3866f0d2013-02-11 22:08:48 -08002623 static void logSurface(SurfaceControl s, String title, String msg, RuntimeException where) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002624 String str = " SURFACE " + s + ": " + msg + " / " + title;
2625 if (where != null) {
2626 Slog.i(TAG, str, where);
2627 } else {
2628 Slog.i(TAG, str);
2629 }
2630 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07002631
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002632 void setTransparentRegionWindow(Session session, IWindow client, Region region) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002633 long origId = Binder.clearCallingIdentity();
2634 try {
2635 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002636 WindowState w = windowForClientLocked(session, client, false);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002637 if ((w != null) && w.mHasSurface) {
Craig Mautneref655012013-01-03 11:20:24 -08002638 w.mWinAnimator.setTransparentRegionHintLocked(region);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002639 }
2640 }
2641 } finally {
2642 Binder.restoreCallingIdentity(origId);
2643 }
2644 }
2645
2646 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002647 int touchableInsets, Rect contentInsets,
Jeff Brownfbf09772011-01-16 14:06:57 -08002648 Rect visibleInsets, Region touchableRegion) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002649 long origId = Binder.clearCallingIdentity();
2650 try {
2651 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002652 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002653 if (w != null) {
2654 w.mGivenInsetsPending = false;
2655 w.mGivenContentInsets.set(contentInsets);
2656 w.mGivenVisibleInsets.set(visibleInsets);
Jeff Brownfbf09772011-01-16 14:06:57 -08002657 w.mGivenTouchableRegion.set(touchableRegion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002658 w.mTouchableInsets = touchableInsets;
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002659 if (w.mGlobalScale != 1) {
2660 w.mGivenContentInsets.scale(w.mGlobalScale);
2661 w.mGivenVisibleInsets.scale(w.mGlobalScale);
2662 w.mGivenTouchableRegion.scale(w.mGlobalScale);
2663 }
Craig Mautnerdf88d732014-01-27 09:21:32 -08002664 final DisplayContent displayContent = w.getDisplayContent();
2665 if (displayContent != null) {
2666 displayContent.layoutNeeded = true;
2667 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002668 performLayoutAndPlaceSurfacesLocked();
2669 }
2670 }
2671 } finally {
2672 Binder.restoreCallingIdentity(origId);
2673 }
2674 }
Romain Guy06882f82009-06-10 13:36:04 -07002675
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002676 public void getWindowDisplayFrame(Session session, IWindow client,
2677 Rect outDisplayFrame) {
2678 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002679 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002680 if (win == null) {
2681 outDisplayFrame.setEmpty();
2682 return;
2683 }
2684 outDisplayFrame.set(win.mDisplayFrame);
2685 }
2686 }
2687
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002688 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2689 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002690 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2691 window.mWallpaperX = x;
2692 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002693 window.mWallpaperXStep = xStep;
2694 window.mWallpaperYStep = yStep;
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002695 updateWallpaperOffsetLocked(window, true);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002696 }
2697 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002698
Dianne Hackborn75804932009-10-20 20:15:20 -07002699 void wallpaperCommandComplete(IBinder window, Bundle result) {
2700 synchronized (mWindowMap) {
2701 if (mWaitingOnWallpaper != null &&
2702 mWaitingOnWallpaper.mClient.asBinder() == window) {
2703 mWaitingOnWallpaper = null;
2704 mWindowMap.notifyAll();
2705 }
2706 }
2707 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002708
Dianne Hackborn75804932009-10-20 20:15:20 -07002709 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2710 String action, int x, int y, int z, Bundle extras, boolean sync) {
2711 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2712 || window == mUpperWallpaperTarget) {
2713 boolean doWait = sync;
2714 int curTokenIndex = mWallpaperTokens.size();
2715 while (curTokenIndex > 0) {
2716 curTokenIndex--;
2717 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2718 int curWallpaperIndex = token.windows.size();
2719 while (curWallpaperIndex > 0) {
2720 curWallpaperIndex--;
2721 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2722 try {
2723 wallpaper.mClient.dispatchWallpaperCommand(action,
2724 x, y, z, extras, sync);
2725 // We only want to be synchronous with one wallpaper.
2726 sync = false;
2727 } catch (RemoteException e) {
2728 }
2729 }
2730 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002731
Dianne Hackborn75804932009-10-20 20:15:20 -07002732 if (doWait) {
2733 // XXX Need to wait for result.
2734 }
2735 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002736
Dianne Hackborn75804932009-10-20 20:15:20 -07002737 return null;
2738 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002739
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002740 public void setUniverseTransformLocked(WindowState window, float alpha,
2741 float offx, float offy, float dsdx, float dtdx, float dsdy, float dtdy) {
2742 Transformation transform = window.mWinAnimator.mUniverseTransform;
2743 transform.setAlpha(alpha);
2744 Matrix matrix = transform.getMatrix();
2745 matrix.getValues(mTmpFloats);
2746 mTmpFloats[Matrix.MTRANS_X] = offx;
2747 mTmpFloats[Matrix.MTRANS_Y] = offy;
2748 mTmpFloats[Matrix.MSCALE_X] = dsdx;
2749 mTmpFloats[Matrix.MSKEW_Y] = dtdx;
2750 mTmpFloats[Matrix.MSKEW_X] = dsdy;
2751 mTmpFloats[Matrix.MSCALE_Y] = dtdy;
2752 matrix.setValues(mTmpFloats);
Craig Mautnerdf88d732014-01-27 09:21:32 -08002753 final DisplayContent displayContent = window.getDisplayContent();
2754 if (displayContent == null) {
2755 return;
2756 }
2757
Craig Mautnerd3849f52014-03-27 13:19:29 -07002758 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
Jeff Brownfa25bf52012-07-23 19:26:30 -07002759 final RectF dispRect = new RectF(0, 0,
Craig Mautner59c00972012-07-30 12:10:24 -07002760 displayInfo.logicalWidth, displayInfo.logicalHeight);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002761 matrix.mapRect(dispRect);
Jeff Brownfa25bf52012-07-23 19:26:30 -07002762 window.mGivenTouchableRegion.set(0, 0,
Craig Mautner59c00972012-07-30 12:10:24 -07002763 displayInfo.logicalWidth, displayInfo.logicalHeight);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002764 window.mGivenTouchableRegion.op((int)dispRect.left, (int)dispRect.top,
2765 (int)dispRect.right, (int)dispRect.bottom, Region.Op.DIFFERENCE);
2766 window.mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
Craig Mautnerdf88d732014-01-27 09:21:32 -08002767 displayContent.layoutNeeded = true;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002768 performLayoutAndPlaceSurfacesLocked();
2769 }
2770
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002771 public void onRectangleOnScreenRequested(IBinder token, Rect rectangle, boolean immediate) {
2772 synchronized (mWindowMap) {
Svetoslav8e3feb12014-02-24 13:46:47 -08002773 if (mAccessibilityController != null) {
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07002774 WindowState window = mWindowMap.get(token);
Svetoslav Ganov545252f2012-12-10 18:29:24 -08002775 //TODO (multidisplay): Magnification is supported only for the default display.
2776 if (window != null && window.getDisplayId() == Display.DEFAULT_DISPLAY) {
Svetoslav8e3feb12014-02-24 13:46:47 -08002777 mAccessibilityController.onRectangleOnScreenRequestedLocked(rectangle,
2778 immediate);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002779 }
2780 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002781 }
2782 }
2783
Dianne Hackborne3f23a32013-03-01 13:25:35 -08002784 public IWindowId getWindowId(IBinder token) {
2785 synchronized (mWindowMap) {
2786 WindowState window = mWindowMap.get(token);
2787 return window != null ? window.mWindowId : null;
2788 }
2789 }
2790
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002791 public int relayoutWindow(Session session, IWindow client, int seq,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002792 WindowManager.LayoutParams attrs, int requestedWidth,
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002793 int requestedHeight, int viewVisibility, int flags,
Dianne Hackbornc4aad012013-02-22 15:05:25 -08002794 Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
Dianne Hackborn5c58de32012-04-28 19:52:37 -07002795 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07002796 boolean toBeDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002797 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002798 boolean configChanged;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002799 boolean surfaceChanged = false;
Dianne Hackborn12d3a942012-04-27 14:16:30 -07002800 boolean animating;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002801
2802 // if they don't have this permission, mask out the status bar bits
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002803 int systemUiVisibility = 0;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002804 if (attrs != null) {
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002805 systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
2806 if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -07002807 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
2808 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002809 systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
Dianne Hackborna44abeb2011-08-08 19:24:01 -07002810 }
Joe Onoratoac0ee892011-01-30 15:38:30 -08002811 }
2812 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002813 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002814
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002815 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002816 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002817 if (win == null) {
2818 return 0;
2819 }
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002820 WindowStateAnimator winAnimator = win.mWinAnimator;
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08002821 if (win.mRequestedWidth != requestedWidth
2822 || win.mRequestedHeight != requestedHeight) {
2823 win.mLayoutNeeded = true;
2824 win.mRequestedWidth = requestedWidth;
2825 win.mRequestedHeight = requestedHeight;
2826 }
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002827 if (attrs != null && seq == win.mSeq) {
2828 win.mSystemUiVisibility = systemUiVisibility;
2829 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002830
2831 if (attrs != null) {
2832 mPolicy.adjustWindowParamsLw(attrs);
2833 }
Romain Guy06882f82009-06-10 13:36:04 -07002834
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002835 winAnimator.mSurfaceDestroyDeferred =
Jeff Brown98365d72012-08-19 20:30:52 -07002836 (flags&WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002837
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002838 int attrChanges = 0;
2839 int flagChanges = 0;
2840 if (attrs != null) {
Dianne Hackborn0e60db22011-09-01 11:17:57 -07002841 if (win.mAttrs.type != attrs.type) {
2842 throw new IllegalArgumentException(
2843 "Window type can not be changed after the window is added.");
2844 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002845 flagChanges = win.mAttrs.flags ^= attrs.flags;
2846 attrChanges = win.mAttrs.copyFrom(attrs);
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002847 if ((attrChanges & (WindowManager.LayoutParams.LAYOUT_CHANGED
2848 | WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED)) != 0) {
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08002849 win.mLayoutNeeded = true;
2850 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002851 }
2852
Dianne Hackborn7ff30112012-11-08 11:12:09 -08002853 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": viewVisibility=" + viewVisibility
Chet Haased5d11af2012-10-31 08:57:17 -07002854 + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002855
Adam Lesinski95c42972013-10-02 10:13:27 -07002856 win.mEnforceSizeCompat =
2857 (win.mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07002858
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002859 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002860 winAnimator.mAlpha = attrs.alpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002861 }
2862
2863 final boolean scaledWindow =
2864 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2865
2866 if (scaledWindow) {
2867 // requested{Width|Height} Surface's physical size
2868 // attrs.{width|height} Size on screen
2869 win.mHScale = (attrs.width != requestedWidth) ?
2870 (attrs.width / (float)requestedWidth) : 1.0f;
2871 win.mVScale = (attrs.height != requestedHeight) ?
2872 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002873 } else {
2874 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002875 }
2876
Craig Mautner65d11b32012-10-01 13:59:52 -07002877 boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002878
Craig Mautner69b08182012-09-05 13:07:13 -07002879 final boolean isDefaultDisplay = win.isDefaultDisplay();
2880 boolean focusMayChange = isDefaultDisplay && (win.mViewVisibility != viewVisibility
Craig Mautner65d11b32012-10-01 13:59:52 -07002881 || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0)
Craig Mautner69b08182012-09-05 13:07:13 -07002882 || (!win.mRelayoutCalled));
Romain Guy06882f82009-06-10 13:36:04 -07002883
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002884 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2885 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07002886 wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002887
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002888 win.mRelayoutCalled = true;
2889 final int oldVisibility = win.mViewVisibility;
2890 win.mViewVisibility = viewVisibility;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07002891 if (DEBUG_SCREEN_ON) {
2892 RuntimeException stack = new RuntimeException();
2893 stack.fillInStackTrace();
2894 Slog.i(TAG, "Relayout " + win + ": oldVis=" + oldVisibility
2895 + " newVis=" + viewVisibility, stack);
2896 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002897 if (viewVisibility == View.VISIBLE &&
2898 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07002899 toBeDisplayed = !win.isVisibleLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002900 if (win.mExiting) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002901 winAnimator.cancelExitAnimationForNextAnimationLocked();
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002902 win.mExiting = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002903 }
2904 if (win.mDestroying) {
2905 win.mDestroying = false;
2906 mDestroySurface.remove(win);
2907 }
2908 if (oldVisibility == View.GONE) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002909 winAnimator.mEnterAnimationPending = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002910 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002911 if (toBeDisplayed) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07002912 if (win.isDrawnLw() && okToDisplay()) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002913 winAnimator.applyEnterAnimationLocked();
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002914 }
2915 if ((win.mAttrs.flags
2916 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2917 if (DEBUG_VISIBILITY) Slog.v(TAG,
2918 "Relayout window turning screen on: " + win);
2919 win.mTurnOnScreen = true;
2920 }
Craig Mautnera3f4bf52012-10-10 20:37:48 -07002921 if (win.isConfigChanged()) {
2922 if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + win
Craig Mautnere8552142012-11-07 13:55:47 -08002923 + " visible with new config: " + mCurConfiguration);
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002924 outConfig.setTo(mCurConfiguration);
2925 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002926 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002927 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2928 // To change the format, we need to re-build the surface.
Craig Mautner96868332012-12-04 14:29:11 -08002929 winAnimator.destroySurfaceLocked();
Craig Mautnerbf08af32012-05-16 19:43:42 -07002930 toBeDisplayed = true;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002931 surfaceChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002932 }
2933 try {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002934 if (!win.mHasSurface) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002935 surfaceChanged = true;
2936 }
Mathias Agopian29479eb2013-02-14 14:36:04 -08002937 SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
2938 if (surfaceControl != null) {
2939 outSurface.copyFrom(surfaceControl);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002940 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002941 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002942 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002943 // For some reason there isn't a surface. Clear the
2944 // caller's object so they see the same state.
2945 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002946 }
2947 } catch (Exception e) {
Jeff Brown2e44b072011-01-24 15:21:56 -08002948 mInputMonitor.updateInputWindowsLw(true /*force*/);
Craig Mautner9e809442012-06-22 17:13:04 -07002949
Joe Onorato8a9b2202010-02-26 18:56:32 -08002950 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002951 + client + " (" + win.mAttrs.getTitle() + ")",
2952 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002953 Binder.restoreCallingIdentity(origId);
2954 return 0;
2955 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002956 if (toBeDisplayed) {
Craig Mautner69b08182012-09-05 13:07:13 -07002957 focusMayChange = isDefaultDisplay;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002958 }
2959 if (win.mAttrs.type == TYPE_INPUT_METHOD
2960 && mInputMethodWindow == null) {
2961 mInputMethodWindow = win;
2962 imMayMove = true;
2963 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002964 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2965 && win.mAppToken != null
2966 && win.mAppToken.startingWindow != null) {
2967 // Special handling of starting window over the base
2968 // window of the app: propagate lock screen flags to it,
2969 // to provide the correct semantics while starting.
2970 final int mask =
2971 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002972 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2973 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002974 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2975 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2976 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002977 } else {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002978 winAnimator.mEnterAnimationPending = false;
Mathias Agopian29479eb2013-02-14 14:36:04 -08002979 if (winAnimator.mSurfaceControl != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002980 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Craig Mautnerbf08af32012-05-16 19:43:42 -07002981 + ": mExiting=" + win.mExiting);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002982 // If we are not currently running the exit animation, we
2983 // need to see about starting one.
Craig Mautnerbf08af32012-05-16 19:43:42 -07002984 if (!win.mExiting) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002985 surfaceChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002986 // Try starting an animation; if there isn't one, we
2987 // can destroy the surface right away.
2988 int transit = WindowManagerPolicy.TRANSIT_EXIT;
Craig Mautnerbb1449b2012-03-23 16:11:14 -07002989 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002990 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2991 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002992 if (win.isWinVisibleLw() &&
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002993 winAnimator.applyAnimationLocked(transit, false)) {
Craig Mautner69b08182012-09-05 13:07:13 -07002994 focusMayChange = isDefaultDisplay;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002995 win.mExiting = true;
Craig Mautnera2c77052012-03-26 12:14:43 -07002996 } else if (win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002997 // Currently in a hide animation... turn this into
2998 // an exit.
2999 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07003000 } else if (win == mWallpaperTarget) {
3001 // If the wallpaper is currently behind this
3002 // window, we need to change both of them inside
3003 // of a transaction to avoid artifacts.
3004 win.mExiting = true;
Craig Mautnera2c77052012-03-26 12:14:43 -07003005 win.mWinAnimator.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003006 } else {
3007 if (mInputMethodWindow == win) {
3008 mInputMethodWindow = null;
3009 }
Craig Mautner96868332012-12-04 14:29:11 -08003010 winAnimator.destroySurfaceLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003011 }
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003012 //TODO (multidisplay): Magnification is supported only for the default
Svetoslav8e3feb12014-02-24 13:46:47 -08003013 if (mAccessibilityController != null
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003014 && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
Svetoslav8e3feb12014-02-24 13:46:47 -08003015 mAccessibilityController.onWindowTransitionLocked(win, transit);
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07003016 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003017 }
3018 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003019
Craig Mautnerbf08af32012-05-16 19:43:42 -07003020 outSurface.release();
3021 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003022 }
3023
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003024 if (focusMayChange) {
3025 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
Jeff Brown3a22cd92011-01-21 13:59:04 -08003026 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
3027 false /*updateInputWindows*/)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003028 imMayMove = false;
3029 }
3030 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
3031 }
Romain Guy06882f82009-06-10 13:36:04 -07003032
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08003033 // updateFocusedWindowLocked() already assigned layers so we only need to
3034 // reassign them at this point if the IM window state gets shuffled
Craig Mautnerb5eb5502013-01-10 17:29:30 -08003035 if (imMayMove && (moveInputMethodWindowsIfNeededLocked(false) || toBeDisplayed)) {
3036 // Little hack here -- we -should- be able to rely on the
3037 // function to return true if the IME has moved and needs
3038 // its layer recomputed. However, if the IME was hidden
3039 // and isn't actually moved in the list, its layer may be
3040 // out of data so we make sure to recompute it.
3041 assignLayersLocked(win.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003042 }
Craig Mautnerb5eb5502013-01-10 17:29:30 -08003043
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003044 if (wallpaperMayMove) {
Craig Mautnerae446592012-12-06 19:05:05 -08003045 getDefaultDisplayContentLocked().pendingLayoutChanges |=
3046 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003047 }
Romain Guy06882f82009-06-10 13:36:04 -07003048
Craig Mautnerdf88d732014-01-27 09:21:32 -08003049 final DisplayContent displayContent = win.getDisplayContent();
3050 if (displayContent != null) {
3051 displayContent.layoutNeeded = true;
3052 }
Jeff Brown98365d72012-08-19 20:30:52 -07003053 win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003054 configChanged = updateOrientationFromAppTokensLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003055 performLayoutAndPlaceSurfacesLocked();
Craig Mautnerbf08af32012-05-16 19:43:42 -07003056 if (toBeDisplayed && win.mIsWallpaper) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003057 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Jeff Brownfa25bf52012-07-23 19:26:30 -07003058 updateWallpaperOffsetLocked(win,
John Spurlockef4adae2013-08-26 17:58:58 -04003059 displayInfo.logicalWidth, displayInfo.logicalHeight, false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07003060 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003061 if (win.mAppToken != null) {
3062 win.mAppToken.updateReportedVisibilityLocked();
3063 }
Dianne Hackbornffb3d932011-05-17 17:44:51 -07003064 outFrame.set(win.mCompatFrame);
Dianne Hackbornc4aad012013-02-22 15:05:25 -08003065 outOverscanInsets.set(win.mOverscanInsets);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003066 outContentInsets.set(win.mContentInsets);
3067 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003068 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003069 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07003070 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003071 + ", requestedHeight=" + requestedHeight
3072 + ", viewVisibility=" + viewVisibility
3073 + "\nRelayout returning frame=" + outFrame
3074 + ", surface=" + outSurface);
3075
Joe Onorato8a9b2202010-02-26 18:56:32 -08003076 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003077 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
3078
3079 inTouchMode = mInTouchMode;
Dianne Hackborn021d2432013-10-13 15:20:09 -07003080 animating = mAnimator.mAnimating && win.mWinAnimator.isAnimating();
Dianne Hackborn12d3a942012-04-27 14:16:30 -07003081 if (animating && !mRelayoutWhileAnimating.contains(win)) {
3082 mRelayoutWhileAnimating.add(win);
3083 }
3084
Jeff Brown2e44b072011-01-24 15:21:56 -08003085 mInputMonitor.updateInputWindowsLw(true /*force*/);
Chet Haased5d11af2012-10-31 08:57:17 -07003086
3087 if (DEBUG_LAYOUT) {
3088 Slog.v(TAG, "Relayout complete " + win + ": outFrame=" + outFrame.toShortString());
3089 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003090 }
3091
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003092 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003093 sendNewConfiguration();
3094 }
Romain Guy06882f82009-06-10 13:36:04 -07003095
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003096 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07003097
Jeff Brown98365d72012-08-19 20:30:52 -07003098 return (inTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0)
3099 | (toBeDisplayed ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0)
3100 | (surfaceChanged ? WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED : 0)
3101 | (animating ? WindowManagerGlobal.RELAYOUT_RES_ANIMATING : 0);
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003102 }
3103
3104 public void performDeferredDestroyWindow(Session session, IWindow client) {
3105 long origId = Binder.clearCallingIdentity();
3106
3107 try {
Craig Mautnerae446592012-12-06 19:05:05 -08003108 synchronized (mWindowMap) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003109 WindowState win = windowForClientLocked(session, client, false);
3110 if (win == null) {
3111 return;
3112 }
Craig Mautner96868332012-12-04 14:29:11 -08003113 win.mWinAnimator.destroyDeferredSurfaceLocked();
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003114 }
3115 } finally {
3116 Binder.restoreCallingIdentity(origId);
3117 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003118 }
3119
Dianne Hackborn64825172011-03-02 21:32:58 -08003120 public boolean outOfMemoryWindow(Session session, IWindow client) {
3121 long origId = Binder.clearCallingIdentity();
3122
3123 try {
Craig Mautnerae446592012-12-06 19:05:05 -08003124 synchronized (mWindowMap) {
Dianne Hackborn64825172011-03-02 21:32:58 -08003125 WindowState win = windowForClientLocked(session, client, false);
3126 if (win == null) {
3127 return false;
3128 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003129 return reclaimSomeSurfaceMemoryLocked(win.mWinAnimator, "from-client", false);
Dianne Hackborn64825172011-03-02 21:32:58 -08003130 }
3131 } finally {
3132 Binder.restoreCallingIdentity(origId);
3133 }
3134 }
3135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003136 public void finishDrawingWindow(Session session, IWindow client) {
3137 final long origId = Binder.clearCallingIdentity();
Craig Mautneref655012013-01-03 11:20:24 -08003138 try {
3139 synchronized (mWindowMap) {
3140 WindowState win = windowForClientLocked(session, client, false);
3141 if (win != null && win.mWinAnimator.finishDrawingLocked()) {
3142 if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
3143 getDefaultDisplayContentLocked().pendingLayoutChanges |=
3144 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
3145 }
Craig Mautnerdf88d732014-01-27 09:21:32 -08003146 final DisplayContent displayContent = win.getDisplayContent();
3147 if (displayContent != null) {
3148 displayContent.layoutNeeded = true;
3149 }
Craig Mautneref655012013-01-03 11:20:24 -08003150 requestTraversalLocked();
Dianne Hackborn759a39e2009-08-09 17:20:27 -07003151 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003152 }
Craig Mautneref655012013-01-03 11:20:24 -08003153 } finally {
3154 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003155 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003156 }
3157
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003158 private boolean applyAnimationLocked(AppWindowToken atoken,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07003159 WindowManager.LayoutParams lp, int transit, boolean enter) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003160 // Only apply an animation if the display isn't frozen. If it is
3161 // frozen, there is no reason to animate and it can cause strange
3162 // artifacts when we unfreeze the display if some different animation
3163 // is running.
Craig Mautner2fb98b12012-03-20 17:24:00 -07003164 if (okToDisplay()) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003165 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Craig Mautner9339c402012-11-30 11:23:56 -08003166 final int width = displayInfo.appWidth;
3167 final int height = displayInfo.appHeight;
Craig Mautner164d4bb2012-11-26 13:51:23 -08003168 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "applyAnimation: atoken="
3169 + atoken);
Winson Chung399f6202014-03-19 10:47:20 -07003170
3171 // Determine the visible rect to calculate the thumbnail clip
3172 WindowState win = atoken.findMainWindow();
3173 Rect containingFrame = new Rect(0, 0, width, height);
3174 Rect contentInsets = new Rect();
3175 if (win != null) {
3176 if (win.mContainingFrame != null) {
3177 containingFrame.set(win.mContainingFrame);
3178 }
3179 if (win.mContentInsets != null) {
3180 contentInsets.set(win.mContentInsets);
3181 }
3182 }
3183
3184 Animation a = mAppTransition.loadAnimation(lp, transit, enter, width, height,
3185 containingFrame, contentInsets);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003186 if (a != null) {
3187 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003188 RuntimeException e = null;
3189 if (!HIDE_STACK_CRAWLS) {
3190 e = new RuntimeException();
3191 e.fillInStackTrace();
3192 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003193 Slog.v(TAG, "Loaded animation " + a + " for " + atoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003194 }
Craig Mautner9339c402012-11-30 11:23:56 -08003195 atoken.mAppAnimator.setAnimation(a, width, height);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003196 }
3197 } else {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003198 atoken.mAppAnimator.clearAnimation();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003199 }
3200
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003201 return atoken.mAppAnimator.animation != null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003202 }
3203
3204 // -------------------------------------------------------------
3205 // Application Window Tokens
3206 // -------------------------------------------------------------
3207
Craig Mautner00af9fe2013-03-25 09:13:41 -07003208 public void validateAppTokens(int stackId, List<TaskGroup> tasks) {
Craig Mautner343ad712013-02-13 22:37:26 -08003209 synchronized (mWindowMap) {
3210 int t = tasks.size() - 1;
3211 if (t < 0) {
3212 Slog.w(TAG, "validateAppTokens: empty task list");
Craig Mautnerb1fd65c2013-02-05 13:34:57 -08003213 return;
3214 }
3215
Craig Mautner343ad712013-02-13 22:37:26 -08003216 TaskGroup task = tasks.get(0);
3217 int taskId = task.taskId;
Craig Mautnerc00204b2013-03-05 15:02:14 -08003218 Task targetTask = mTaskIdToTask.get(taskId);
3219 DisplayContent displayContent = targetTask.getDisplayContent();
Craig Mautner343ad712013-02-13 22:37:26 -08003220 if (displayContent == null) {
3221 Slog.w(TAG, "validateAppTokens: no Display for taskId=" + taskId);
3222 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003223 }
Craig Mautnerb1fd65c2013-02-05 13:34:57 -08003224
Craig Mautner00af9fe2013-03-25 09:13:41 -07003225 final ArrayList<Task> localTasks = mStackIdToStack.get(stackId).getTasks();
Craig Mautnerf81b90872013-02-26 13:02:43 -08003226 int taskNdx;
3227 for (taskNdx = localTasks.size() - 1; taskNdx >= 0 && t >= 0; --taskNdx, --t) {
3228 AppTokenList localTokens = localTasks.get(taskNdx).mAppTokens;
Craig Mautner343ad712013-02-13 22:37:26 -08003229 task = tasks.get(t);
3230 List<IApplicationToken> tokens = task.tokens;
Craig Mautner343ad712013-02-13 22:37:26 -08003231
3232 DisplayContent lastDisplayContent = displayContent;
Craig Mautnerc00204b2013-03-05 15:02:14 -08003233 displayContent = mTaskIdToTask.get(taskId).getDisplayContent();
Craig Mautner343ad712013-02-13 22:37:26 -08003234 if (displayContent != lastDisplayContent) {
3235 Slog.w(TAG, "validateAppTokens: displayContent changed in TaskGroup list!");
3236 return;
3237 }
3238
Craig Mautnerf81b90872013-02-26 13:02:43 -08003239 int tokenNdx;
3240 int v;
3241 for (tokenNdx = localTokens.size() - 1, v = task.tokens.size() - 1;
3242 tokenNdx >= 0 && v >= 0; ) {
3243 final AppWindowToken atoken = localTokens.get(tokenNdx);
Craig Mautner343ad712013-02-13 22:37:26 -08003244 if (atoken.removed) {
Craig Mautnerf81b90872013-02-26 13:02:43 -08003245 --tokenNdx;
Craig Mautner343ad712013-02-13 22:37:26 -08003246 continue;
3247 }
3248 if (tokens.get(v) != atoken.token) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08003249 break;
Craig Mautner343ad712013-02-13 22:37:26 -08003250 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08003251 --tokenNdx;
Craig Mautner343ad712013-02-13 22:37:26 -08003252 v--;
3253 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08003254
3255 if (tokenNdx >= 0 || v >= 0) {
3256 break;
3257 }
Craig Mautner343ad712013-02-13 22:37:26 -08003258 }
3259
Craig Mautnerf81b90872013-02-26 13:02:43 -08003260 if (taskNdx >= 0 || t >= 0) {
Craig Mautner11bf9a52013-02-19 14:08:51 -08003261 Slog.w(TAG, "validateAppTokens: Mismatch! ActivityManager=" + tasks);
Craig Mautner1d001b62013-06-18 16:52:43 -07003262 Slog.w(TAG, "validateAppTokens: Mismatch! WindowManager=" + localTasks);
Craig Mautnerb44de0d2013-02-21 20:00:58 -08003263 Slog.w(TAG, "validateAppTokens: Mismatch! Callers=" + Debug.getCallers(4));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003264 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003265 }
3266 }
3267
Craig Mautner00af9fe2013-03-25 09:13:41 -07003268 public void validateStackOrder(Integer[] remoteStackIds) {
3269 // TODO:
3270 }
3271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003272 boolean checkCallingPermission(String permission, String func) {
3273 // Quick check: if the calling permission is me, it's all okay.
3274 if (Binder.getCallingPid() == Process.myPid()) {
3275 return true;
3276 }
Romain Guy06882f82009-06-10 13:36:04 -07003277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003278 if (mContext.checkCallingPermission(permission)
3279 == PackageManager.PERMISSION_GRANTED) {
3280 return true;
3281 }
3282 String msg = "Permission Denial: " + func + " from pid="
3283 + Binder.getCallingPid()
3284 + ", uid=" + Binder.getCallingUid()
3285 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003286 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003287 return false;
3288 }
Craig Mautner9e809442012-06-22 17:13:04 -07003289
Craig Mautner2fb98b12012-03-20 17:24:00 -07003290 boolean okToDisplay() {
3291 return !mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully();
3292 }
Romain Guy06882f82009-06-10 13:36:04 -07003293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003294 AppWindowToken findAppWindowToken(IBinder token) {
3295 WindowToken wtoken = mTokenMap.get(token);
3296 if (wtoken == null) {
3297 return null;
3298 }
3299 return wtoken.appWindowToken;
3300 }
Romain Guy06882f82009-06-10 13:36:04 -07003301
Craig Mautnercf8cbbe2012-03-25 21:54:36 -07003302 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003303 public void addWindowToken(IBinder token, int type) {
3304 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3305 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003306 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003307 }
Romain Guy06882f82009-06-10 13:36:04 -07003308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003309 synchronized(mWindowMap) {
3310 WindowToken wtoken = mTokenMap.get(token);
3311 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003312 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003313 return;
3314 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003315 wtoken = new WindowToken(this, token, type, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003316 mTokenMap.put(token, wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003317 if (type == TYPE_WALLPAPER) {
3318 mWallpaperTokens.add(wtoken);
3319 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003320 }
3321 }
Romain Guy06882f82009-06-10 13:36:04 -07003322
Craig Mautner9e809442012-06-22 17:13:04 -07003323 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003324 public void removeWindowToken(IBinder token) {
3325 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3326 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003327 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003328 }
3329
3330 final long origId = Binder.clearCallingIdentity();
3331 synchronized(mWindowMap) {
Craig Mautnerb1fd65c2013-02-05 13:34:57 -08003332 DisplayContent displayContent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003333 WindowToken wtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003334 if (wtoken != null) {
3335 boolean delayed = false;
3336 if (!wtoken.hidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003337 final int N = wtoken.windows.size();
3338 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003340 for (int i=0; i<N; i++) {
3341 WindowState win = wtoken.windows.get(i);
Craig Mautnerdf88d732014-01-27 09:21:32 -08003342 displayContent = win.getDisplayContent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003343
Craig Mautnera2c77052012-03-26 12:14:43 -07003344 if (win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003345 delayed = true;
3346 }
Romain Guy06882f82009-06-10 13:36:04 -07003347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003348 if (win.isVisibleNow()) {
Craig Mautner59c00972012-07-30 12:10:24 -07003349 win.mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT,
3350 false);
Svetoslav Ganov545252f2012-12-10 18:29:24 -08003351 //TODO (multidisplay): Magnification is supported only for the default
Svetoslav8e3feb12014-02-24 13:46:47 -08003352 if (mAccessibilityController != null && win.isDefaultDisplay()) {
3353 mAccessibilityController.onWindowTransitionLocked(win,
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07003354 WindowManagerPolicy.TRANSIT_EXIT);
3355 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003356 changed = true;
Craig Mautnerdf88d732014-01-27 09:21:32 -08003357 if (displayContent != null) {
3358 displayContent.layoutNeeded = true;
3359 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003360 }
3361 }
3362
Craig Mautner4b5aa782012-10-02 18:11:25 -07003363 wtoken.hidden = true;
3364
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003365 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003366 performLayoutAndPlaceSurfacesLocked();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003367 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
3368 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003369 }
Romain Guy06882f82009-06-10 13:36:04 -07003370
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003371 if (delayed) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08003372 if (displayContent != null) {
3373 displayContent.mExitingTokens.add(wtoken);
3374 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003375 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3376 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003377 }
3378 }
Romain Guy06882f82009-06-10 13:36:04 -07003379
Jeff Brown2e44b072011-01-24 15:21:56 -08003380 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003381 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003382 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003383 }
3384 }
3385 Binder.restoreCallingIdentity(origId);
3386 }
3387
Craig Mautner31482a72013-10-02 10:04:13 -07003388 private Task createTask(int taskId, int stackId, int userId, AppWindowToken atoken) {
Craig Mautner9ef471f2014-02-07 13:11:47 -08003389 if (DEBUG_STACK) Slog.i(TAG, "createTask: taskId=" + taskId + " stackId=" + stackId
3390 + " atoken=" + atoken);
Craig Mautner31482a72013-10-02 10:04:13 -07003391 final TaskStack stack = mStackIdToStack.get(stackId);
3392 if (stack == null) {
3393 throw new IllegalArgumentException("addAppToken: invalid stackId=" + stackId);
3394 }
Craig Mautner2c2549c2013-11-12 08:31:15 -08003395 EventLog.writeEvent(EventLogTags.WM_TASK_CREATED, taskId, stackId);
Craig Mautner31482a72013-10-02 10:04:13 -07003396 Task task = new Task(atoken, stack, userId);
Craig Mautner8e797342013-10-09 16:18:29 -07003397 mTaskIdToTask.put(taskId, task);
Craig Mautner31482a72013-10-02 10:04:13 -07003398 stack.addTask(task, true);
Craig Mautner31482a72013-10-02 10:04:13 -07003399 return task;
3400 }
3401
Craig Mautneref25d7a2012-05-15 23:01:47 -07003402 @Override
Craig Mautnerc00204b2013-03-05 15:02:14 -08003403 public void addAppToken(int addPos, IApplicationToken token, int taskId, int stackId,
Craig Mautner5d9f5472013-11-12 14:02:52 -08003404 int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId,
3405 int configChanges) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003406 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3407 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003408 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003409 }
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07003410
Jeff Brown349703e2010-06-22 01:27:15 -07003411 // Get the dispatching timeout here while we are not holding any locks so that it
3412 // can be cached by the AppWindowToken. The timeout value is used later by the
3413 // input dispatcher in code that does hold locks. If we did not cache the value
3414 // here we would run the chance of introducing a deadlock between the window manager
3415 // (which holds locks while updating the input dispatcher state) and the activity manager
3416 // (which holds locks while querying the application token).
3417 long inputDispatchingTimeoutNanos;
3418 try {
3419 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3420 } catch (RemoteException ex) {
3421 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3422 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3423 }
Romain Guy06882f82009-06-10 13:36:04 -07003424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003425 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003426 AppWindowToken atoken = findAppWindowToken(token.asBinder());
3427 if (atoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003428 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003429 return;
3430 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003431 atoken = new AppWindowToken(this, token);
3432 atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
Craig Mautnerb1fd65c2013-02-05 13:34:57 -08003433 atoken.groupId = taskId;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003434 atoken.appFullscreen = fullscreen;
Craig Mautner5962b122012-10-05 14:45:52 -07003435 atoken.showWhenLocked = showWhenLocked;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003436 atoken.requestedOrientation = requestedOrientation;
Craig Mautner4c5eb222013-11-18 12:59:05 -08003437 atoken.layoutConfigChanges = (configChanges &
3438 (ActivityInfo.CONFIG_SCREEN_SIZE | ActivityInfo.CONFIG_ORIENTATION)) != 0;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003439 if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + atoken
Craig Mautnerac6f8432013-07-17 13:24:59 -07003440 + " to stack=" + stackId + " task=" + taskId + " at " + addPos);
Craig Mautnerb1fd65c2013-02-05 13:34:57 -08003441
Craig Mautnerc00204b2013-03-05 15:02:14 -08003442 Task task = mTaskIdToTask.get(taskId);
3443 if (task == null) {
Craig Mautner42bf39e2014-02-21 16:46:22 -08003444 createTask(taskId, stackId, userId, atoken);
Craig Mautnerc00204b2013-03-05 15:02:14 -08003445 } else {
3446 task.addAppToken(addPos, atoken);
Craig Mautnerb1fd65c2013-02-05 13:34:57 -08003447 }
Craig Mautnerc00204b2013-03-05 15:02:14 -08003448
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003449 mTokenMap.put(token.asBinder(), atoken);
Romain Guy06882f82009-06-10 13:36:04 -07003450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003451 // Application tokens start out hidden.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003452 atoken.hidden = true;
3453 atoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003454
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003455 //dump();
3456 }
3457 }
Romain Guy06882f82009-06-10 13:36:04 -07003458
Craig Mautner9e809442012-06-22 17:13:04 -07003459 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003460 public void setAppGroupId(IBinder token, int groupId) {
3461 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner6fbda632012-07-03 09:26:39 -07003462 "setAppGroupId()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003463 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003464 }
3465
3466 synchronized(mWindowMap) {
Craig Mautner32b44d02013-02-21 08:26:06 -08003467 final AppWindowToken atoken = findAppWindowToken(token);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003468 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003469 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003470 return;
3471 }
Craig Mautnerdf88d732014-01-27 09:21:32 -08003472 final Task oldTask = mTaskIdToTask.get(atoken.groupId);
Craig Mautner9ef471f2014-02-07 13:11:47 -08003473 removeAppFromTaskLocked(atoken);
Craig Mautnerc00204b2013-03-05 15:02:14 -08003474
3475 atoken.groupId = groupId;
3476 Task newTask = mTaskIdToTask.get(groupId);
3477 if (newTask == null) {
Craig Mautner31482a72013-10-02 10:04:13 -07003478 newTask = createTask(groupId, oldTask.mStack.mStackId, oldTask.mUserId, atoken);
Yevgen Pronenkoc36a5b92014-02-19 10:33:07 +01003479 } else {
3480 newTask.mAppTokens.add(atoken);
Craig Mautner32b44d02013-02-21 08:26:06 -08003481 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003482 }
3483 }
Romain Guy06882f82009-06-10 13:36:04 -07003484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003485 public int getOrientationFromWindowsLocked() {
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003486 if (mDisplayFrozen || mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
3487 // If the display is frozen, some activities may be in the middle
3488 // of restarting, and thus have removed their old window. If the
3489 // window has the flag to hide the lock screen, then the lock screen
3490 // can re-appear and inflict its own orientation on us. Keep the
3491 // orientation stable until this all settles down.
3492 return mLastWindowForcedOrientation;
3493 }
3494
Craig Mautner59c00972012-07-30 12:10:24 -07003495 // TODO(multidisplay): Change to the correct display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003496 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07003497 int pos = windows.size() - 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003498 while (pos >= 0) {
Craig Mautnere8552142012-11-07 13:55:47 -08003499 WindowState win = windows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003500 pos--;
Craig Mautnere8552142012-11-07 13:55:47 -08003501 if (win.mAppToken != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003502 // We hit an application window. so the orientation will be determined by the
3503 // app window. No point in continuing further.
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003504 return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003505 }
Craig Mautnere8552142012-11-07 13:55:47 -08003506 if (!win.isVisibleLw() || !win.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003507 continue;
3508 }
Craig Mautnere8552142012-11-07 13:55:47 -08003509 int req = win.mAttrs.screenOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003510 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3511 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3512 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003513 }
Craig Mautner9e809442012-06-22 17:13:04 -07003514
Craig Mautnere8552142012-11-07 13:55:47 -08003515 if (DEBUG_ORIENTATION) Slog.v(TAG, win + " forcing orientation to " + req);
Craig Mautner9e809442012-06-22 17:13:04 -07003516 return (mLastWindowForcedOrientation=req);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003517 }
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003518 return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003519 }
Romain Guy06882f82009-06-10 13:36:04 -07003520
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003521 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003522 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3523 boolean findingBehind = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003524 boolean lastFullscreen = false;
Craig Mautnerb1fd65c2013-02-05 13:34:57 -08003525 // TODO: Multi window.
3526 DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautnerd9a22882013-03-16 15:00:36 -07003527 final ArrayList<Task> tasks = displayContent.getTasks();
Craig Mautnerf81b90872013-02-26 13:02:43 -08003528 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
3529 AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
Craig Mautnerd9a22882013-03-16 15:00:36 -07003530 final int firstToken = tokens.size() - 1;
3531 for (int tokenNdx = firstToken; tokenNdx >= 0; --tokenNdx) {
Craig Mautnerf81b90872013-02-26 13:02:43 -08003532 final AppWindowToken atoken = tokens.get(tokenNdx);
Craig Mautnerc5a6e442013-06-05 17:22:35 -07003533
Craig Mautnerf81b90872013-02-26 13:02:43 -08003534 if (DEBUG_APP_ORIENTATION) Slog.v(TAG, "Checking app orientation: " + atoken);
Craig Mautnerc5a6e442013-06-05 17:22:35 -07003535
Craig Mautnerf81b90872013-02-26 13:02:43 -08003536 // if we're about to tear down this window and not seek for
3537 // the behind activity, don't use it for orientation
3538 if (!findingBehind
3539 && (!atoken.hidden && atoken.hiddenRequested)) {
3540 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
3541 + " -- going to hide");
3542 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003543 }
Craig Mautnerc5a6e442013-06-05 17:22:35 -07003544
Craig Mautnerd9a22882013-03-16 15:00:36 -07003545 if (tokenNdx == firstToken) {
3546 // If we have hit a new Task, and the bottom
Craig Mautnerf81b90872013-02-26 13:02:43 -08003547 // of the previous group didn't explicitly say to use
3548 // the orientation behind it, and the last app was
3549 // full screen, then we'll stick with the
3550 // user's orientation.
3551 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3552 && lastFullscreen) {
3553 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
3554 + " -- end of group, return " + lastOrientation);
3555 return lastOrientation;
3556 }
3557 }
Craig Mautnerc5a6e442013-06-05 17:22:35 -07003558
Craig Mautnerf81b90872013-02-26 13:02:43 -08003559 // We ignore any hidden applications on the top.
3560 if (atoken.hiddenRequested || atoken.willBeHidden) {
3561 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
3562 + " -- hidden on top");
3563 continue;
3564 }
Craig Mautnerc5a6e442013-06-05 17:22:35 -07003565
Craig Mautnerd9a22882013-03-16 15:00:36 -07003566 if (tokenNdx == 0) {
3567 // Last token in this task.
Craig Mautnerf81b90872013-02-26 13:02:43 -08003568 lastOrientation = atoken.requestedOrientation;
3569 }
Craig Mautnerc5a6e442013-06-05 17:22:35 -07003570
Craig Mautnerf81b90872013-02-26 13:02:43 -08003571 int or = atoken.requestedOrientation;
3572 // If this application is fullscreen, and didn't explicitly say
3573 // to use the orientation behind it, then just take whatever
3574 // orientation it has and ignores whatever is under it.
3575 lastFullscreen = atoken.appFullscreen;
3576 if (lastFullscreen
3577 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3578 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
3579 + " -- full screen, return " + or);
3580 return or;
3581 }
3582 // If this application has requested an explicit orientation,
3583 // then use it.
3584 if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
3585 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3586 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
3587 + " -- explicitly set, return " + or);
3588 return or;
3589 }
3590 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003591 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003592 }
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003593 if (DEBUG_ORIENTATION) Slog.v(TAG, "No app is requesting an orientation");
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003594 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003595 }
Romain Guy06882f82009-06-10 13:36:04 -07003596
Craig Mautner711f90a2012-07-03 18:43:52 -07003597 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003598 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003599 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003600 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3601 "updateOrientationFromAppTokens()")) {
3602 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3603 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003604
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003605 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003606 long ident = Binder.clearCallingIdentity();
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003607
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003608 synchronized(mWindowMap) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003609 config = updateOrientationFromAppTokensLocked(currentConfig,
3610 freezeThisOneIfNeeded);
3611 }
3612
3613 Binder.restoreCallingIdentity(ident);
3614 return config;
3615 }
3616
3617 private Configuration updateOrientationFromAppTokensLocked(
3618 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
3619 Configuration config = null;
3620
3621 if (updateOrientationFromAppTokensLocked(false)) {
3622 if (freezeThisOneIfNeeded != null) {
Craig Mautner2268e7e2012-12-13 15:40:00 -08003623 AppWindowToken atoken = findAppWindowToken(freezeThisOneIfNeeded);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003624 if (atoken != null) {
Craig Mautner34b73df2014-01-12 21:11:08 -08003625 startAppFreezingScreenLocked(atoken);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003626 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003627 }
3628 config = computeNewConfigurationLocked();
3629
3630 } else if (currentConfig != null) {
3631 // No obvious action we need to take, but if our current
3632 // state mismatches the activity manager's, update it,
3633 // disregarding font scale, which should remain set to
3634 // the value of the previous configuration.
3635 mTempConfiguration.setToDefaults();
3636 mTempConfiguration.fontScale = currentConfig.fontScale;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08003637 if (computeScreenConfigurationLocked(mTempConfiguration)) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003638 if (currentConfig.diff(mTempConfiguration) != 0) {
3639 mWaitingForConfig = true;
Craig Mautner05d29032013-05-03 13:40:13 -07003640 final DisplayContent displayContent = getDefaultDisplayContentLocked();
3641 displayContent.layoutNeeded = true;
Craig Mautner3c174372013-02-21 17:54:37 -08003642 int anim[] = new int[2];
Craig Mautner05d29032013-05-03 13:40:13 -07003643 if (displayContent.isDimming()) {
Craig Mautner3c174372013-02-21 17:54:37 -08003644 anim[0] = anim[1] = 0;
3645 } else {
3646 mPolicy.selectRotationAnimationLw(anim);
3647 }
3648 startFreezingDisplayLocked(false, anim[0], anim[1]);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003649 config = new Configuration(mTempConfiguration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003650 }
3651 }
3652 }
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003653
Dianne Hackborncfaef692009-06-15 14:24:44 -07003654 return config;
3655 }
3656
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003657 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003658 * Determine the new desired orientation of the display, returning
3659 * a non-null new Configuration if it has changed from the current
3660 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3661 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3662 * SCREEN. This will typically be done for you if you call
3663 * sendNewConfiguration().
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003664 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003665 * The orientation is computed from non-application windows first. If none of
3666 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003667 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003668 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3669 * android.os.IBinder)
3670 */
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003671 boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003672 long ident = Binder.clearCallingIdentity();
3673 try {
Craig Mautner2268e7e2012-12-13 15:40:00 -08003674 int req = getOrientationFromWindowsLocked();
3675 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3676 req = getOrientationFromAppTokensLocked();
3677 }
Romain Guy06882f82009-06-10 13:36:04 -07003678
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003679 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003680 mForcedAppOrientation = req;
3681 //send a message to Policy indicating orientation change to take
3682 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003683 mPolicy.setCurrentOrientationLw(req);
Jeff Brown01a98dd2011-09-20 15:08:29 -07003684 if (updateRotationUncheckedLocked(inTransaction)) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003685 // changed
3686 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003687 }
3688 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003689
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003690 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003691 } finally {
3692 Binder.restoreCallingIdentity(ident);
3693 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003694 }
Romain Guy06882f82009-06-10 13:36:04 -07003695
Craig Mautner918b53b2012-07-09 14:15:54 -07003696 @Override
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003697 public void setNewConfiguration(Configuration config) {
3698 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3699 "setNewConfiguration()")) {
3700 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3701 }
3702
3703 synchronized(mWindowMap) {
3704 mCurConfiguration = new Configuration(config);
Dianne Hackborna57c6952013-03-29 14:46:40 -07003705 if (mWaitingForConfig) {
3706 mWaitingForConfig = false;
3707 mLastFinishedFreezeSource = "new-config";
3708 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003709 performLayoutAndPlaceSurfacesLocked();
3710 }
3711 }
Craig Mautner918b53b2012-07-09 14:15:54 -07003712
3713 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003714 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3715 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3716 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003717 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003718 }
Romain Guy06882f82009-06-10 13:36:04 -07003719
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003720 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003721 AppWindowToken atoken = findAppWindowToken(token.asBinder());
3722 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003723 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003724 return;
3725 }
Romain Guy06882f82009-06-10 13:36:04 -07003726
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003727 atoken.requestedOrientation = requestedOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003728 }
3729 }
Romain Guy06882f82009-06-10 13:36:04 -07003730
Craig Mautner76a71652012-09-03 23:23:58 -07003731 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003732 public int getAppOrientation(IApplicationToken token) {
3733 synchronized(mWindowMap) {
3734 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3735 if (wtoken == null) {
3736 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3737 }
Romain Guy06882f82009-06-10 13:36:04 -07003738
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003739 return wtoken.requestedOrientation;
3740 }
3741 }
Romain Guy06882f82009-06-10 13:36:04 -07003742
Craig Mautnerf7666462013-04-28 08:58:21 -07003743 /** Call while in a Surface transaction. */
3744 void setFocusedStackLayer() {
3745 mFocusedStackLayer = 0;
Craig Mautner05d29032013-05-03 13:40:13 -07003746 if (mFocusedApp != null) {
3747 final WindowList windows = mFocusedApp.allAppWindows;
3748 for (int i = windows.size() - 1; i >= 0; --i) {
3749 final WindowState win = windows.get(i);
3750 final int animLayer = win.mWinAnimator.mAnimLayer;
3751 if (win.mAttachedWindow == null && win.isVisibleLw() &&
3752 animLayer > mFocusedStackLayer) {
3753 mFocusedStackLayer = animLayer + LAYER_OFFSET_FOCUSED_STACK;
3754 }
Craig Mautnerf7666462013-04-28 08:58:21 -07003755 }
3756 }
3757 if (DEBUG_LAYERS) Slog.v(TAG, "Setting FocusedStackFrame to layer=" +
3758 mFocusedStackLayer);
3759 mFocusedStackFrame.setLayer(mFocusedStackLayer);
3760 }
3761
3762 void setFocusedStackFrame() {
3763 final TaskStack stack;
3764 if (mFocusedApp != null) {
3765 Task task = mTaskIdToTask.get(mFocusedApp.groupId);
3766 stack = task.mStack;
Craig Mautnerdf88d732014-01-27 09:21:32 -08003767 final DisplayContent displayContent = task.getDisplayContent();
3768 if (displayContent != null) {
3769 displayContent.setTouchExcludeRegion(stack);
3770 }
Craig Mautnerf7666462013-04-28 08:58:21 -07003771 } else {
3772 stack = null;
3773 }
Craig Mautnera9a3fb12013-04-18 10:01:00 -07003774 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setFocusedStackFrame");
3775 SurfaceControl.openTransaction();
3776 try {
3777 if (stack == null) {
3778 mFocusedStackFrame.setVisibility(false);
3779 } else {
Craig Mautnered6649f2013-12-02 14:08:25 -08003780 mFocusedStackFrame.setBounds(stack);
3781 final boolean multipleStacks = !stack.isFullscreen();
Craig Mautnera9a3fb12013-04-18 10:01:00 -07003782 mFocusedStackFrame.setVisibility(multipleStacks);
3783 }
3784 } finally {
3785 SurfaceControl.closeTransaction();
3786 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> CLOSE TRANSACTION setFocusedStackFrame");
3787 }
3788 }
3789
Craig Mautner76a71652012-09-03 23:23:58 -07003790 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003791 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3792 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3793 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003794 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003795 }
3796
3797 synchronized(mWindowMap) {
Craig Mautner42bf39e2014-02-21 16:46:22 -08003798 final AppWindowToken newFocus;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003799 if (token == null) {
Craig Mautner58458122013-09-14 14:59:50 -07003800 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
Craig Mautner42bf39e2014-02-21 16:46:22 -08003801 newFocus = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003802 } else {
Craig Mautner42bf39e2014-02-21 16:46:22 -08003803 newFocus = findAppWindowToken(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003804 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003805 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003806 }
Craig Mautner58458122013-09-14 14:59:50 -07003807 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Set focused app to: " + newFocus
3808 + " old focus=" + mFocusedApp + " moveFocusNow=" + moveFocusNow);
Craig Mautner42bf39e2014-02-21 16:46:22 -08003809 }
3810
3811 final boolean changed = mFocusedApp != newFocus;
3812 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003813 mFocusedApp = newFocus;
Craig Mautner42bf39e2014-02-21 16:46:22 -08003814 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003815 }
3816
3817 if (moveFocusNow && changed) {
3818 final long origId = Binder.clearCallingIdentity();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003819 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003820 Binder.restoreCallingIdentity(origId);
3821 }
3822 }
3823 }
3824
Craig Mautner76a71652012-09-03 23:23:58 -07003825 @Override
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003826 public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003827 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3828 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003829 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003830 }
Romain Guy06882f82009-06-10 13:36:04 -07003831
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003832 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003833 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003834 TAG, "Prepare app transition: transit=" + transit
Craig Mautner164d4bb2012-11-26 13:51:23 -08003835 + " " + mAppTransition
Craig Mautner1d961d42012-05-27 12:02:11 -07003836 + " alwaysKeepCurrent=" + alwaysKeepCurrent
Craig Mautneref25d7a2012-05-15 23:01:47 -07003837 + " Callers=" + Debug.getCallers(3));
Craig Mautner8e975be2013-09-21 16:12:13 -07003838 if (!mAppTransition.isTransitionSet() || mAppTransition.isTransitionNone()) {
3839 mAppTransition.setAppTransition(transit);
3840 } else if (!alwaysKeepCurrent) {
3841 if (transit == AppTransition.TRANSIT_TASK_OPEN
3842 && mAppTransition.isTransitionEqual(
3843 AppTransition.TRANSIT_TASK_CLOSE)) {
3844 // Opening a new task always supersedes a close for the anim.
Craig Mautner164d4bb2012-11-26 13:51:23 -08003845 mAppTransition.setAppTransition(transit);
Craig Mautner8e975be2013-09-21 16:12:13 -07003846 } else if (transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3847 && mAppTransition.isTransitionEqual(
3848 AppTransition.TRANSIT_ACTIVITY_CLOSE)) {
3849 // Opening a new activity always supersedes a close for the anim.
3850 mAppTransition.setAppTransition(transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003851 }
Craig Mautner8e975be2013-09-21 16:12:13 -07003852 }
3853 if (okToDisplay()) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003854 mAppTransition.prepare();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003855 mStartingIconInTransition = false;
3856 mSkipAppTransitionAnimation = false;
3857 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
You Kimcb6291c2012-12-04 23:22:28 +09003858 mH.sendEmptyMessageDelayed(H.APP_TRANSITION_TIMEOUT, 5000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003859 }
3860 }
3861 }
3862
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003863 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003864 public int getPendingAppTransition() {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003865 return mAppTransition.getAppTransition();
Dianne Hackborn84375872012-06-01 19:03:50 -07003866 }
3867
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003868 @Override
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003869 public void overridePendingAppTransition(String packageName,
Dianne Hackborn84375872012-06-01 19:03:50 -07003870 int enterAnim, int exitAnim, IRemoteCallback startedCallback) {
3871 synchronized(mWindowMap) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003872 mAppTransition.overridePendingAppTransition(packageName, enterAnim, exitAnim,
3873 startedCallback);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003874 }
3875 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003876
Craig Mautnera91f9e22012-09-14 16:22:08 -07003877 @Override
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003878 public void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
3879 int startHeight) {
Dianne Hackborn84375872012-06-01 19:03:50 -07003880 synchronized(mWindowMap) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003881 mAppTransition.overridePendingAppTransitionScaleUp(startX, startY, startWidth,
3882 startHeight);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003883 }
3884 }
3885
Craig Mautnera91f9e22012-09-14 16:22:08 -07003886 @Override
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003887 public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX,
Michael Jurka832cb222012-04-13 09:32:47 -07003888 int startY, IRemoteCallback startedCallback, boolean scaleUp) {
Dianne Hackborn84375872012-06-01 19:03:50 -07003889 synchronized(mWindowMap) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08003890 mAppTransition.overridePendingAppTransitionThumb(srcThumb, startX, startY,
3891 startedCallback, scaleUp);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003892 }
3893 }
3894
Craig Mautnera91f9e22012-09-14 16:22:08 -07003895 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003896 public void executeAppTransition() {
3897 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3898 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003899 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003900 }
Romain Guy06882f82009-06-10 13:36:04 -07003901
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003902 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003903 if (DEBUG_APP_TRANSITIONS) {
3904 RuntimeException e = new RuntimeException("here");
3905 e.fillInStackTrace();
Craig Mautner164d4bb2012-11-26 13:51:23 -08003906 Slog.w(TAG, "Execute app transition: " + mAppTransition, e);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003907 }
Craig Mautner164d4bb2012-11-26 13:51:23 -08003908 if (mAppTransition.isTransitionSet()) {
Craig Mautnerae446592012-12-06 19:05:05 -08003909 mAppTransition.setReady();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003910 final long origId = Binder.clearCallingIdentity();
3911 performLayoutAndPlaceSurfacesLocked();
3912 Binder.restoreCallingIdentity(origId);
3913 }
3914 }
3915 }
3916
Craig Mautnere6f7d502012-10-08 10:34:17 -07003917 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003918 public void setAppStartingWindow(IBinder token, String pkg,
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07003919 int theme, CompatibilityInfo compatInfo,
Adam Powell04fe6eb2013-05-31 14:39:48 -07003920 CharSequence nonLocalizedLabel, int labelRes, int icon, int logo,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003921 int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003922 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner6fbda632012-07-03 09:26:39 -07003923 "setAppStartingWindow()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003924 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003925 }
3926
3927 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003928 if (DEBUG_STARTING_WINDOW) Slog.v(
Craig Mautner8863cca2012-09-18 15:04:34 -07003929 TAG, "setAppStartingWindow: token=" + token + " pkg=" + pkg
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003930 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003931
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003932 AppWindowToken wtoken = findAppWindowToken(token);
3933 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003934 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003935 return;
3936 }
3937
3938 // If the display is frozen, we won't do anything until the
3939 // actual window is displayed so there is no reason to put in
3940 // the starting window.
Craig Mautner2fb98b12012-03-20 17:24:00 -07003941 if (!okToDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003942 return;
3943 }
Romain Guy06882f82009-06-10 13:36:04 -07003944
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003945 if (wtoken.startingData != null) {
3946 return;
3947 }
Romain Guy06882f82009-06-10 13:36:04 -07003948
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003949 if (transferFrom != null) {
3950 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3951 if (ttoken != null) {
3952 WindowState startingWindow = ttoken.startingWindow;
3953 if (startingWindow != null) {
3954 if (mStartingIconInTransition) {
3955 // In this case, the starting icon has already
3956 // been displayed, so start letting windows get
3957 // shown immediately without any more transitions.
3958 mSkipAppTransitionAnimation = true;
3959 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003960 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
Craig Mautner8863cca2012-09-18 15:04:34 -07003961 "Moving existing starting " + startingWindow + " from " + ttoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003962 + " to " + wtoken);
3963 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003964
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003965 // Transfer the starting window over to the new
3966 // token.
3967 wtoken.startingData = ttoken.startingData;
3968 wtoken.startingView = ttoken.startingView;
Craig Mautnerf4120952012-06-21 18:25:39 -07003969 wtoken.startingDisplayed = ttoken.startingDisplayed;
Craig Mautner8863cca2012-09-18 15:04:34 -07003970 ttoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003971 wtoken.startingWindow = startingWindow;
Craig Mautnerf4120952012-06-21 18:25:39 -07003972 wtoken.reportedVisible = ttoken.reportedVisible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003973 ttoken.startingData = null;
3974 ttoken.startingView = null;
3975 ttoken.startingWindow = null;
3976 ttoken.startingMoved = true;
3977 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003978 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003979 startingWindow.mAppToken = wtoken;
Craig Mautner8863cca2012-09-18 15:04:34 -07003980 startingWindow.mWinAnimator.mAppAnimator = wtoken.mAppAnimator;
3981
Craig Mautner6fbda632012-07-03 09:26:39 -07003982 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) {
3983 Slog.v(TAG, "Removing starting window: " + startingWindow);
3984 }
Craig Mautner59c00972012-07-30 12:10:24 -07003985 startingWindow.getWindowList().remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07003986 mWindowsChanged = true;
Craig Mautner6fbda632012-07-03 09:26:39 -07003987 if (DEBUG_ADD_REMOVE) Slog.v(TAG,
3988 "Removing starting " + startingWindow + " from " + ttoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003989 ttoken.windows.remove(startingWindow);
3990 ttoken.allAppWindows.remove(startingWindow);
3991 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003992
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003993 // Propagate other interesting state between the
3994 // tokens. If the old token is displayed, we should
3995 // immediately force the new one to be displayed. If
3996 // it is animating, we need to move that animation to
3997 // the new one.
3998 if (ttoken.allDrawn) {
3999 wtoken.allDrawn = true;
Craig Mautner7636dfb2012-11-16 15:24:11 -08004000 wtoken.deferClearAllDrawn = ttoken.deferClearAllDrawn;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004001 }
4002 if (ttoken.firstWindowDrawn) {
4003 wtoken.firstWindowDrawn = true;
4004 }
4005 if (!ttoken.hidden) {
4006 wtoken.hidden = false;
4007 wtoken.hiddenRequested = false;
4008 wtoken.willBeHidden = false;
4009 }
4010 if (wtoken.clientHidden != ttoken.clientHidden) {
4011 wtoken.clientHidden = ttoken.clientHidden;
4012 wtoken.sendAppVisibilityToClients();
4013 }
Craig Mautner59431632012-04-04 11:56:44 -07004014 final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
4015 final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
4016 if (tAppAnimator.animation != null) {
4017 wAppAnimator.animation = tAppAnimator.animation;
4018 wAppAnimator.animating = tAppAnimator.animating;
4019 wAppAnimator.animLayerAdjustment = tAppAnimator.animLayerAdjustment;
4020 tAppAnimator.animation = null;
4021 tAppAnimator.animLayerAdjustment = 0;
4022 wAppAnimator.updateLayers();
4023 tAppAnimator.updateLayers();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004024 }
Romain Guy06882f82009-06-10 13:36:04 -07004025
Jeff Brown3a22cd92011-01-21 13:59:04 -08004026 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4027 true /*updateInputWindows*/);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07004028 getDefaultDisplayContentLocked().layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004029 performLayoutAndPlaceSurfacesLocked();
4030 Binder.restoreCallingIdentity(origId);
4031 return;
4032 } else if (ttoken.startingData != null) {
4033 // The previous app was getting ready to show a
4034 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004035 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004036 "Moving pending starting from " + ttoken
4037 + " to " + wtoken);
4038 wtoken.startingData = ttoken.startingData;
4039 ttoken.startingData = null;
4040 ttoken.startingMoved = true;
4041 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
4042 // Note: we really want to do sendMessageAtFrontOfQueue() because we
4043 // want to process the message ASAP, before any other queued
4044 // messages.
4045 mH.sendMessageAtFrontOfQueue(m);
4046 return;
4047 }
Craig Mautner59431632012-04-04 11:56:44 -07004048 final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
4049 final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
4050 if (tAppAnimator.thumbnail != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004051 // The old token is animating with a thumbnail, transfer
4052 // that to the new token.
Craig Mautner59431632012-04-04 11:56:44 -07004053 if (wAppAnimator.thumbnail != null) {
4054 wAppAnimator.thumbnail.destroy();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004055 }
Craig Mautner59431632012-04-04 11:56:44 -07004056 wAppAnimator.thumbnail = tAppAnimator.thumbnail;
4057 wAppAnimator.thumbnailX = tAppAnimator.thumbnailX;
4058 wAppAnimator.thumbnailY = tAppAnimator.thumbnailY;
4059 wAppAnimator.thumbnailLayer = tAppAnimator.thumbnailLayer;
4060 wAppAnimator.thumbnailAnimation = tAppAnimator.thumbnailAnimation;
4061 tAppAnimator.thumbnail = null;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004062 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004063 }
4064 }
4065
4066 // There is no existing starting window, and the caller doesn't
4067 // want us to create one, so that's it!
4068 if (!createIfNeeded) {
4069 return;
4070 }
Romain Guy06882f82009-06-10 13:36:04 -07004071
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08004072 // If this is a translucent window, then don't
Dianne Hackborn284ac932009-08-28 10:34:25 -07004073 // show a starting window -- the current effect (a full-screen
4074 // opaque starting window that fades away to the real contents
4075 // when it is ready) does not work for this.
Craig Mautner6fbda632012-07-03 09:26:39 -07004076 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Checking theme of starting window: 0x"
4077 + Integer.toHexString(theme));
Dianne Hackborn284ac932009-08-28 10:34:25 -07004078 if (theme != 0) {
4079 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
Amith Yamasani4befbec2013-07-10 16:18:01 -07004080 com.android.internal.R.styleable.Window, mCurrentUserId);
Dianne Hackborn0b800192012-06-21 15:29:36 -07004081 if (ent == null) {
4082 // Whoops! App doesn't exist. Um. Okay. We'll just
4083 // pretend like we didn't see that.
4084 return;
4085 }
Craig Mautner6fbda632012-07-03 09:26:39 -07004086 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Translucent="
4087 + ent.array.getBoolean(
4088 com.android.internal.R.styleable.Window_windowIsTranslucent, false)
4089 + " Floating="
4090 + ent.array.getBoolean(
4091 com.android.internal.R.styleable.Window_windowIsFloating, false)
4092 + " ShowWallpaper="
4093 + ent.array.getBoolean(
4094 com.android.internal.R.styleable.Window_windowShowWallpaper, false));
Dianne Hackborn284ac932009-08-28 10:34:25 -07004095 if (ent.array.getBoolean(
4096 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
4097 return;
4098 }
4099 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07004100 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
4101 return;
4102 }
4103 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07004104 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08004105 if (mWallpaperTarget == null) {
4106 // If this theme is requesting a wallpaper, and the wallpaper
4107 // is not curently visible, then this effectively serves as
4108 // an opaque window and our starting window transition animation
4109 // can still work. We just need to make sure the starting window
4110 // is also showing the wallpaper.
Craig Mautner65d11b32012-10-01 13:59:52 -07004111 windowFlags |= FLAG_SHOW_WALLPAPER;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08004112 } else {
4113 return;
4114 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07004115 }
4116 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004117
Craig Mautner6fbda632012-07-03 09:26:39 -07004118 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Creating StartingData");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004119 mStartingIconInTransition = true;
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07004120 wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
Adam Powell04fe6eb2013-05-31 14:39:48 -07004121 labelRes, icon, logo, windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004122 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
4123 // Note: we really want to do sendMessageAtFrontOfQueue() because we
4124 // want to process the message ASAP, before any other queued
4125 // messages.
Craig Mautner6fbda632012-07-03 09:26:39 -07004126 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Enqueueing ADD_STARTING");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004127 mH.sendMessageAtFrontOfQueue(m);
4128 }
4129 }
4130
Craig Mautnera61bc652013-10-28 15:43:18 -07004131 public void removeAppStartingWindow(IBinder token) {
4132 synchronized (mWindowMap) {
4133 AppWindowToken wtoken = mTokenMap.get(token).appWindowToken;
4134 if (wtoken.startingWindow != null) {
4135 scheduleRemoveStartingWindow(wtoken);
4136 }
4137 }
4138 }
4139
Craig Mautner312eac42012-11-13 10:56:22 -08004140 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004141 public void setAppWillBeHidden(IBinder token) {
4142 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4143 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004144 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004145 }
4146
4147 AppWindowToken wtoken;
4148
4149 synchronized(mWindowMap) {
4150 wtoken = findAppWindowToken(token);
4151 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004152 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 -08004153 return;
4154 }
4155 wtoken.willBeHidden = true;
4156 }
4157 }
Romain Guy06882f82009-06-10 13:36:04 -07004158
Craig Mautner5eda9b32013-07-02 11:58:16 -07004159 public void setAppFullscreen(IBinder token, boolean toOpaque) {
Craig Mautner4addfc52013-06-25 08:05:45 -07004160 AppWindowToken atoken = findAppWindowToken(token);
4161 if (atoken != null) {
Craig Mautner5eda9b32013-07-02 11:58:16 -07004162 atoken.appFullscreen = toOpaque;
Craig Mautner71dd1b62014-02-18 15:48:52 -08004163 // When making translucent, wait until windows below have been drawn.
4164 if (toOpaque) {
4165 // Making opaque so do it now.
4166 setWindowOpaque(token, true);
4167 }
Craig Mautner5eda9b32013-07-02 11:58:16 -07004168 requestTraversal();
Craig Mautner4addfc52013-06-25 08:05:45 -07004169 }
4170 }
4171
Craig Mautner71dd1b62014-02-18 15:48:52 -08004172 public void setWindowOpaque(IBinder token, boolean isOpaque) {
4173 AppWindowToken wtoken = findAppWindowToken(token);
4174 if (wtoken != null) {
4175 WindowState win = wtoken.findMainWindow();
4176 if (win != null) {
4177 win.mWinAnimator.setOpaque(isOpaque);
4178 }
4179 }
4180 }
4181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004182 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004183 boolean visible, int transit, boolean performLayout) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004184 boolean delayed = false;
4185
4186 if (wtoken.clientHidden == visible) {
4187 wtoken.clientHidden = !visible;
4188 wtoken.sendAppVisibilityToClients();
4189 }
Romain Guy06882f82009-06-10 13:36:04 -07004190
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004191 wtoken.willBeHidden = false;
4192 if (wtoken.hidden == visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004193 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004194 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004195 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
4196 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07004197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004198 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07004199
Craig Mautner4b71aa12012-12-27 17:20:01 -08004200 if (transit != AppTransition.TRANSIT_UNSET) {
Craig Mautnerfbf378c2012-04-23 17:24:21 -07004201 if (wtoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) {
Craig Mautner59431632012-04-04 11:56:44 -07004202 wtoken.mAppAnimator.animation = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004203 }
Craig Mautnerf20588f2012-04-11 17:06:21 -07004204 if (applyAnimationLocked(wtoken, lp, transit, visible)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004205 delayed = runningAppAnimation = true;
4206 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07004207 WindowState window = wtoken.findMainWindow();
Svetoslav Ganov545252f2012-12-10 18:29:24 -08004208 //TODO (multidisplay): Magnification is supported only for the default display.
Svetoslav8e3feb12014-02-24 13:46:47 -08004209 if (window != null && mAccessibilityController != null
Svetoslav Ganov545252f2012-12-10 18:29:24 -08004210 && window.getDisplayId() == Display.DEFAULT_DISPLAY) {
Svetoslav8e3feb12014-02-24 13:46:47 -08004211 mAccessibilityController.onAppWindowTransitionLocked(window, transit);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07004212 }
Craig Mautnerf20588f2012-04-11 17:06:21 -07004213 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004214 }
Romain Guy06882f82009-06-10 13:36:04 -07004215
Craig Mautnerf20588f2012-04-11 17:06:21 -07004216 final int N = wtoken.allAppWindows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004217 for (int i=0; i<N; i++) {
4218 WindowState win = wtoken.allAppWindows.get(i);
4219 if (win == wtoken.startingWindow) {
4220 continue;
4221 }
4222
Joe Onorato8a9b2202010-02-26 18:56:32 -08004223 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004224 //win.dump(" ");
4225 if (visible) {
4226 if (!win.isVisibleNow()) {
4227 if (!runningAppAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07004228 win.mWinAnimator.applyAnimationLocked(
4229 WindowManagerPolicy.TRANSIT_ENTER, true);
Svetoslav Ganov545252f2012-12-10 18:29:24 -08004230 //TODO (multidisplay): Magnification is supported only for the default
Svetoslav8e3feb12014-02-24 13:46:47 -08004231 if (mAccessibilityController != null
Svetoslav Ganov545252f2012-12-10 18:29:24 -08004232 && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
Svetoslav8e3feb12014-02-24 13:46:47 -08004233 mAccessibilityController.onWindowTransitionLocked(win,
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07004234 WindowManagerPolicy.TRANSIT_ENTER);
4235 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004236 }
4237 changed = true;
Craig Mautnerdf88d732014-01-27 09:21:32 -08004238 final DisplayContent displayContent = win.getDisplayContent();
4239 if (displayContent != null) {
4240 displayContent.layoutNeeded = true;
4241 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004242 }
4243 } else if (win.isVisibleNow()) {
4244 if (!runningAppAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07004245 win.mWinAnimator.applyAnimationLocked(
4246 WindowManagerPolicy.TRANSIT_EXIT, false);
Svetoslav Ganov545252f2012-12-10 18:29:24 -08004247 //TODO (multidisplay): Magnification is supported only for the default
Svetoslav8e3feb12014-02-24 13:46:47 -08004248 if (mAccessibilityController != null
Svetoslav Ganov545252f2012-12-10 18:29:24 -08004249 && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
Svetoslav8e3feb12014-02-24 13:46:47 -08004250 mAccessibilityController.onWindowTransitionLocked(win,
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07004251 WindowManagerPolicy.TRANSIT_EXIT);
4252 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004253 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004254 changed = true;
Craig Mautnerdf88d732014-01-27 09:21:32 -08004255 final DisplayContent displayContent = win.getDisplayContent();
4256 if (displayContent != null) {
4257 displayContent.layoutNeeded = true;
4258 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004259 }
4260 }
4261
4262 wtoken.hidden = wtoken.hiddenRequested = !visible;
4263 if (!visible) {
4264 unsetAppFreezingScreenLocked(wtoken, true, true);
4265 } else {
4266 // If we are being set visible, and the starting window is
4267 // not yet displayed, then make sure it doesn't get displayed.
4268 WindowState swin = wtoken.startingWindow;
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07004269 if (swin != null && !swin.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004270 swin.mPolicyVisibility = false;
4271 swin.mPolicyVisibilityAfterAnim = false;
4272 }
4273 }
Romain Guy06882f82009-06-10 13:36:04 -07004274
Joe Onorato8a9b2202010-02-26 18:56:32 -08004275 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004276 + ": hidden=" + wtoken.hidden + " hiddenRequested="
4277 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07004278
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004279 if (changed) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08004280 mInputMonitor.setUpdateInputWindowsNeededLw();
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004281 if (performLayout) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08004282 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4283 false /*updateInputWindows*/);
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004284 performLayoutAndPlaceSurfacesLocked();
4285 }
Jeff Brown2e44b072011-01-24 15:21:56 -08004286 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004287 }
4288 }
4289
Craig Mautner59431632012-04-04 11:56:44 -07004290 if (wtoken.mAppAnimator.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004291 delayed = true;
4292 }
Romain Guy06882f82009-06-10 13:36:04 -07004293
Craig Mautnerf20588f2012-04-11 17:06:21 -07004294 for (int i = wtoken.allAppWindows.size() - 1; i >= 0 && !delayed; i--) {
4295 if (wtoken.allAppWindows.get(i).mWinAnimator.isWindowAnimating()) {
4296 delayed = true;
4297 }
4298 }
4299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004300 return delayed;
4301 }
4302
Craig Mautner312eac42012-11-13 10:56:22 -08004303 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004304 public void setAppVisibility(IBinder token, boolean visible) {
4305 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4306 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004307 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004308 }
4309
4310 AppWindowToken wtoken;
4311
4312 synchronized(mWindowMap) {
4313 wtoken = findAppWindowToken(token);
4314 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004315 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004316 return;
4317 }
4318
4319 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004320 RuntimeException e = null;
4321 if (!HIDE_STACK_CRAWLS) {
4322 e = new RuntimeException();
4323 e.fillInStackTrace();
4324 }
Craig Mautner0afddcb2012-05-08 15:38:00 -07004325 Slog.v(TAG, "setAppVisibility(" + token + ", visible=" + visible
Craig Mautner164d4bb2012-11-26 13:51:23 -08004326 + "): " + mAppTransition
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004327 + " hidden=" + wtoken.hidden
4328 + " hiddenRequested=" + wtoken.hiddenRequested, e);
4329 }
Romain Guy06882f82009-06-10 13:36:04 -07004330
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004331 // If we are preparing an app transition, then delay changing
4332 // the visibility of this token until we execute that transition.
Craig Mautner164d4bb2012-11-26 13:51:23 -08004333 if (okToDisplay() && mAppTransition.isTransitionSet()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004334 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07004335
Craig Mautnerf4120952012-06-21 18:25:39 -07004336 if (!wtoken.startingDisplayed) {
Craig Mautner8863cca2012-09-18 15:04:34 -07004337 if (DEBUG_APP_TRANSITIONS) Slog.v(
4338 TAG, "Setting dummy animation on: " + wtoken);
Craig Mautnerf4120952012-06-21 18:25:39 -07004339 wtoken.mAppAnimator.setDummyAnimation();
4340 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004341 mOpeningApps.remove(wtoken);
4342 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004343 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004344 wtoken.inPendingTransaction = true;
4345 if (visible) {
4346 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004347 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004348
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004349 // If the token is currently hidden (should be the
4350 // common case), then we need to set up to wait for
4351 // its windows to be ready.
4352 if (wtoken.hidden) {
4353 wtoken.allDrawn = false;
Craig Mautner7636dfb2012-11-16 15:24:11 -08004354 wtoken.deferClearAllDrawn = false;
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004355 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004356
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004357 if (wtoken.clientHidden) {
4358 // In the case where we are making an app visible
4359 // but holding off for a transition, we still need
4360 // to tell the client to make its windows visible so
4361 // they get drawn. Otherwise, we will wait on
4362 // performing the transition until all windows have
4363 // been drawn, they never will be, and we are sad.
4364 wtoken.clientHidden = false;
4365 wtoken.sendAppVisibilityToClients();
4366 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004367 }
4368 } else {
4369 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004370
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004371 // If the token is currently visible (should be the
4372 // common case), then set up to wait for it to be hidden.
4373 if (!wtoken.hidden) {
4374 wtoken.waitingToHide = true;
4375 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004376 }
4377 return;
4378 }
Romain Guy06882f82009-06-10 13:36:04 -07004379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004380 final long origId = Binder.clearCallingIdentity();
Craig Mautner4b71aa12012-12-27 17:20:01 -08004381 setTokenVisibilityLocked(wtoken, null, visible, AppTransition.TRANSIT_UNSET,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004382 true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004383 wtoken.updateReportedVisibilityLocked();
4384 Binder.restoreCallingIdentity(origId);
4385 }
4386 }
4387
4388 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
4389 boolean unfreezeSurfaceNow, boolean force) {
Craig Mautner59431632012-04-04 11:56:44 -07004390 if (wtoken.mAppAnimator.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004391 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004392 + " force=" + force);
4393 final int N = wtoken.allAppWindows.size();
4394 boolean unfrozeWindows = false;
4395 for (int i=0; i<N; i++) {
4396 WindowState w = wtoken.allAppWindows.get(i);
4397 if (w.mAppFreezing) {
4398 w.mAppFreezing = false;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07004399 if (w.mHasSurface && !w.mOrientationChanging) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07004400 if (DEBUG_ORIENTATION) Slog.v(TAG, "set mOrientationChanging of " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004401 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07004402 mInnerFields.mOrientationChangeComplete = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004403 }
Dianne Hackborna57c6952013-03-29 14:46:40 -07004404 w.mLastFreezeDuration = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004405 unfrozeWindows = true;
Craig Mautnerdf88d732014-01-27 09:21:32 -08004406 final DisplayContent displayContent = w.getDisplayContent();
4407 if (displayContent != null) {
4408 displayContent.layoutNeeded = true;
4409 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004410 }
4411 }
4412 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004413 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
Craig Mautner59431632012-04-04 11:56:44 -07004414 wtoken.mAppAnimator.freezingScreen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07004415 wtoken.mAppAnimator.lastFreezeDuration = (int)(SystemClock.elapsedRealtime()
4416 - mDisplayFreezeTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004417 mAppsFreezingScreen--;
Dianne Hackborna57c6952013-03-29 14:46:40 -07004418 mLastFinishedFreezeSource = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004419 }
4420 if (unfreezeSurfaceNow) {
4421 if (unfrozeWindows) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004422 performLayoutAndPlaceSurfacesLocked();
4423 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004424 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004425 }
4426 }
4427 }
Romain Guy06882f82009-06-10 13:36:04 -07004428
Craig Mautner34b73df2014-01-12 21:11:08 -08004429 private void startAppFreezingScreenLocked(AppWindowToken wtoken) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004430 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004431 RuntimeException e = null;
4432 if (!HIDE_STACK_CRAWLS) {
4433 e = new RuntimeException();
4434 e.fillInStackTrace();
4435 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004436 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004437 + ": hidden=" + wtoken.hidden + " freezing="
Craig Mautner59431632012-04-04 11:56:44 -07004438 + wtoken.mAppAnimator.freezingScreen, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004439 }
4440 if (!wtoken.hiddenRequested) {
Craig Mautner59431632012-04-04 11:56:44 -07004441 if (!wtoken.mAppAnimator.freezingScreen) {
4442 wtoken.mAppAnimator.freezingScreen = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -07004443 wtoken.mAppAnimator.lastFreezeDuration = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004444 mAppsFreezingScreen++;
4445 if (mAppsFreezingScreen == 1) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07004446 startFreezingDisplayLocked(false, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004447 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
You Kimcb6291c2012-12-04 23:22:28 +09004448 mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 5000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004449 }
4450 }
4451 final int N = wtoken.allAppWindows.size();
4452 for (int i=0; i<N; i++) {
4453 WindowState w = wtoken.allAppWindows.get(i);
4454 w.mAppFreezing = true;
4455 }
4456 }
4457 }
Romain Guy06882f82009-06-10 13:36:04 -07004458
Craig Mautner312eac42012-11-13 10:56:22 -08004459 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004460 public void startAppFreezingScreen(IBinder token, int configChanges) {
4461 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4462 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004463 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004464 }
4465
4466 synchronized(mWindowMap) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07004467 if (configChanges == 0 && okToDisplay()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004468 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004469 return;
4470 }
Romain Guy06882f82009-06-10 13:36:04 -07004471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004472 AppWindowToken wtoken = findAppWindowToken(token);
4473 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004474 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004475 return;
4476 }
4477 final long origId = Binder.clearCallingIdentity();
Craig Mautner34b73df2014-01-12 21:11:08 -08004478 startAppFreezingScreenLocked(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004479 Binder.restoreCallingIdentity(origId);
4480 }
4481 }
Romain Guy06882f82009-06-10 13:36:04 -07004482
Craig Mautner312eac42012-11-13 10:56:22 -08004483 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004484 public void stopAppFreezingScreen(IBinder token, boolean force) {
4485 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4486 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004487 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004488 }
4489
4490 synchronized(mWindowMap) {
4491 AppWindowToken wtoken = findAppWindowToken(token);
4492 if (wtoken == null || wtoken.appToken == null) {
4493 return;
4494 }
4495 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004496 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
Craig Mautner59431632012-04-04 11:56:44 -07004497 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.mAppAnimator.freezingScreen);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004498 unsetAppFreezingScreenLocked(wtoken, true, force);
4499 Binder.restoreCallingIdentity(origId);
4500 }
4501 }
Romain Guy06882f82009-06-10 13:36:04 -07004502
Craig Mautner9ef471f2014-02-07 13:11:47 -08004503 void removeAppFromTaskLocked(AppWindowToken wtoken) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08004504 final Task task = mTaskIdToTask.get(wtoken.groupId);
Craig Mautner312ba862014-02-10 17:55:01 -08004505 if (task != null) {
Craig Mautner42bf39e2014-02-21 16:46:22 -08004506 if (!task.removeAppToken(wtoken)) {
4507 Slog.e(TAG, "removeAppFromTaskLocked: token=" + wtoken + " not found.");
4508 }
Craig Mautnerdf88d732014-01-27 09:21:32 -08004509 }
4510 }
4511
Craig Mautnerae446592012-12-06 19:05:05 -08004512 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004513 public void removeAppToken(IBinder token) {
4514 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4515 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004516 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004517 }
4518
4519 AppWindowToken wtoken = null;
4520 AppWindowToken startingToken = null;
4521 boolean delayed = false;
4522
4523 final long origId = Binder.clearCallingIdentity();
4524 synchronized(mWindowMap) {
4525 WindowToken basewtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004526 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004527 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004528 delayed = setTokenVisibilityLocked(wtoken, null, false,
Craig Mautner4b71aa12012-12-27 17:20:01 -08004529 AppTransition.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004530 wtoken.inPendingTransaction = false;
4531 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004532 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004533 if (mClosingApps.contains(wtoken)) {
4534 delayed = true;
Craig Mautner164d4bb2012-11-26 13:51:23 -08004535 } else if (mAppTransition.isTransitionSet()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004536 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004537 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004538 delayed = true;
4539 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004540 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004541 TAG, "Removing app " + wtoken + " delayed=" + delayed
Craig Mautner59431632012-04-04 11:56:44 -07004542 + " animation=" + wtoken.mAppAnimator.animation
4543 + " animating=" + wtoken.mAppAnimator.animating);
Craig Mautner42bf39e2014-02-21 16:46:22 -08004544 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "removeAppToken: "
4545 + wtoken + " delayed=" + delayed + " Callers=" + Debug.getCallers(4));
Craig Mautnerdc548482014-02-05 13:35:24 -08004546 final TaskStack stack = mTaskIdToTask.get(wtoken.groupId).mStack;
4547 if (delayed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004548 // set the token aside because it has an active animation to be finished
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004549 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4550 "removeAppToken make exiting: " + wtoken);
Craig Mautnerdc548482014-02-05 13:35:24 -08004551 stack.mExitingAppTokens.add(wtoken);
Craig Mautner9ef471f2014-02-07 13:11:47 -08004552 wtoken.mDeferRemoval = true;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004553 } else {
4554 // Make sure there is no animation running on this token,
4555 // so any windows associated with it will be removed as
4556 // soon as their animations are complete
Craig Mautner59431632012-04-04 11:56:44 -07004557 wtoken.mAppAnimator.clearAnimation();
4558 wtoken.mAppAnimator.animating = false;
Craig Mautner9ef471f2014-02-07 13:11:47 -08004559 removeAppFromTaskLocked(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004560 }
Craig Mautnerdf88d732014-01-27 09:21:32 -08004561
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004562 wtoken.removed = true;
4563 if (wtoken.startingData != null) {
4564 startingToken = wtoken;
4565 }
4566 unsetAppFreezingScreenLocked(wtoken, true, true);
4567 if (mFocusedApp == wtoken) {
Craig Mautner58458122013-09-14 14:59:50 -07004568 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004569 mFocusedApp = null;
Jeff Brown3a22cd92011-01-21 13:59:04 -08004570 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004571 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004572 }
4573 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004574 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004575 }
Romain Guy06882f82009-06-10 13:36:04 -07004576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004577 if (!delayed && wtoken != null) {
4578 wtoken.updateReportedVisibilityLocked();
4579 }
4580 }
4581 Binder.restoreCallingIdentity(origId);
4582
Craig Mautner68cc2412013-10-01 10:39:43 -07004583 // Will only remove if startingToken non null.
4584 scheduleRemoveStartingWindow(startingToken);
4585 }
4586
Craig Mautner68cc2412013-10-01 10:39:43 -07004587 void scheduleRemoveStartingWindow(AppWindowToken wtoken) {
4588 if (wtoken != null && wtoken.startingWindow != null) {
4589 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, Debug.getCallers(1) +
4590 ": Schedule remove starting " + wtoken + (wtoken != null ?
4591 " startingWindow=" + wtoken.startingWindow : ""));
Craig Mautner68cc2412013-10-01 10:39:43 -07004592 Message m = mH.obtainMessage(H.REMOVE_STARTING, wtoken);
4593 mH.sendMessage(m);
4594 }
4595 }
Craig Mautnerdf88d732014-01-27 09:21:32 -08004596
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004597 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08004598 WindowList windows = token.windows;
4599 final int NW = windows.size();
Craig Mautneref25d7a2012-05-15 23:01:47 -07004600 if (NW > 0) {
4601 mWindowsChanged = true;
4602 }
Craig Mautnerdf88d732014-01-27 09:21:32 -08004603 for (int i = 0; i < NW; i++) {
4604 WindowState win = windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004605 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
Craig Mautner59c00972012-07-30 12:10:24 -07004606 win.getWindowList().remove(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004607 int j = win.mChildWindows.size();
4608 while (j > 0) {
4609 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004610 WindowState cwin = win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004611 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004612 "Tmp removing child window " + cwin);
Craig Mautner59c00972012-07-30 12:10:24 -07004613 cwin.getWindowList().remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004614 }
4615 }
4616 return NW > 0;
4617 }
4618
4619 void dumpAppTokensLocked() {
Craig Mautnerdc548482014-02-05 13:35:24 -08004620 final int numStacks = mStackIdToStack.size();
4621 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
4622 final TaskStack stack = mStackIdToStack.valueAt(stackNdx);
4623 Slog.v(TAG, " Stack #" + stack.mStackId + " tasks from bottom to top:");
4624 final ArrayList<Task> tasks = stack.getTasks();
4625 final int numTasks = tasks.size();
4626 for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
4627 final Task task = tasks.get(taskNdx);
4628 Slog.v(TAG, " Task #" + task.taskId + " activities from bottom to top:");
4629 AppTokenList tokens = task.mAppTokens;
4630 final int numTokens = tokens.size();
4631 for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
4632 Slog.v(TAG, " activity #" + tokenNdx + ": " + tokens.get(tokenNdx).token);
Craig Mautnerf81b90872013-02-26 13:02:43 -08004633 }
Craig Mautnerb1fd65c2013-02-05 13:34:57 -08004634 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004635 }
4636 }
Romain Guy06882f82009-06-10 13:36:04 -07004637
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004638 void dumpWindowsLocked() {
Craig Mautnerf8924152013-07-16 09:10:55 -07004639 final int numDisplays = mDisplayContents.size();
4640 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08004641 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
4642 Slog.v(TAG, " Display #" + displayContent.getDisplayId());
4643 final WindowList windows = displayContent.getWindowList();
Craig Mautnerf8924152013-07-16 09:10:55 -07004644 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08004645 Slog.v(TAG, " #" + winNdx + ": " + windows.get(winNdx));
Craig Mautnerf8924152013-07-16 09:10:55 -07004646 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004647 }
4648 }
Romain Guy06882f82009-06-10 13:36:04 -07004649
Craig Mautner926f3832013-02-13 11:56:07 -08004650 private int findAppWindowInsertionPointLocked(AppWindowToken target) {
4651 final int taskId = target.groupId;
Craig Mautnerc00204b2013-03-05 15:02:14 -08004652 Task targetTask = mTaskIdToTask.get(taskId);
4653 if (targetTask == null) {
4654 Slog.w(TAG, "findAppWindowInsertionPointLocked: no Task for " + target + " taskId="
4655 + taskId);
4656 return 0;
4657 }
4658 DisplayContent displayContent = targetTask.getDisplayContent();
Craig Mautner926f3832013-02-13 11:56:07 -08004659 if (displayContent == null) {
Craig Mautnerc00204b2013-03-05 15:02:14 -08004660 Slog.w(TAG, "findAppWindowInsertionPointLocked: no DisplayContent for " + target);
Craig Mautner926f3832013-02-13 11:56:07 -08004661 return 0;
4662 }
4663 final WindowList windows = displayContent.getWindowList();
4664 final int NW = windows.size();
4665
Craig Mautnerf81b90872013-02-26 13:02:43 -08004666 boolean found = false;
Craig Mautnerc00204b2013-03-05 15:02:14 -08004667 final ArrayList<Task> tasks = displayContent.getTasks();
Craig Mautnerf81b90872013-02-26 13:02:43 -08004668 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
Craig Mautnerc00204b2013-03-05 15:02:14 -08004669 final Task task = tasks.get(taskNdx);
Craig Mautnerf81b90872013-02-26 13:02:43 -08004670 if (!found && task.taskId != taskId) {
Craig Mautner926f3832013-02-13 11:56:07 -08004671 continue;
4672 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08004673 AppTokenList tokens = task.mAppTokens;
4674 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
4675 final AppWindowToken wtoken = tokens.get(tokenNdx);
4676 if (!found && wtoken == target) {
4677 found = true;
4678 }
4679 if (found) {
4680 // Find the first app token below the new position that has
4681 // a window displayed.
4682 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows in " + wtoken.token);
4683 if (wtoken.sendingToBottom) {
4684 if (DEBUG_REORDER) Slog.v(TAG, "Skipping token -- currently sending to bottom");
4685 continue;
4686 }
4687 for (int i = wtoken.windows.size() - 1; i >= 0; --i) {
4688 WindowState win = wtoken.windows.get(i);
4689 for (int j = win.mChildWindows.size() - 1; j >= 0; --j) {
4690 WindowState cwin = win.mChildWindows.get(j);
4691 if (cwin.mSubLayer >= 0) {
4692 for (int pos = NW - 1; pos >= 0; pos--) {
4693 if (windows.get(pos) == cwin) {
4694 if (DEBUG_REORDER) Slog.v(TAG,
4695 "Found child win @" + (pos + 1));
4696 return pos + 1;
4697 }
4698 }
4699 }
4700 }
Craig Mautner926f3832013-02-13 11:56:07 -08004701 for (int pos = NW - 1; pos >= 0; pos--) {
Craig Mautnerf81b90872013-02-26 13:02:43 -08004702 if (windows.get(pos) == win) {
4703 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos + 1));
Craig Mautner926f3832013-02-13 11:56:07 -08004704 return pos + 1;
4705 }
4706 }
4707 }
4708 }
Craig Mautner926f3832013-02-13 11:56:07 -08004709 }
4710 }
Craig Mautner7c495cb2013-10-13 23:19:45 +00004711 // Never put an app window underneath wallpaper.
4712 for (int pos = NW - 1; pos >= 0; pos--) {
4713 if (windows.get(pos).mIsWallpaper) {
4714 if (DEBUG_REORDER) Slog.v(TAG, "Found wallpaper @" + pos);
4715 return pos + 1;
4716 }
4717 }
Craig Mautner926f3832013-02-13 11:56:07 -08004718 return 0;
4719 }
4720
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004721 private final int reAddWindowLocked(int index, WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -07004722 final WindowList windows = win.getWindowList();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004723 final int NCW = win.mChildWindows.size();
4724 boolean added = false;
4725 for (int j=0; j<NCW; j++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004726 WindowState cwin = win.mChildWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004727 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004728 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004729 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004730 win.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004731 windows.add(index, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004732 index++;
4733 added = true;
4734 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004735 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004736 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004737 cwin.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004738 windows.add(index, cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004739 index++;
4740 }
4741 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004742 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004743 + index + ": " + win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004744 win.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004745 windows.add(index, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004746 index++;
4747 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004748 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004749 return index;
4750 }
Romain Guy06882f82009-06-10 13:36:04 -07004751
Craig Mautner59c00972012-07-30 12:10:24 -07004752 private final int reAddAppWindowsLocked(final DisplayContent displayContent, int index,
4753 WindowToken token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004754 final int NW = token.windows.size();
4755 for (int i=0; i<NW; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07004756 final WindowState win = token.windows.get(i);
Craig Mautnerdf88d732014-01-27 09:21:32 -08004757 final DisplayContent winDisplayContent = win.getDisplayContent();
4758 if (winDisplayContent == displayContent || winDisplayContent == null) {
4759 win.mDisplayContent = displayContent;
Craig Mautner69b08182012-09-05 13:07:13 -07004760 index = reAddWindowLocked(index, win);
Craig Mautner59c00972012-07-30 12:10:24 -07004761 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004762 }
4763 return index;
4764 }
4765
Craig Mautnerdf88d732014-01-27 09:21:32 -08004766 void tmpRemoveTaskWindowsLocked(Task task) {
4767 AppTokenList tokens = task.mAppTokens;
4768 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
4769 tmpRemoveAppWindowsLocked(tokens.get(tokenNdx));
4770 }
4771 }
4772
Craig Mautner77df2ee2013-10-24 12:47:07 -07004773 void moveStackWindowsLocked(DisplayContent displayContent) {
Craig Mautner926f3832013-02-13 11:56:07 -08004774 // First remove all of the windows from the list.
Craig Mautner77df2ee2013-10-24 12:47:07 -07004775 final ArrayList<Task> tasks = displayContent.getTasks();
Craig Mautner5457e612013-05-10 16:25:02 -07004776 final int numTasks = tasks.size();
4777 for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08004778 tmpRemoveTaskWindowsLocked(tasks.get(taskNdx));
Craig Mautner05d62722013-02-11 09:39:27 -08004779 }
Craig Mautner926f3832013-02-13 11:56:07 -08004780
4781 // And now add them back at the correct place.
4782 // Where to start adding?
Craig Mautner5457e612013-05-10 16:25:02 -07004783 for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
4784 AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
4785 int pos = findAppWindowInsertionPointLocked(tokens.get(0));
4786 final int numTokens = tokens.size();
4787 for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
4788 final AppWindowToken wtoken = tokens.get(tokenNdx);
4789 if (wtoken != null) {
4790 final int newPos = reAddAppWindowsLocked(displayContent, pos, wtoken);
4791 if (newPos != pos) {
4792 displayContent.layoutNeeded = true;
4793 }
4794 pos = newPos;
Craig Mautner926f3832013-02-13 11:56:07 -08004795 }
Craig Mautner926f3832013-02-13 11:56:07 -08004796 }
4797 }
Craig Mautner5457e612013-05-10 16:25:02 -07004798
Craig Mautner926f3832013-02-13 11:56:07 -08004799 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
Craig Mautnercf910b02013-04-23 11:23:27 -07004800 false /*updateInputWindows*/)) {
Craig Mautner926f3832013-02-13 11:56:07 -08004801 assignLayersLocked(displayContent.getWindowList());
4802 }
4803
Craig Mautner926f3832013-02-13 11:56:07 -08004804 mInputMonitor.setUpdateInputWindowsNeededLw();
4805 performLayoutAndPlaceSurfacesLocked();
4806 mInputMonitor.updateInputWindowsLw(false /*force*/);
4807
4808 //dump();
4809 }
4810
4811 public void moveTaskToTop(int taskId) {
4812 final long origId = Binder.clearCallingIdentity();
4813 try {
4814 synchronized(mWindowMap) {
Craig Mautnerc00204b2013-03-05 15:02:14 -08004815 Task task = mTaskIdToTask.get(taskId);
4816 if (task == null) {
Craig Mautner31482a72013-10-02 10:04:13 -07004817 // Normal behavior, addAppToken will be called next and task will be created.
Craig Mautnerc00204b2013-03-05 15:02:14 -08004818 return;
4819 }
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -07004820 final TaskStack stack = task.mStack;
4821 final DisplayContent displayContent = task.getDisplayContent();
Craig Mautnered6649f2013-12-02 14:08:25 -08004822 displayContent.moveStack(stack, true);
Craig Mautnere0a38842013-12-16 16:14:02 -08004823 if (displayContent.isDefaultDisplay) {
4824 final TaskStack homeStack = displayContent.getHomeStack();
4825 if (homeStack != stack) {
4826 // When a non-home stack moves to the top, the home stack moves to the
4827 // bottom.
4828 displayContent.moveStack(homeStack, false);
4829 }
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -07004830 }
4831 stack.moveTaskToTop(task);
Craig Mautner926f3832013-02-13 11:56:07 -08004832 }
4833 } finally {
4834 Binder.restoreCallingIdentity(origId);
4835 }
Craig Mautner05d62722013-02-11 09:39:27 -08004836 }
4837
4838 public void moveTaskToBottom(int taskId) {
Craig Mautner926f3832013-02-13 11:56:07 -08004839 final long origId = Binder.clearCallingIdentity();
4840 try {
4841 synchronized(mWindowMap) {
Craig Mautnerc00204b2013-03-05 15:02:14 -08004842 Task task = mTaskIdToTask.get(taskId);
4843 if (task == null) {
Craig Mautner926f3832013-02-13 11:56:07 -08004844 Slog.e(TAG, "moveTaskToBottom: taskId=" + taskId
Craig Mautnerc00204b2013-03-05 15:02:14 -08004845 + " not found in mTaskIdToTask");
Craig Mautner926f3832013-02-13 11:56:07 -08004846 return;
4847 }
Craig Mautner5457e612013-05-10 16:25:02 -07004848 final TaskStack stack = task.mStack;
4849 stack.moveTaskToBottom(task);
Craig Mautner77df2ee2013-10-24 12:47:07 -07004850 moveStackWindowsLocked(stack.getDisplayContent());
Craig Mautner926f3832013-02-13 11:56:07 -08004851 }
4852 } finally {
4853 Binder.restoreCallingIdentity(origId);
Craig Mautner05d62722013-02-11 09:39:27 -08004854 }
Craig Mautner05d62722013-02-11 09:39:27 -08004855 }
4856
Craig Mautnerc00204b2013-03-05 15:02:14 -08004857 /**
Craig Mautner93884a52014-01-10 13:28:10 -08004858 * Create a new TaskStack and place it on a DisplayContent.
Craig Mautnerc00204b2013-03-05 15:02:14 -08004859 * @param stackId The unique identifier of the new stack.
Craig Mautner93884a52014-01-10 13:28:10 -08004860 * @param displayId The unique identifier of the DisplayContent.
Craig Mautnerc00204b2013-03-05 15:02:14 -08004861 */
Craig Mautnerdf88d732014-01-27 09:21:32 -08004862 public void attachStack(int stackId, int displayId) {
Craig Mautner4504de52013-12-20 09:06:56 -08004863 final long origId = Binder.clearCallingIdentity();
4864 try {
4865 synchronized (mWindowMap) {
Craig Mautner93884a52014-01-10 13:28:10 -08004866 final DisplayContent displayContent = mDisplayContents.get(displayId);
4867 if (displayContent != null) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08004868 TaskStack stack = mStackIdToStack.get(stackId);
4869 if (stack == null) {
4870 if (DEBUG_STACK) Slog.d(TAG, "attachStack: stackId=" + stackId);
4871 stack = new TaskStack(this, stackId);
4872 mStackIdToStack.put(stackId, stack);
4873 }
4874 stack.attachDisplayContent(displayContent);
4875 displayContent.attachStack(stack);
4876 moveStackWindowsLocked(displayContent);
4877 final WindowList windows = displayContent.getWindowList();
4878 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
4879 windows.get(winNdx).reportResized();
4880 }
Craig Mautner4cd0c132013-04-16 15:55:52 -07004881 }
Craig Mautner967212c2013-04-13 21:10:58 -07004882 }
Craig Mautner4504de52013-12-20 09:06:56 -08004883 } finally {
4884 Binder.restoreCallingIdentity(origId);
Craig Mautnerc00204b2013-03-05 15:02:14 -08004885 }
4886 }
4887
Craig Mautner95da1082014-02-24 17:54:35 -08004888 void detachStackLocked(DisplayContent displayContent, TaskStack stack) {
4889 displayContent.detachStack(stack);
4890 stack.detachDisplay();
4891 }
4892
Craig Mautnerdf88d732014-01-27 09:21:32 -08004893 public void detachStack(int stackId) {
4894 synchronized (mWindowMap) {
4895 TaskStack stack = mStackIdToStack.get(stackId);
4896 if (stack != null) {
4897 final DisplayContent displayContent = stack.getDisplayContent();
4898 if (displayContent != null) {
Craig Mautner1bf2b872014-02-05 15:37:40 -08004899 if (stack.isAnimating()) {
Craig Mautner95da1082014-02-24 17:54:35 -08004900 stack.mDeferDetach = true;
Craig Mautner1bf2b872014-02-05 15:37:40 -08004901 return;
4902 }
Craig Mautner95da1082014-02-24 17:54:35 -08004903 detachStackLocked(displayContent, stack);
Craig Mautnerdf88d732014-01-27 09:21:32 -08004904 }
4905 }
4906 }
4907 }
4908
Craig Mautner95da1082014-02-24 17:54:35 -08004909 public void removeStack(int stackId) {
4910 mStackIdToStack.remove(stackId);
4911 }
4912
Craig Mautner9ef471f2014-02-07 13:11:47 -08004913 void removeTaskLocked(Task task) {
4914 final int taskId = task.taskId;
4915 final TaskStack stack = task.mStack;
4916 if (stack.isAnimating()) {
4917 if (DEBUG_STACK) Slog.i(TAG, "removeTask: deferring removing taskId=" + taskId);
4918 task.mDeferRemoval = true;
4919 return;
4920 }
4921 if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing taskId=" + taskId);
4922 EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, taskId, "removeTask");
4923 task.mDeferRemoval = false;
4924 task.mStack.removeTask(task);
4925 mTaskIdToTask.delete(task.taskId);
4926 }
4927
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07004928 public void removeTask(int taskId) {
Craig Mautnerc00204b2013-03-05 15:02:14 -08004929 synchronized (mWindowMap) {
4930 Task task = mTaskIdToTask.get(taskId);
Craig Mautner4cd0c132013-04-16 15:55:52 -07004931 if (task == null) {
Craig Mautner1d001b62013-06-18 16:52:43 -07004932 if (DEBUG_STACK) Slog.i(TAG, "removeTask: could not find taskId=" + taskId);
Craig Mautner4cd0c132013-04-16 15:55:52 -07004933 return;
4934 }
Craig Mautner9ef471f2014-02-07 13:11:47 -08004935 removeTaskLocked(task);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07004936 }
4937 }
Craig Mautner4cd0c132013-04-16 15:55:52 -07004938
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07004939 public void addTask(int taskId, int stackId, boolean toTop) {
4940 synchronized (mWindowMap) {
Craig Mautner9ef471f2014-02-07 13:11:47 -08004941 if (DEBUG_STACK) Slog.i(TAG, "addTask: adding taskId=" + taskId
4942 + " to " + (toTop ? "top" : "bottom"));
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07004943 Task task = mTaskIdToTask.get(taskId);
4944 if (task == null) {
4945 return;
4946 }
Craig Mautner4cd0c132013-04-16 15:55:52 -07004947 TaskStack stack = mStackIdToStack.get(stackId);
4948 stack.addTask(task, toTop);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07004949 final DisplayContent displayContent = stack.getDisplayContent();
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07004950 displayContent.layoutNeeded = true;
Craig Mautnerc00204b2013-03-05 15:02:14 -08004951 performLayoutAndPlaceSurfacesLocked();
4952 }
4953 }
4954
Craig Mautnered6649f2013-12-02 14:08:25 -08004955 public void resizeStack(int stackId, Rect bounds) {
Craig Mautnerc00204b2013-03-05 15:02:14 -08004956 synchronized (mWindowMap) {
Craig Mautnered6649f2013-12-02 14:08:25 -08004957 final TaskStack stack = mStackIdToStack.get(stackId);
4958 if (stack == null) {
4959 throw new IllegalArgumentException("resizeStack: stackId " + stackId
4960 + " not found.");
Craig Mautnerc00204b2013-03-05 15:02:14 -08004961 }
Craig Mautnered6649f2013-12-02 14:08:25 -08004962 if (stack.setBounds(bounds)) {
Craig Mautnerb660b9d2014-02-13 10:59:16 -08004963 stack.resizeWindows();
Craig Mautnered6649f2013-12-02 14:08:25 -08004964 stack.getDisplayContent().layoutNeeded = true;
4965 performLayoutAndPlaceSurfacesLocked();
4966 }
Craig Mautner5ff12102013-05-24 12:50:15 -07004967 }
4968 }
4969
Craig Mautnered6649f2013-12-02 14:08:25 -08004970 public void getStackBounds(int stackId, Rect bounds) {
4971 final TaskStack stack = mStackIdToStack.get(stackId);
4972 if (stack != null) {
4973 stack.getBounds(bounds);
4974 return;
Craig Mautner967212c2013-04-13 21:10:58 -07004975 }
Craig Mautnered6649f2013-12-02 14:08:25 -08004976 bounds.setEmpty();
Craig Mautner967212c2013-04-13 21:10:58 -07004977 }
4978
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004979 // -------------------------------------------------------------
4980 // Misc IWindowSession methods
4981 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004982
Craig Mautner5642a482012-08-23 12:16:53 -07004983 @Override
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07004984 public void startFreezingScreen(int exitAnim, int enterAnim) {
4985 if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
4986 "startFreezingScreen()")) {
4987 throw new SecurityException("Requires FREEZE_SCREEN permission");
4988 }
4989
4990 synchronized(mWindowMap) {
4991 if (!mClientFreezingScreen) {
4992 mClientFreezingScreen = true;
4993 final long origId = Binder.clearCallingIdentity();
4994 try {
4995 startFreezingDisplayLocked(false, exitAnim, enterAnim);
4996 mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
You Kimcb6291c2012-12-04 23:22:28 +09004997 mH.sendEmptyMessageDelayed(H.CLIENT_FREEZE_TIMEOUT, 5000);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07004998 } finally {
4999 Binder.restoreCallingIdentity(origId);
5000 }
5001 }
5002 }
5003 }
5004
5005 @Override
5006 public void stopFreezingScreen() {
5007 if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
5008 "stopFreezingScreen()")) {
5009 throw new SecurityException("Requires FREEZE_SCREEN permission");
5010 }
5011
5012 synchronized(mWindowMap) {
5013 if (mClientFreezingScreen) {
5014 mClientFreezingScreen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07005015 mLastFinishedFreezeSource = "client";
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07005016 final long origId = Binder.clearCallingIdentity();
5017 try {
5018 stopFreezingDisplayLocked();
5019 } finally {
5020 Binder.restoreCallingIdentity(origId);
5021 }
5022 }
5023 }
5024 }
5025
5026 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005027 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04005028 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005029 != PackageManager.PERMISSION_GRANTED) {
5030 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5031 }
Jim Millerd6b57052010-06-07 17:52:42 -07005032
Craig Mautner5642a482012-08-23 12:16:53 -07005033 mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage(
5034 KeyguardDisableHandler.KEYGUARD_DISABLE, new Pair<IBinder, String>(token, tag)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005035 }
5036
Craig Mautner5642a482012-08-23 12:16:53 -07005037 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005038 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04005039 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005040 != PackageManager.PERMISSION_GRANTED) {
5041 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5042 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005043
Craig Mautner5642a482012-08-23 12:16:53 -07005044 mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage(
5045 KeyguardDisableHandler.KEYGUARD_REENABLE, token));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005046 }
5047
5048 /**
5049 * @see android.app.KeyguardManager#exitKeyguardSecurely
5050 */
Craig Mautner2268e7e2012-12-13 15:40:00 -08005051 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005052 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
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 }
5057 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
Craig Mautner2268e7e2012-12-13 15:40:00 -08005058 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005059 public void onKeyguardExitResult(boolean success) {
5060 try {
5061 callback.onKeyguardExitResult(success);
5062 } catch (RemoteException e) {
5063 // Client has died, we don't care.
5064 }
5065 }
5066 });
5067 }
5068
Craig Mautner2268e7e2012-12-13 15:40:00 -08005069 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005070 public boolean inKeyguardRestrictedInputMode() {
5071 return mPolicy.inKeyguardRestrictedKeyInputMode();
5072 }
Romain Guy06882f82009-06-10 13:36:04 -07005073
Craig Mautner2268e7e2012-12-13 15:40:00 -08005074 @Override
Mike Lockwood520d8bc2011-02-18 13:23:13 -05005075 public boolean isKeyguardLocked() {
5076 return mPolicy.isKeyguardLocked();
5077 }
5078
Craig Mautner2268e7e2012-12-13 15:40:00 -08005079 @Override
Mike Lockwood520d8bc2011-02-18 13:23:13 -05005080 public boolean isKeyguardSecure() {
5081 return mPolicy.isKeyguardSecure();
5082 }
5083
Craig Mautner2268e7e2012-12-13 15:40:00 -08005084 @Override
Dianne Hackborn90c52de2011-09-23 12:57:44 -07005085 public void dismissKeyguard() {
5086 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
5087 != PackageManager.PERMISSION_GRANTED) {
5088 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5089 }
5090 synchronized(mWindowMap) {
5091 mPolicy.dismissKeyguardLw();
5092 }
5093 }
5094
Craig Mautner0bf6ec92012-12-18 08:33:27 -08005095 @Override
Dianne Hackbornffa42482009-09-23 22:20:11 -07005096 public void closeSystemDialogs(String reason) {
5097 synchronized(mWindowMap) {
Craig Mautnerf8924152013-07-16 09:10:55 -07005098 final int numDisplays = mDisplayContents.size();
5099 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
5100 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
5101 final int numWindows = windows.size();
5102 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
5103 final WindowState w = windows.get(winNdx);
5104 if (w.mHasSurface) {
5105 try {
5106 w.mClient.closeSystemDialogs(reason);
5107 } catch (RemoteException e) {
5108 }
Dianne Hackbornffa42482009-09-23 22:20:11 -07005109 }
5110 }
5111 }
5112 }
5113 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005115 static float fixScale(float scale) {
5116 if (scale < 0) scale = 0;
5117 else if (scale > 20) scale = 20;
5118 return Math.abs(scale);
5119 }
Romain Guy06882f82009-06-10 13:36:04 -07005120
Craig Mautner0bf6ec92012-12-18 08:33:27 -08005121 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005122 public void setAnimationScale(int which, float scale) {
5123 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
5124 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005125 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005126 }
5127
Cyril Mottier5f5882f2013-07-15 10:29:48 +02005128 scale = fixScale(scale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005129 switch (which) {
Cyril Mottier5f5882f2013-07-15 10:29:48 +02005130 case 0: mWindowAnimationScale = scale; break;
5131 case 1: mTransitionAnimationScale = scale; break;
5132 case 2: mAnimatorDurationScale = scale; break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005133 }
Romain Guy06882f82009-06-10 13:36:04 -07005134
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005135 // Persist setting
You Kimcb6291c2012-12-04 23:22:28 +09005136 mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005137 }
Romain Guy06882f82009-06-10 13:36:04 -07005138
Craig Mautner4b71aa12012-12-27 17:20:01 -08005139 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005140 public void setAnimationScales(float[] scales) {
5141 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
5142 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005143 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005144 }
5145
5146 if (scales != null) {
5147 if (scales.length >= 1) {
5148 mWindowAnimationScale = fixScale(scales[0]);
5149 }
5150 if (scales.length >= 2) {
5151 mTransitionAnimationScale = fixScale(scales[1]);
5152 }
Chet Haasec38fa1f2012-02-01 16:37:46 -08005153 if (scales.length >= 3) {
Jeff Brownff7e6ef2012-08-15 02:05:18 -07005154 setAnimatorDurationScale(fixScale(scales[2]));
Chet Haasec38fa1f2012-02-01 16:37:46 -08005155 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005156 }
Romain Guy06882f82009-06-10 13:36:04 -07005157
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005158 // Persist setting
You Kimcb6291c2012-12-04 23:22:28 +09005159 mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005160 }
Romain Guy06882f82009-06-10 13:36:04 -07005161
Jeff Brownff7e6ef2012-08-15 02:05:18 -07005162 private void setAnimatorDurationScale(float scale) {
5163 mAnimatorDurationScale = scale;
5164 ValueAnimator.setDurationScale(scale);
5165 }
5166
Craig Mautner4b71aa12012-12-27 17:20:01 -08005167 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005168 public float getAnimationScale(int which) {
5169 switch (which) {
5170 case 0: return mWindowAnimationScale;
5171 case 1: return mTransitionAnimationScale;
Chet Haasec38fa1f2012-02-01 16:37:46 -08005172 case 2: return mAnimatorDurationScale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005173 }
5174 return 0;
5175 }
Romain Guy06882f82009-06-10 13:36:04 -07005176
Craig Mautner4b71aa12012-12-27 17:20:01 -08005177 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005178 public float[] getAnimationScales() {
Chet Haasec38fa1f2012-02-01 16:37:46 -08005179 return new float[] { mWindowAnimationScale, mTransitionAnimationScale,
5180 mAnimatorDurationScale };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005181 }
Romain Guy06882f82009-06-10 13:36:04 -07005182
Craig Mautner037aa8d2013-06-07 10:35:44 -07005183 @Override
5184 public void registerPointerEventListener(PointerEventListener listener) {
5185 mPointerEventDispatcher.registerInputEventListener(listener);
5186 }
5187
5188 @Override
5189 public void unregisterPointerEventListener(PointerEventListener listener) {
5190 mPointerEventDispatcher.unregisterInputEventListener(listener);
5191 }
5192
Jeff Brownac143512012-04-05 18:57:33 -07005193 // Called by window manager policy. Not exposed externally.
5194 @Override
5195 public int getLidState() {
Jeff Brownc458ce92012-04-30 14:58:40 -07005196 int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY,
5197 InputManagerService.SW_LID);
Jeff Brownac143512012-04-05 18:57:33 -07005198 if (sw > 0) {
Jeff Brown27fd3422012-04-09 11:05:16 -07005199 // Switch state: AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL.
Jeff Brownac143512012-04-05 18:57:33 -07005200 return LID_CLOSED;
Jeff Brown27fd3422012-04-09 11:05:16 -07005201 } else if (sw == 0) {
5202 // Switch state: AKEY_STATE_UP.
5203 return LID_OPEN;
Jeff Brownac143512012-04-05 18:57:33 -07005204 } else {
Jeff Brown27fd3422012-04-09 11:05:16 -07005205 // Switch state: AKEY_STATE_UNKNOWN.
Jeff Brownac143512012-04-05 18:57:33 -07005206 return LID_ABSENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005207 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005208 }
Romain Guy06882f82009-06-10 13:36:04 -07005209
Jeff Brownac143512012-04-05 18:57:33 -07005210 // Called by window manager policy. Not exposed externally.
5211 @Override
Jeff Browncf39bdf2012-05-18 14:41:19 -07005212 public void switchKeyboardLayout(int deviceId, int direction) {
5213 mInputManager.switchKeyboardLayout(deviceId, direction);
5214 }
5215
5216 // Called by window manager policy. Not exposed externally.
5217 @Override
Jeff Brown9a538ee2012-08-20 14:56:57 -07005218 public void shutdown(boolean confirm) {
5219 ShutdownThread.shutdown(mContext, confirm);
Jeff Brown7304c342012-05-11 18:42:42 -07005220 }
5221
5222 // Called by window manager policy. Not exposed externally.
5223 @Override
Jeff Brown9a538ee2012-08-20 14:56:57 -07005224 public void rebootSafeMode(boolean confirm) {
5225 ShutdownThread.rebootSafeMode(mContext, confirm);
Jeff Brown7304c342012-05-11 18:42:42 -07005226 }
5227
Amith Yamasani734983f2014-03-04 16:48:05 -08005228 public void updateRelatedUserIds(final int[] relatedUserIds) {
Craig Mautnerf1b67412012-09-19 13:18:29 -07005229 synchronized (mWindowMap) {
Amith Yamasani734983f2014-03-04 16:48:05 -08005230 mRelatedUserIds = relatedUserIds;
5231 }
5232 }
5233
5234 public void setCurrentUser(final int newUserId, final int[] relatedUserIds) {
5235 synchronized (mWindowMap) {
Craig Mautnerf1b67412012-09-19 13:18:29 -07005236 mCurrentUserId = newUserId;
Amith Yamasani734983f2014-03-04 16:48:05 -08005237 mRelatedUserIds = relatedUserIds;
Amith Yamasani4befbec2013-07-10 16:18:01 -07005238 mAppTransition.setCurrentUser(newUserId);
Craig Mautnerf1b67412012-09-19 13:18:29 -07005239 mPolicy.setCurrentUserLw(newUserId);
Craig Mautner88400d32012-09-30 12:35:45 -07005240
5241 // Hide windows that should not be seen by the new user.
Craig Mautnerf8924152013-07-16 09:10:55 -07005242 final int numDisplays = mDisplayContents.size();
5243 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
5244 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautnerdc548482014-02-05 13:35:24 -08005245 displayContent.switchUserStacks(newUserId);
Craig Mautner858d8a62013-04-23 17:08:34 -07005246 rebuildAppWindowListLocked(displayContent);
Craig Mautner88400d32012-09-30 12:35:45 -07005247 }
5248 performLayoutAndPlaceSurfacesLocked();
Craig Mautnerf1b67412012-09-19 13:18:29 -07005249 }
5250 }
5251
Amith Yamasani734983f2014-03-04 16:48:05 -08005252 /* Called by WindowState */
5253 boolean isRelatedToOrCurrentUserLocked(int userId) {
5254 if (userId == mCurrentUserId) return true;
5255 for (int i = 0; i < mRelatedUserIds.length; i++) {
5256 if (mRelatedUserIds[i] == userId) return true;
5257 }
5258 return false;
5259 }
5260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005261 public void enableScreenAfterBoot() {
5262 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005263 if (DEBUG_BOOT) {
5264 RuntimeException here = new RuntimeException("here");
5265 here.fillInStackTrace();
5266 Slog.i(TAG, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled
5267 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5268 + " mShowingBootMessages=" + mShowingBootMessages
5269 + " mSystemBooted=" + mSystemBooted, here);
5270 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005271 if (mSystemBooted) {
5272 return;
5273 }
5274 mSystemBooted = true;
Dianne Hackborn661cd522011-08-22 00:26:20 -07005275 hideBootMessagesLocked();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005276 // If the screen still doesn't come up after 30 seconds, give
5277 // up and turn it on.
You Kimcb6291c2012-12-04 23:22:28 +09005278 mH.sendEmptyMessageDelayed(H.BOOT_TIMEOUT, 30*1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005279 }
Romain Guy06882f82009-06-10 13:36:04 -07005280
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07005281 mPolicy.systemBooted();
5282
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005283 performEnableScreen();
5284 }
Romain Guy06882f82009-06-10 13:36:04 -07005285
Dianne Hackborn661cd522011-08-22 00:26:20 -07005286 void enableScreenIfNeededLocked() {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005287 if (DEBUG_BOOT) {
5288 RuntimeException here = new RuntimeException("here");
5289 here.fillInStackTrace();
5290 Slog.i(TAG, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled
5291 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5292 + " mShowingBootMessages=" + mShowingBootMessages
5293 + " mSystemBooted=" + mSystemBooted, here);
5294 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005295 if (mDisplayEnabled) {
5296 return;
5297 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005298 if (!mSystemBooted && !mShowingBootMessages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005299 return;
5300 }
You Kimcb6291c2012-12-04 23:22:28 +09005301 mH.sendEmptyMessage(H.ENABLE_SCREEN);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005302 }
Romain Guy06882f82009-06-10 13:36:04 -07005303
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005304 public void performBootTimeout() {
5305 synchronized(mWindowMap) {
Mike Lockwooded8902d2013-11-15 11:01:47 -08005306 if (mDisplayEnabled) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005307 return;
5308 }
5309 Slog.w(TAG, "***** BOOT TIMEOUT: forcing display enabled");
5310 mForceDisplayEnabled = true;
5311 }
5312 performEnableScreen();
5313 }
5314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005315 public void performEnableScreen() {
5316 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005317 if (DEBUG_BOOT) {
5318 RuntimeException here = new RuntimeException("here");
5319 here.fillInStackTrace();
5320 Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
5321 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5322 + " mShowingBootMessages=" + mShowingBootMessages
Jeff Brown780c46f2012-06-24 12:15:38 -07005323 + " mSystemBooted=" + mSystemBooted
5324 + " mOnlyCore=" + mOnlyCore, here);
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005325 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005326 if (mDisplayEnabled) {
5327 return;
5328 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005329 if (!mSystemBooted && !mShowingBootMessages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005330 return;
5331 }
Romain Guy06882f82009-06-10 13:36:04 -07005332
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005333 if (!mForceDisplayEnabled) {
5334 // Don't enable the screen until all existing windows
5335 // have been drawn.
5336 boolean haveBootMsg = false;
5337 boolean haveApp = false;
Justin Mattson4233f262012-04-09 18:23:16 -07005338 // if the wallpaper service is disabled on the device, we're never going to have
5339 // wallpaper, don't bother waiting for it
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005340 boolean haveWallpaper = false;
Justin Mattson4233f262012-04-09 18:23:16 -07005341 boolean wallpaperEnabled = mContext.getResources().getBoolean(
Jeff Brown780c46f2012-06-24 12:15:38 -07005342 com.android.internal.R.bool.config_enableWallpaperService)
5343 && !mOnlyCore;
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005344 boolean haveKeyguard = true;
Craig Mautner59c00972012-07-30 12:10:24 -07005345 // TODO(multidisplay): Expand to all displays?
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005346 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07005347 final int N = windows.size();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005348 for (int i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07005349 WindowState w = windows.get(i);
Craig Mautner65d11b32012-10-01 13:59:52 -07005350 if (w.mAttrs.type == TYPE_KEYGUARD) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005351 // Only if there is a keyguard attached to the window manager
5352 // will we consider ourselves as having a keyguard. If it
5353 // isn't attached, we don't know if it wants to be shown or
5354 // hidden. If it is attached, we will say we have a keyguard
5355 // if the window doesn't want to be visible, because in that
5356 // case it explicitly doesn't want to be shown so we should
5357 // not delay turning the screen on for it.
5358 boolean vis = w.mViewVisibility == View.VISIBLE
5359 && w.mPolicyVisibility;
5360 haveKeyguard = !vis;
5361 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005362 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
5363 return;
5364 }
5365 if (w.isDrawnLw()) {
Craig Mautner65d11b32012-10-01 13:59:52 -07005366 if (w.mAttrs.type == TYPE_BOOT_PROGRESS) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005367 haveBootMsg = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005368 } else if (w.mAttrs.type == TYPE_APPLICATION) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005369 haveApp = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005370 } else if (w.mAttrs.type == TYPE_WALLPAPER) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005371 haveWallpaper = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005372 } else if (w.mAttrs.type == TYPE_KEYGUARD) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005373 haveKeyguard = true;
5374 }
5375 }
5376 }
5377
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005378 if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005379 Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
5380 + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
Justin Mattson4233f262012-04-09 18:23:16 -07005381 + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled
5382 + " haveKeyguard=" + haveKeyguard);
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005383 }
5384
5385 // If we are turning on the screen to show the boot message,
5386 // don't do it until the boot message is actually displayed.
5387 if (!mSystemBooted && !haveBootMsg) {
5388 return;
5389 }
Craig Mautner312eac42012-11-13 10:56:22 -08005390
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005391 // If we are turning on the screen after the boot is completed
5392 // normally, don't do so until we have the application and
5393 // wallpaper.
Justin Mattson4233f262012-04-09 18:23:16 -07005394 if (mSystemBooted && ((!haveApp && !haveKeyguard) ||
5395 (wallpaperEnabled && !haveWallpaper))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005396 return;
5397 }
5398 }
Romain Guy06882f82009-06-10 13:36:04 -07005399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005400 mDisplayEnabled = true;
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005401 if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005402 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005403 StringWriter sw = new StringWriter();
Dianne Hackborn8c841092013-06-24 13:46:13 -07005404 PrintWriter pw = new FastPrintWriter(sw, false, 1024);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005405 this.dump(null, pw, null);
Dianne Hackborn8c841092013-06-24 13:46:13 -07005406 pw.flush();
Joe Onorato8a9b2202010-02-26 18:56:32 -08005407 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005408 }
5409 try {
5410 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
5411 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005412 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005413 Parcel data = Parcel.obtain();
5414 data.writeInterfaceToken("android.ui.ISurfaceComposer");
Jeff Brownc042ee22012-05-08 13:03:42 -07005415 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005416 data, null, 0);
5417 data.recycle();
5418 }
5419 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005420 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005421 }
Jeff Brown08a746a2012-06-24 12:14:49 -07005422
5423 // Enable input dispatch.
5424 mInputMonitor.setEventDispatchingLw(mEventDispatchingEnabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005425 }
Romain Guy06882f82009-06-10 13:36:04 -07005426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005427 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07005428
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005429 // Make sure the last requested orientation has been applied.
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005430 updateRotationUnchecked(false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005431 }
Romain Guy06882f82009-06-10 13:36:04 -07005432
Dianne Hackborn661cd522011-08-22 00:26:20 -07005433 public void showBootMessage(final CharSequence msg, final boolean always) {
5434 boolean first = false;
5435 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005436 if (DEBUG_BOOT) {
5437 RuntimeException here = new RuntimeException("here");
5438 here.fillInStackTrace();
5439 Slog.i(TAG, "showBootMessage: msg=" + msg + " always=" + always
5440 + " mAllowBootMessages=" + mAllowBootMessages
5441 + " mShowingBootMessages=" + mShowingBootMessages
5442 + " mSystemBooted=" + mSystemBooted, here);
5443 }
Dianne Hackborn58f42a52011-10-10 13:46:34 -07005444 if (!mAllowBootMessages) {
5445 return;
5446 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005447 if (!mShowingBootMessages) {
5448 if (!always) {
5449 return;
5450 }
5451 first = true;
5452 }
5453 if (mSystemBooted) {
5454 return;
5455 }
5456 mShowingBootMessages = true;
5457 mPolicy.showBootMessage(msg, always);
5458 }
5459 if (first) {
5460 performEnableScreen();
5461 }
5462 }
5463
5464 public void hideBootMessagesLocked() {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005465 if (DEBUG_BOOT) {
5466 RuntimeException here = new RuntimeException("here");
5467 here.fillInStackTrace();
5468 Slog.i(TAG, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled
5469 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5470 + " mShowingBootMessages=" + mShowingBootMessages
5471 + " mSystemBooted=" + mSystemBooted, here);
5472 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005473 if (mShowingBootMessages) {
5474 mShowingBootMessages = false;
5475 mPolicy.hideBootMessages();
5476 }
5477 }
5478
Craig Mautner6cfa7292013-01-15 09:05:42 -08005479 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005480 public void setInTouchMode(boolean mode) {
5481 synchronized(mWindowMap) {
5482 mInTouchMode = mode;
5483 }
5484 }
5485
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005486 // TODO: more accounting of which pid(s) turned it on, keep count,
5487 // only allow disables from pids which have count on, etc.
Craig Mautner0447a812012-05-22 16:01:31 -07005488 @Override
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005489 public void showStrictModeViolation(boolean on) {
Chris Craik3198ef32012-10-10 14:52:30 -07005490 int pid = Binder.getCallingPid();
5491 mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, on ? 1 : 0, pid));
Craig Mautner0447a812012-05-22 16:01:31 -07005492 }
Mike Lockwood3a74bd32011-08-12 13:55:22 -07005493
Chris Craik3198ef32012-10-10 14:52:30 -07005494 private void showStrictModeViolation(int arg, int pid) {
Craig Mautner0447a812012-05-22 16:01:31 -07005495 final boolean on = arg != 0;
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005496 synchronized(mWindowMap) {
5497 // Ignoring requests to enable the red border from clients
5498 // which aren't on screen. (e.g. Broadcast Receivers in
5499 // the background..)
5500 if (on) {
5501 boolean isVisible = false;
Craig Mautnerf8924152013-07-16 09:10:55 -07005502 final int numDisplays = mDisplayContents.size();
5503 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
5504 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
5505 final int numWindows = windows.size();
5506 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
5507 final WindowState ws = windows.get(winNdx);
5508 if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
5509 isVisible = true;
5510 break;
5511 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005512 }
5513 }
5514 if (!isVisible) {
5515 return;
5516 }
5517 }
5518
Dianne Hackborn36991742011-10-11 21:35:26 -07005519 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
5520 ">>> OPEN TRANSACTION showStrictModeViolation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -08005521 SurfaceControl.openTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005522 try {
Jeff Browne215f262012-09-10 16:01:14 -07005523 // TODO(multi-display): support multiple displays
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005524 if (mStrictModeFlash == null) {
Jeff Browne215f262012-09-10 16:01:14 -07005525 mStrictModeFlash = new StrictModeFlash(
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005526 getDefaultDisplayContentLocked().getDisplay(), mFxSession);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005527 }
5528 mStrictModeFlash.setVisibility(on);
5529 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -08005530 SurfaceControl.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -07005531 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
5532 "<<< CLOSE TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005533 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005534 }
5535 }
5536
Craig Mautner6cfa7292013-01-15 09:05:42 -08005537 @Override
Brad Fitzpatrickc1a968a2010-11-24 08:56:40 -08005538 public void setStrictModeVisualIndicatorPreference(String value) {
5539 SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
5540 }
5541
Jim Millere70d5062011-03-08 21:38:39 -08005542 /**
5543 * Takes a snapshot of the screen. In landscape mode this grabs the whole screen.
5544 * In portrait mode, it grabs the upper region of the screen based on the vertical dimension
5545 * of the target image.
Craig Mautner312eac42012-11-13 10:56:22 -08005546 *
Craig Mautner59c00972012-07-30 12:10:24 -07005547 * @param displayId the Display to take a screenshot of.
Jim Millere70d5062011-03-08 21:38:39 -08005548 * @param width the width of the target bitmap
5549 * @param height the height of the target bitmap
John Reck172e87c2013-10-02 16:55:16 -07005550 * @param force565 if true the returned bitmap will be RGB_565, otherwise it
5551 * will be the same config as the surface
Jim Millere70d5062011-03-08 21:38:39 -08005552 */
Craig Mautner2d5618c2012-10-18 13:55:47 -07005553 @Override
John Reck172e87c2013-10-02 16:55:16 -07005554 public Bitmap screenshotApplications(IBinder appToken, int displayId, int width,
5555 int height, boolean force565) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005556 if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5557 "screenshotApplications()")) {
5558 throw new SecurityException("Requires READ_FRAME_BUFFER permission");
5559 }
5560
Craig Mautner24d887472013-03-20 15:40:36 -07005561 Bitmap rawss = null;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005562
Dianne Hackbornd2835932010-12-13 16:28:46 -08005563 int maxLayer = 0;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005564 final Rect frame = new Rect();
5565
Craig Mautner24d887472013-03-20 15:40:36 -07005566 float scale = 0;
Jim Millere70d5062011-03-08 21:38:39 -08005567 int dw, dh;
Craig Mautner24d887472013-03-20 15:40:36 -07005568 int rot = Surface.ROTATION_0;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005569
Craig Mautner24d887472013-03-20 15:40:36 -07005570 boolean screenshotReady;
5571 int minLayer;
5572 if (appToken == null) {
5573 screenshotReady = true;
5574 minLayer = 0;
5575 } else {
5576 screenshotReady = false;
5577 minLayer = Integer.MAX_VALUE;
5578 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005579
Craig Mautner24d887472013-03-20 15:40:36 -07005580 int retryCount = 0;
5581 WindowState appWin = null;
5582
5583 do {
5584 if (retryCount++ > 0) {
5585 try {
5586 Thread.sleep(100);
5587 } catch (InterruptedException e) {
5588 }
Craig Mautner2d5618c2012-10-18 13:55:47 -07005589 }
Craig Mautner24d887472013-03-20 15:40:36 -07005590 synchronized(mWindowMap) {
5591 final DisplayContent displayContent = getDisplayContentLocked(displayId);
5592 if (displayContent == null) {
5593 return null;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005594 }
Craig Mautner24d887472013-03-20 15:40:36 -07005595 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
5596 dw = displayInfo.logicalWidth;
5597 dh = displayInfo.logicalHeight;
5598
5599 int aboveAppLayer = mPolicy.windowTypeToLayerLw(TYPE_APPLICATION)
5600 * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
5601 aboveAppLayer += TYPE_LAYER_MULTIPLIER;
5602
5603 boolean isImeTarget = mInputMethodTarget != null
5604 && mInputMethodTarget.mAppToken != null
5605 && mInputMethodTarget.mAppToken.appToken != null
5606 && mInputMethodTarget.mAppToken.appToken.asBinder() == appToken;
5607
5608 // Figure out the part of the screen that is actually the app.
5609 boolean including = false;
5610 appWin = null;
5611 final WindowList windows = displayContent.getWindowList();
Craig Mautner76ea2242013-05-15 11:40:05 -07005612 final Rect stackBounds = new Rect();
Craig Mautner24d887472013-03-20 15:40:36 -07005613 for (int i = windows.size() - 1; i >= 0; i--) {
5614 WindowState ws = windows.get(i);
5615 if (!ws.mHasSurface) {
5616 continue;
5617 }
5618 if (ws.mLayer >= aboveAppLayer) {
5619 continue;
5620 }
5621 // When we will skip windows: when we are not including
5622 // ones behind a window we didn't skip, and we are actually
5623 // taking a screenshot of a specific app.
5624 if (!including && appToken != null) {
5625 // Also, we can possibly skip this window if it is not
5626 // an IME target or the application for the screenshot
5627 // is not the current IME target.
5628 if (!ws.mIsImWindow || !isImeTarget) {
5629 // And finally, this window is of no interest if it
5630 // is not associated with the screenshot app.
5631 if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
5632 continue;
5633 }
5634 appWin = ws;
Craig Mautnered6649f2013-12-02 14:08:25 -08005635 ws.getStackBounds(stackBounds);
Craig Mautner24d887472013-03-20 15:40:36 -07005636 }
5637 }
5638
5639 // We keep on including windows until we go past a full-screen
5640 // window.
Sangkyu Lee7ccba972013-11-21 15:20:33 +09005641 including = !ws.mIsImWindow && !ws.isFullscreen(dw, dh);
Craig Mautner24d887472013-03-20 15:40:36 -07005642
5643 final WindowStateAnimator winAnim = ws.mWinAnimator;
5644 if (maxLayer < winAnim.mSurfaceLayer) {
5645 maxLayer = winAnim.mSurfaceLayer;
5646 }
Craig Mautner4238e3e2013-03-28 15:28:55 -07005647 if (minLayer > winAnim.mSurfaceLayer) {
5648 minLayer = winAnim.mSurfaceLayer;
5649 }
Craig Mautner24d887472013-03-20 15:40:36 -07005650
5651 // Don't include wallpaper in bounds calculation
5652 if (!ws.mIsWallpaper) {
5653 final Rect wf = ws.mFrame;
5654 final Rect cr = ws.mContentInsets;
5655 int left = wf.left + cr.left;
5656 int top = wf.top + cr.top;
5657 int right = wf.right - cr.right;
5658 int bottom = wf.bottom - cr.bottom;
5659 frame.union(left, top, right, bottom);
Craig Mautner76ea2242013-05-15 11:40:05 -07005660 frame.intersect(stackBounds);
Craig Mautner24d887472013-03-20 15:40:36 -07005661 }
5662
Craig Mautner4238e3e2013-03-28 15:28:55 -07005663 if (ws.mAppToken != null && ws.mAppToken.token == appToken &&
5664 ws.isDisplayedLw()) {
5665 screenshotReady = true;
5666 }
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005667 }
5668
Craig Mautner24d887472013-03-20 15:40:36 -07005669 if (appToken != null && appWin == null) {
5670 // Can't find a window to snapshot.
5671 if (DEBUG_SCREENSHOT) Slog.i(TAG,
5672 "Screenshot: Couldn't find a surface matching " + appToken);
5673 return null;
5674 }
5675 if (!screenshotReady) {
5676 // Delay and hope that window gets drawn.
5677 if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot: No image ready for " + appToken
5678 + ", " + appWin + " drawState=" + appWin.mWinAnimator.mDrawState);
5679 continue;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005680 }
Craig Mautner312eac42012-11-13 10:56:22 -08005681
Craig Mautner24d887472013-03-20 15:40:36 -07005682 // Constrain frame to the screen size.
5683 frame.intersect(0, 0, dw, dh);
5684
5685 if (frame.isEmpty() || maxLayer == 0) {
5686 if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot of " + appToken
5687 + ": returning null frame=" + frame.toShortString() + " maxLayer="
5688 + maxLayer);
5689 return null;
Jim Miller2aded182011-03-08 15:32:42 -08005690 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005691
Craig Mautner24d887472013-03-20 15:40:36 -07005692 // The screenshot API does not apply the current screen rotation.
5693 rot = getDefaultDisplayContentLocked().getDisplay().getRotation();
5694 int fw = frame.width();
5695 int fh = frame.height();
Jim Millere70d5062011-03-08 21:38:39 -08005696
Craig Mautner24d887472013-03-20 15:40:36 -07005697 // Constrain thumbnail to smaller of screen width or height. Assumes aspect
5698 // of thumbnail is the same as the screen (in landscape) or square.
Craig Mautner76ea2242013-05-15 11:40:05 -07005699 scale = Math.max(width / (float) fw, height / (float) fh);
5700 /*
Craig Mautner24d887472013-03-20 15:40:36 -07005701 float targetWidthScale = width / (float) fw;
5702 float targetHeightScale = height / (float) fh;
Craig Mautner76ea2242013-05-15 11:40:05 -07005703 if (fw <= fh) {
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005704 scale = targetWidthScale;
Craig Mautner24d887472013-03-20 15:40:36 -07005705 // If aspect of thumbnail is the same as the screen (in landscape),
5706 // select the slightly larger value so we fill the entire bitmap
5707 if (targetHeightScale > scale && (int) (targetHeightScale * fw) == width) {
5708 scale = targetHeightScale;
5709 }
5710 } else {
5711 scale = targetHeightScale;
5712 // If aspect of thumbnail is the same as the screen (in landscape),
5713 // select the slightly larger value so we fill the entire bitmap
5714 if (targetWidthScale > scale && (int) (targetWidthScale * fh) == height) {
5715 scale = targetWidthScale;
5716 }
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005717 }
Craig Mautner76ea2242013-05-15 11:40:05 -07005718 */
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005719
Craig Mautner24d887472013-03-20 15:40:36 -07005720 // The screen shot will contain the entire screen.
5721 dw = (int)(dw*scale);
5722 dh = (int)(dh*scale);
5723 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
5724 int tmp = dw;
5725 dw = dh;
5726 dh = tmp;
5727 rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -07005728 }
Craig Mautner24d887472013-03-20 15:40:36 -07005729 if (DEBUG_SCREENSHOT) {
5730 Slog.i(TAG, "Screenshot: " + dw + "x" + dh + " from " + minLayer + " to "
5731 + maxLayer + " appToken=" + appToken);
5732 for (int i = 0; i < windows.size(); i++) {
5733 WindowState win = windows.get(i);
5734 Slog.i(TAG, win + ": " + win.mLayer
5735 + " animLayer=" + win.mWinAnimator.mAnimLayer
5736 + " surfaceLayer=" + win.mWinAnimator.mSurfaceLayer);
5737 }
5738 }
Dan Stoza16ec12a2014-02-14 15:06:55 -08005739 // TODO: Replace 'false' in the following line with a variable that indicates
5740 // whether the screenshot should use the identity transformation matrix
5741 // (e.g., enable it when taking a screenshot for recents, since we might be in
5742 // the middle of the rotation animation, but don't want a rotated recent image).
5743 rawss = SurfaceControl.screenshot(dw, dh, minLayer, maxLayer, false);
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -07005744 }
Craig Mautner24d887472013-03-20 15:40:36 -07005745 } while (!screenshotReady && retryCount <= MAX_SCREENSHOT_RETRIES);
Craig Mautner4238e3e2013-03-28 15:28:55 -07005746 if (retryCount > MAX_SCREENSHOT_RETRIES) Slog.i(TAG, "Screenshot max retries " +
5747 retryCount + " of " + appToken + " appWin=" + (appWin == null ?
5748 "null" : (appWin + " drawState=" + appWin.mWinAnimator.mDrawState)));
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005749
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005750 if (rawss == null) {
Craig Mautner4238e3e2013-03-28 15:28:55 -07005751 Slog.w(TAG, "Screenshot failure taking screenshot for (" + dw + "x" + dh
Dianne Hackborn88b03bd2010-12-16 11:15:18 -08005752 + ") to layer " + maxLayer);
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005753 return null;
5754 }
Jim Millere70d5062011-03-08 21:38:39 -08005755
John Reck172e87c2013-10-02 16:55:16 -07005756 Bitmap bm = Bitmap.createBitmap(width, height, force565 ? Config.RGB_565 : rawss.getConfig());
Craig Mautner76ea2242013-05-15 11:40:05 -07005757 frame.scale(scale);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005758 Matrix matrix = new Matrix();
5759 ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07005760 // TODO: Test for RTL vs. LTR and use frame.right-width instead of -frame.left
Craig Mautner76ea2242013-05-15 11:40:05 -07005761 matrix.postTranslate(-FloatMath.ceil(frame.left), -FloatMath.ceil(frame.top));
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005762 Canvas canvas = new Canvas(bm);
Dianne Hackbornca46b872013-04-17 18:06:22 -07005763 canvas.drawColor(0xFF000000);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005764 canvas.drawBitmap(rawss, matrix, null);
Dianne Hackborn6311d0a2011-08-02 16:37:58 -07005765 canvas.setBitmap(null);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005766
Craig Mautner4697bea2013-10-24 09:13:14 -07005767 if (DEBUG_SCREENSHOT) {
Craig Mautner24d887472013-03-20 15:40:36 -07005768 // TEST IF IT's ALL BLACK
5769 int[] buffer = new int[bm.getWidth() * bm.getHeight()];
5770 bm.getPixels(buffer, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm.getHeight());
5771 boolean allBlack = true;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07005772 final int firstColor = buffer[0];
Craig Mautner24d887472013-03-20 15:40:36 -07005773 for (int i = 0; i < buffer.length; i++) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07005774 if (buffer[i] != firstColor) {
Craig Mautner24d887472013-03-20 15:40:36 -07005775 allBlack = false;
5776 break;
5777 }
5778 }
5779 if (allBlack) {
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07005780 Slog.i(TAG, "Screenshot " + appWin + " was monochrome(" +
5781 Integer.toHexString(firstColor) + ")! mSurfaceLayer=" +
Craig Mautner4238e3e2013-03-28 15:28:55 -07005782 (appWin != null ? appWin.mWinAnimator.mSurfaceLayer : "null") +
5783 " minLayer=" + minLayer + " maxLayer=" + maxLayer);
Craig Mautner24d887472013-03-20 15:40:36 -07005784 }
5785 }
5786
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005787 rawss.recycle();
5788 return bm;
5789 }
5790
Jeff Brown01a98dd2011-09-20 15:08:29 -07005791 /**
5792 * Freeze rotation changes. (Enable "rotation lock".)
5793 * Persists across reboots.
Jeff Brown4dfce202011-10-05 12:00:10 -07005794 * @param rotation The desired rotation to freeze to, or -1 to use the
5795 * current rotation.
Jeff Brown01a98dd2011-09-20 15:08:29 -07005796 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005797 @Override
Jeff Brown4dfce202011-10-05 12:00:10 -07005798 public void freezeRotation(int rotation) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005799 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005800 "freezeRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005801 throw new SecurityException("Requires SET_ORIENTATION permission");
5802 }
Jeff Brown4dfce202011-10-05 12:00:10 -07005803 if (rotation < -1 || rotation > Surface.ROTATION_270) {
5804 throw new IllegalArgumentException("Rotation argument must be -1 or a valid "
5805 + "rotation constant.");
5806 }
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005807
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005808 if (DEBUG_ORIENTATION) Slog.v(TAG, "freezeRotation: mRotation=" + mRotation);
5809
Daniel Sandler3de830b2013-02-20 15:23:52 -05005810 long origId = Binder.clearCallingIdentity();
5811 try {
5812 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED,
5813 rotation == -1 ? mRotation : rotation);
5814 } finally {
5815 Binder.restoreCallingIdentity(origId);
5816 }
5817
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005818 updateRotationUnchecked(false, false);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005819 }
5820
Jeff Brown01a98dd2011-09-20 15:08:29 -07005821 /**
5822 * Thaw rotation changes. (Disable "rotation lock".)
5823 * Persists across reboots.
5824 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005825 @Override
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005826 public void thawRotation() {
5827 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005828 "thawRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005829 throw new SecurityException("Requires SET_ORIENTATION permission");
5830 }
5831
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005832 if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation);
5833
Daniel Sandler3de830b2013-02-20 15:23:52 -05005834 long origId = Binder.clearCallingIdentity();
5835 try {
5836 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE,
5837 777); // rot not used
5838 } finally {
5839 Binder.restoreCallingIdentity(origId);
5840 }
5841
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005842 updateRotationUnchecked(false, false);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005843 }
5844
Jeff Brown01a98dd2011-09-20 15:08:29 -07005845 /**
5846 * Recalculate the current rotation.
5847 *
5848 * Called by the window manager policy whenever the state of the system changes
5849 * such that the current rotation might need to be updated, such as when the
5850 * device is docked or rotated into a new posture.
5851 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08005852 @Override
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005853 public void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
5854 updateRotationUnchecked(alwaysSendConfiguration, forceRelayout);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005855 }
5856
5857 /**
5858 * Temporarily pauses rotation changes until resumed.
5859 *
5860 * This can be used to prevent rotation changes from occurring while the user is
5861 * performing certain operations, such as drag and drop.
5862 *
Craig Mautner6cfa7292013-01-15 09:05:42 -08005863 * This call nests and must be matched by an equal number of calls to
5864 * {@link #resumeRotationLocked}.
Jeff Brown01a98dd2011-09-20 15:08:29 -07005865 */
5866 void pauseRotationLocked() {
5867 mDeferredRotationPauseCount += 1;
5868 }
5869
5870 /**
5871 * Resumes normal rotation changes after being paused.
5872 */
5873 void resumeRotationLocked() {
5874 if (mDeferredRotationPauseCount > 0) {
5875 mDeferredRotationPauseCount -= 1;
5876 if (mDeferredRotationPauseCount == 0) {
5877 boolean changed = updateRotationUncheckedLocked(false);
5878 if (changed) {
5879 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
5880 }
5881 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005882 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005883 }
Romain Guy06882f82009-06-10 13:36:04 -07005884
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005885 public void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005886 if(DEBUG_ORIENTATION) Slog.v(TAG, "updateRotationUnchecked("
5887 + "alwaysSendConfiguration=" + alwaysSendConfiguration + ")");
Romain Guy06882f82009-06-10 13:36:04 -07005888
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005889 long origId = Binder.clearCallingIdentity();
5890 boolean changed;
5891 synchronized(mWindowMap) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005892 changed = updateRotationUncheckedLocked(false);
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005893 if (!changed || forceRelayout) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005894 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005895 performLayoutAndPlaceSurfacesLocked();
5896 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005897 }
Romain Guy06882f82009-06-10 13:36:04 -07005898
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005899 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005900 sendNewConfiguration();
5901 }
Romain Guy06882f82009-06-10 13:36:04 -07005902
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005903 Binder.restoreCallingIdentity(origId);
5904 }
Romain Guy06882f82009-06-10 13:36:04 -07005905
Craig Mautner59c00972012-07-30 12:10:24 -07005906 // TODO(multidisplay): Rotate any display?
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005907 /**
Jeff Brown01a98dd2011-09-20 15:08:29 -07005908 * Updates the current rotation.
5909 *
5910 * Returns true if the rotation has been changed. In this case YOU
5911 * MUST CALL sendNewConfiguration() TO UNFREEZE THE SCREEN.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005912 */
Jeff Brown01a98dd2011-09-20 15:08:29 -07005913 public boolean updateRotationUncheckedLocked(boolean inTransaction) {
5914 if (mDeferredRotationPauseCount > 0) {
5915 // Rotation updates have been paused temporarily. Defer the update until
5916 // updates have been resumed.
5917 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, rotation is paused.");
Christopher Tateccd24de2011-01-12 15:02:55 -08005918 return false;
5919 }
5920
Craig Mautnera91f9e22012-09-14 16:22:08 -07005921 ScreenRotationAnimation screenRotationAnimation =
5922 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
5923 if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005924 // Rotation updates cannot be performed while the previous rotation change
5925 // animation is still in progress. Skip this update. We will try updating
5926 // again after the animation is finished and the display is unfrozen.
5927 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, animation in progress.");
5928 return false;
5929 }
5930
5931 if (!mDisplayEnabled) {
5932 // No point choosing a rotation if the display is not enabled.
5933 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, display is not enabled.");
5934 return false;
5935 }
5936
5937 // TODO: Implement forced rotation changes.
5938 // Set mAltOrientation to indicate that the application is receiving
5939 // an orientation that has different metrics than it expected.
5940 // eg. Portrait instead of Landscape.
5941
5942 int rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, mRotation);
5943 boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
5944 mForcedAppOrientation, rotation);
5945
5946 if (DEBUG_ORIENTATION) {
5947 Slog.v(TAG, "Application requested orientation "
5948 + mForcedAppOrientation + ", got rotation " + rotation
5949 + " which has " + (altOrientation ? "incompatible" : "compatible")
5950 + " metrics");
5951 }
5952
5953 if (mRotation == rotation && mAltOrientation == altOrientation) {
5954 // No change.
5955 return false;
5956 }
5957
5958 if (DEBUG_ORIENTATION) {
5959 Slog.v(TAG,
5960 "Rotation changed to " + rotation + (altOrientation ? " (alt)" : "")
5961 + " from " + mRotation + (mAltOrientation ? " (alt)" : "")
5962 + ", forceApp=" + mForcedAppOrientation);
5963 }
5964
5965 mRotation = rotation;
5966 mAltOrientation = altOrientation;
Jeff Brownc0347aa2011-09-23 17:26:09 -07005967 mPolicy.setRotationLw(mRotation);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005968
5969 mWindowsFreezingScreen = true;
5970 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
Craig Mautner0bf6ec92012-12-18 08:33:27 -08005971 mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT, WINDOW_FREEZE_TIMEOUT_DURATION);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005972 mWaitingForConfig = true;
Craig Mautner05d29032013-05-03 13:40:13 -07005973 final DisplayContent displayContent = getDefaultDisplayContentLocked();
5974 displayContent.layoutNeeded = true;
Craig Mautner3c174372013-02-21 17:54:37 -08005975 final int[] anim = new int[2];
Craig Mautner05d29032013-05-03 13:40:13 -07005976 if (displayContent.isDimming()) {
Craig Mautner3c174372013-02-21 17:54:37 -08005977 anim[0] = anim[1] = 0;
5978 } else {
5979 mPolicy.selectRotationAnimationLw(anim);
5980 }
5981 startFreezingDisplayLocked(inTransaction, anim[0], anim[1]);
Craig Mautnera91f9e22012-09-14 16:22:08 -07005982 // startFreezingDisplayLocked can reset the ScreenRotationAnimation.
5983 screenRotationAnimation =
5984 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005985
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08005986 // We need to update our screen size information to match the new
5987 // rotation. Note that this is redundant with the later call to
5988 // sendNewConfiguration() that must be called after this function
5989 // returns... however we need to do the screen size part of that
Jeff Brown4ed8fe72012-08-30 18:18:29 -07005990 // before then so we have the correct size to use when initializing
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08005991 // the rotation animation for the new rotation.
5992 computeScreenConfigurationLocked(null);
5993
Craig Mautner59c00972012-07-30 12:10:24 -07005994 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07005995 if (!inTransaction) {
5996 if (SHOW_TRANSACTIONS) {
5997 Slog.i(TAG, ">>> OPEN TRANSACTION setRotationUnchecked");
5998 }
Mathias Agopian3866f0d2013-02-11 22:08:48 -08005999 SurfaceControl.openTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006000 }
Jamie Gennise2909e12011-10-10 15:48:06 -07006001 try {
6002 // NOTE: We disable the rotation in the emulator because
6003 // it doesn't support hardware OpenGL emulation yet.
Craig Mautnera91f9e22012-09-14 16:22:08 -07006004 if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
6005 && screenRotationAnimation.hasScreenshot()) {
6006 if (screenRotationAnimation.setRotationInTransaction(
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006007 rotation, mFxSession,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006008 MAX_ANIMATION_DURATION, mTransitionAnimationScale,
Craig Mautner59c00972012-07-30 12:10:24 -07006009 displayInfo.logicalWidth, displayInfo.logicalHeight)) {
Craig Mautner96868332012-12-04 14:29:11 -08006010 scheduleAnimationLocked();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006011 }
Jamie Gennise2909e12011-10-10 15:48:06 -07006012 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006013
Jeff Brown4ccb8232014-01-16 22:16:42 -08006014 mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
Jamie Gennise2909e12011-10-10 15:48:06 -07006015 } finally {
6016 if (!inTransaction) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -08006017 SurfaceControl.closeTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006018 if (SHOW_LIGHT_TRANSACTIONS) {
6019 Slog.i(TAG, "<<< CLOSE TRANSACTION setRotationUnchecked");
6020 }
Jamie Gennise2909e12011-10-10 15:48:06 -07006021 }
6022 }
6023
Craig Mautner59c00972012-07-30 12:10:24 -07006024 final WindowList windows = displayContent.getWindowList();
6025 for (int i = windows.size() - 1; i >= 0; i--) {
6026 WindowState w = windows.get(i);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07006027 if (w.mHasSurface) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07006028 if (DEBUG_ORIENTATION) Slog.v(TAG, "Set mOrientationChanging of " + w);
Jeff Brown01a98dd2011-09-20 15:08:29 -07006029 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07006030 mInnerFields.mOrientationChangeComplete = false;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006031 }
Dianne Hackborna57c6952013-03-29 14:46:40 -07006032 w.mLastFreezeDuration = 0;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006033 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006034
Jeff Brown01a98dd2011-09-20 15:08:29 -07006035 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
6036 try {
Jim Miller7267ed12013-12-09 17:38:05 -08006037 mRotationWatchers.get(i).watcher.onRotationChanged(rotation);
Jeff Brown01a98dd2011-09-20 15:08:29 -07006038 } catch (RemoteException e) {
6039 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006040 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006041
Svetoslav Ganov545252f2012-12-10 18:29:24 -08006042 //TODO (multidisplay): Magnification is supported only for the default display.
Svetoslav8e3feb12014-02-24 13:46:47 -08006043 if (mAccessibilityController != null
Svetoslav Ganov545252f2012-12-10 18:29:24 -08006044 && displayContent.getDisplayId() == Display.DEFAULT_DISPLAY) {
Svetoslav8e3feb12014-02-24 13:46:47 -08006045 mAccessibilityController.onRotationChangedLocked(getDefaultDisplayContentLocked(), rotation);
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07006046 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006047
Jeff Brown01a98dd2011-09-20 15:08:29 -07006048 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006049 }
Romain Guy06882f82009-06-10 13:36:04 -07006050
Craig Mautner0bf6ec92012-12-18 08:33:27 -08006051 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006052 public int getRotation() {
6053 return mRotation;
6054 }
6055
Craig Mautner0bf6ec92012-12-18 08:33:27 -08006056 @Override
Svetoslav Ganov80943d82013-01-02 10:25:37 -08006057 public boolean isRotationFrozen() {
6058 return mPolicy.getUserRotationMode() == WindowManagerPolicy.USER_ROTATION_LOCKED;
6059 }
6060
6061 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006062 public int watchRotation(IRotationWatcher watcher) {
6063 final IBinder watcherBinder = watcher.asBinder();
6064 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
Craig Mautner0bf6ec92012-12-18 08:33:27 -08006065 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006066 public void binderDied() {
6067 synchronized (mWindowMap) {
6068 for (int i=0; i<mRotationWatchers.size(); i++) {
Jim Miller7267ed12013-12-09 17:38:05 -08006069 if (watcherBinder == mRotationWatchers.get(i).watcher.asBinder()) {
6070 RotationWatcher removed = mRotationWatchers.remove(i);
6071 IBinder binder = removed.watcher.asBinder();
6072 if (binder != null) {
6073 binder.unlinkToDeath(this, 0);
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07006074 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006075 i--;
6076 }
6077 }
6078 }
6079 }
6080 };
Romain Guy06882f82009-06-10 13:36:04 -07006081
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006082 synchronized (mWindowMap) {
6083 try {
6084 watcher.asBinder().linkToDeath(dr, 0);
Jim Miller7267ed12013-12-09 17:38:05 -08006085 mRotationWatchers.add(new RotationWatcher(watcher, dr));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006086 } catch (RemoteException e) {
6087 // Client died, no cleanup needed.
6088 }
Romain Guy06882f82009-06-10 13:36:04 -07006089
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006090 return mRotation;
6091 }
6092 }
6093
Brian Colonnab1b9a8a2013-03-29 11:52:42 -04006094 @Override
6095 public void removeRotationWatcher(IRotationWatcher watcher) {
6096 final IBinder watcherBinder = watcher.asBinder();
6097 synchronized (mWindowMap) {
6098 for (int i=0; i<mRotationWatchers.size(); i++) {
Jim Miller7267ed12013-12-09 17:38:05 -08006099 RotationWatcher rotationWatcher = mRotationWatchers.get(i);
6100 if (watcherBinder == rotationWatcher.watcher.asBinder()) {
6101 RotationWatcher removed = mRotationWatchers.remove(i);
6102 IBinder binder = removed.watcher.asBinder();
6103 if (binder != null) {
6104 binder.unlinkToDeath(removed.deathRecipient, 0);
6105 }
Brian Colonnab1b9a8a2013-03-29 11:52:42 -04006106 i--;
6107 }
6108 }
6109 }
6110 }
6111
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006112 /**
Adam Powelldfee59a2011-08-05 20:48:30 -07006113 * Apps that use the compact menu panel (as controlled by the panelMenuIsCompact
6114 * theme attribute) on devices that feature a physical options menu key attempt to position
6115 * their menu panel window along the edge of the screen nearest the physical menu key.
6116 * This lowers the travel distance between invoking the menu panel and selecting
6117 * a menu option.
6118 *
6119 * This method helps control where that menu is placed. Its current implementation makes
6120 * assumptions about the menu key and its relationship to the screen based on whether
6121 * the device's natural orientation is portrait (width < height) or landscape.
6122 *
6123 * The menu key is assumed to be located along the bottom edge of natural-portrait
6124 * devices and along the right edge of natural-landscape devices. If these assumptions
6125 * do not hold for the target device, this method should be changed to reflect that.
6126 *
6127 * @return A {@link Gravity} value for placing the options menu window
6128 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08006129 @Override
Adam Powelldfee59a2011-08-05 20:48:30 -07006130 public int getPreferredOptionsPanelGravity() {
6131 synchronized (mWindowMap) {
6132 final int rotation = getRotation();
6133
Craig Mautner59c00972012-07-30 12:10:24 -07006134 // TODO(multidisplay): Assume that such devices physical keys are on the main screen.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006135 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07006136 if (displayContent.mInitialDisplayWidth < displayContent.mInitialDisplayHeight) {
Adam Powelldfee59a2011-08-05 20:48:30 -07006137 // On devices with a natural orientation of portrait
6138 switch (rotation) {
6139 default:
6140 case Surface.ROTATION_0:
6141 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
6142 case Surface.ROTATION_90:
Adam Powell67ed6c72011-08-28 13:21:56 -07006143 return Gravity.RIGHT | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006144 case Surface.ROTATION_180:
Adam Powell67ed6c72011-08-28 13:21:56 -07006145 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006146 case Surface.ROTATION_270:
Fabrice Di Meglioaac0d4e2012-07-19 19:21:26 -07006147 return Gravity.START | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006148 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08006149 }
6150
6151 // On devices with a natural orientation of landscape
6152 switch (rotation) {
6153 default:
6154 case Surface.ROTATION_0:
6155 return Gravity.RIGHT | Gravity.BOTTOM;
6156 case Surface.ROTATION_90:
6157 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
6158 case Surface.ROTATION_180:
6159 return Gravity.START | Gravity.BOTTOM;
6160 case Surface.ROTATION_270:
6161 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006162 }
6163 }
6164 }
6165
6166 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006167 * Starts the view server on the specified port.
6168 *
6169 * @param port The port to listener to.
6170 *
6171 * @return True if the server was successfully started, false otherwise.
6172 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08006173 * @see com.android.server.wm.ViewServer
6174 * @see com.android.server.wm.ViewServer#VIEW_SERVER_DEFAULT_PORT
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006175 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08006176 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006177 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07006178 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006179 return false;
6180 }
6181
6182 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
6183 return false;
6184 }
6185
6186 if (port < 1024) {
6187 return false;
6188 }
6189
6190 if (mViewServer != null) {
6191 if (!mViewServer.isRunning()) {
6192 try {
6193 return mViewServer.start();
6194 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006195 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006196 }
6197 }
6198 return false;
6199 }
6200
6201 try {
6202 mViewServer = new ViewServer(this, port);
6203 return mViewServer.start();
6204 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006205 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006206 }
6207 return false;
6208 }
6209
Romain Guy06882f82009-06-10 13:36:04 -07006210 private boolean isSystemSecure() {
6211 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
6212 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6213 }
6214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006215 /**
6216 * Stops the view server if it exists.
6217 *
6218 * @return True if the server stopped, false if it wasn't started or
6219 * couldn't be stopped.
6220 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08006221 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006222 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08006223 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006224 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07006225 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006226 return false;
6227 }
6228
6229 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
6230 return false;
6231 }
6232
6233 if (mViewServer != null) {
6234 return mViewServer.stop();
6235 }
6236 return false;
6237 }
6238
6239 /**
6240 * Indicates whether the view server is running.
6241 *
6242 * @return True if the server is running, false otherwise.
6243 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08006244 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006245 */
Craig Mautner6cfa7292013-01-15 09:05:42 -08006246 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006247 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07006248 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006249 return false;
6250 }
6251
6252 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
6253 return false;
6254 }
6255
6256 return mViewServer != null && mViewServer.isRunning();
6257 }
6258
6259 /**
6260 * Lists all availble windows in the system. The listing is written in the
6261 * specified Socket's output stream with the following syntax:
6262 * windowHashCodeInHexadecimal windowName
6263 * Each line of the ouput represents a different window.
6264 *
6265 * @param client The remote client to send the listing to.
6266 * @return False if an error occured, true otherwise.
6267 */
6268 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07006269 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006270 return false;
6271 }
6272
6273 boolean result = true;
6274
Craig Mautner59c00972012-07-30 12:10:24 -07006275 WindowList windows = new WindowList();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006276 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006277 //noinspection unchecked
Craig Mautnerf8924152013-07-16 09:10:55 -07006278 final int numDisplays = mDisplayContents.size();
6279 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
6280 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
6281 windows.addAll(displayContent.getWindowList());
Craig Mautner59c00972012-07-30 12:10:24 -07006282 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006283 }
6284
6285 BufferedWriter out = null;
6286
6287 // Any uncaught exception will crash the system process
6288 try {
6289 OutputStream clientStream = client.getOutputStream();
6290 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
6291
Craig Mautner59c00972012-07-30 12:10:24 -07006292 final int count = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006293 for (int i = 0; i < count; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07006294 final WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006295 out.write(Integer.toHexString(System.identityHashCode(w)));
6296 out.write(' ');
6297 out.append(w.mAttrs.getTitle());
6298 out.write('\n');
6299 }
6300
6301 out.write("DONE.\n");
6302 out.flush();
6303 } catch (Exception e) {
6304 result = false;
6305 } finally {
6306 if (out != null) {
6307 try {
6308 out.close();
6309 } catch (IOException e) {
6310 result = false;
6311 }
6312 }
6313 }
6314
6315 return result;
6316 }
6317
Craig Mautner59c00972012-07-30 12:10:24 -07006318 // TODO(multidisplay): Extend to multiple displays.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006319 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07006320 * Returns the focused window in the following format:
6321 * windowHashCodeInHexadecimal windowName
6322 *
6323 * @param client The remote client to send the listing to.
6324 * @return False if an error occurred, true otherwise.
6325 */
6326 boolean viewServerGetFocusedWindow(Socket client) {
6327 if (isSystemSecure()) {
6328 return false;
6329 }
6330
6331 boolean result = true;
6332
6333 WindowState focusedWindow = getFocusedWindow();
6334
6335 BufferedWriter out = null;
6336
6337 // Any uncaught exception will crash the system process
6338 try {
6339 OutputStream clientStream = client.getOutputStream();
6340 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
6341
6342 if(focusedWindow != null) {
6343 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
6344 out.write(' ');
6345 out.append(focusedWindow.mAttrs.getTitle());
6346 }
6347 out.write('\n');
6348 out.flush();
6349 } catch (Exception e) {
6350 result = false;
6351 } finally {
6352 if (out != null) {
6353 try {
6354 out.close();
6355 } catch (IOException e) {
6356 result = false;
6357 }
6358 }
6359 }
6360
6361 return result;
6362 }
6363
6364 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006365 * Sends a command to a target window. The result of the command, if any, will be
6366 * written in the output stream of the specified socket.
6367 *
6368 * The parameters must follow this syntax:
6369 * windowHashcode extra
6370 *
6371 * Where XX is the length in characeters of the windowTitle.
6372 *
6373 * The first parameter is the target window. The window with the specified hashcode
6374 * will be the target. If no target can be found, nothing happens. The extra parameters
6375 * will be delivered to the target window and as parameters to the command itself.
6376 *
6377 * @param client The remote client to sent the result, if any, to.
6378 * @param command The command to execute.
6379 * @param parameters The command parameters.
6380 *
6381 * @return True if the command was successfully delivered, false otherwise. This does
6382 * not indicate whether the command itself was successful.
6383 */
6384 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07006385 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006386 return false;
6387 }
6388
6389 boolean success = true;
6390 Parcel data = null;
6391 Parcel reply = null;
6392
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006393 BufferedWriter out = null;
6394
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006395 // Any uncaught exception will crash the system process
6396 try {
6397 // Find the hashcode of the window
6398 int index = parameters.indexOf(' ');
6399 if (index == -1) {
6400 index = parameters.length();
6401 }
6402 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08006403 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006404
6405 // Extract the command's parameter after the window description
6406 if (index < parameters.length()) {
6407 parameters = parameters.substring(index + 1);
6408 } else {
6409 parameters = "";
6410 }
6411
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006412 final WindowState window = findWindow(hashCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006413 if (window == null) {
6414 return false;
6415 }
6416
6417 data = Parcel.obtain();
6418 data.writeInterfaceToken("android.view.IWindow");
6419 data.writeString(command);
6420 data.writeString(parameters);
6421 data.writeInt(1);
6422 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
6423
6424 reply = Parcel.obtain();
6425
6426 final IBinder binder = window.mClient.asBinder();
6427 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
6428 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
6429
6430 reply.readException();
6431
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006432 if (!client.isOutputShutdown()) {
6433 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
6434 out.write("DONE\n");
6435 out.flush();
6436 }
6437
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006438 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006439 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006440 success = false;
6441 } finally {
6442 if (data != null) {
6443 data.recycle();
6444 }
6445 if (reply != null) {
6446 reply.recycle();
6447 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006448 if (out != null) {
6449 try {
6450 out.close();
6451 } catch (IOException e) {
6452
6453 }
6454 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006455 }
6456
6457 return success;
6458 }
6459
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07006460 public void addWindowChangeListener(WindowChangeListener listener) {
6461 synchronized(mWindowMap) {
6462 mWindowChangeListeners.add(listener);
6463 }
6464 }
6465
6466 public void removeWindowChangeListener(WindowChangeListener listener) {
6467 synchronized(mWindowMap) {
6468 mWindowChangeListeners.remove(listener);
6469 }
6470 }
6471
6472 private void notifyWindowsChanged() {
6473 WindowChangeListener[] windowChangeListeners;
6474 synchronized(mWindowMap) {
6475 if(mWindowChangeListeners.isEmpty()) {
6476 return;
6477 }
6478 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
6479 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
6480 }
6481 int N = windowChangeListeners.length;
6482 for(int i = 0; i < N; i++) {
6483 windowChangeListeners[i].windowsChanged();
6484 }
6485 }
6486
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07006487 private void notifyFocusChanged() {
6488 WindowChangeListener[] windowChangeListeners;
6489 synchronized(mWindowMap) {
6490 if(mWindowChangeListeners.isEmpty()) {
6491 return;
6492 }
6493 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
6494 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
6495 }
6496 int N = windowChangeListeners.length;
6497 for(int i = 0; i < N; i++) {
6498 windowChangeListeners[i].focusChanged();
6499 }
6500 }
6501
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006502 private WindowState findWindow(int hashCode) {
6503 if (hashCode == -1) {
Craig Mautner59c00972012-07-30 12:10:24 -07006504 // TODO(multidisplay): Extend to multiple displays.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006505 return getFocusedWindow();
6506 }
6507
6508 synchronized (mWindowMap) {
Craig Mautnerf8924152013-07-16 09:10:55 -07006509 final int numDisplays = mDisplayContents.size();
6510 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
6511 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
6512 final int numWindows = windows.size();
6513 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
6514 final WindowState w = windows.get(winNdx);
6515 if (System.identityHashCode(w) == hashCode) {
6516 return w;
6517 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006518 }
6519 }
6520 }
6521
6522 return null;
6523 }
6524
6525 /*
6526 * Instruct the Activity Manager to fetch the current configuration and broadcast
6527 * that to config-changed listeners if appropriate.
6528 */
6529 void sendNewConfiguration() {
6530 try {
6531 mActivityManager.updateConfiguration(null);
6532 } catch (RemoteException e) {
6533 }
6534 }
Romain Guy06882f82009-06-10 13:36:04 -07006535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006536 public Configuration computeNewConfiguration() {
6537 synchronized (mWindowMap) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006538 Configuration config = computeNewConfigurationLocked();
6539 if (config == null && mWaitingForConfig) {
6540 // Nothing changed but we are waiting for something... stop that!
6541 mWaitingForConfig = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07006542 mLastFinishedFreezeSource = "new-config";
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006543 performLayoutAndPlaceSurfacesLocked();
6544 }
6545 return config;
Dianne Hackbornc485a602009-03-24 22:39:49 -07006546 }
6547 }
Romain Guy06882f82009-06-10 13:36:04 -07006548
Dianne Hackbornc485a602009-03-24 22:39:49 -07006549 Configuration computeNewConfigurationLocked() {
6550 Configuration config = new Configuration();
Dianne Hackborn09e5b9d2011-10-04 16:32:01 -07006551 config.fontScale = 0;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006552 if (!computeScreenConfigurationLocked(config)) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07006553 return null;
6554 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07006555 return config;
6556 }
Romain Guy06882f82009-06-10 13:36:04 -07006557
Craig Mautner59c00972012-07-30 12:10:24 -07006558 private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation, int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006559 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006560 final int width = mPolicy.getConfigDisplayWidth(dw, dh, rotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006561 if (width < displayInfo.smallestNominalAppWidth) {
6562 displayInfo.smallestNominalAppWidth = width;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006563 }
Craig Mautner59c00972012-07-30 12:10:24 -07006564 if (width > displayInfo.largestNominalAppWidth) {
6565 displayInfo.largestNominalAppWidth = width;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006566 }
6567 final int height = mPolicy.getConfigDisplayHeight(dw, dh, rotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006568 if (height < displayInfo.smallestNominalAppHeight) {
6569 displayInfo.smallestNominalAppHeight = height;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006570 }
Craig Mautner59c00972012-07-30 12:10:24 -07006571 if (height > displayInfo.largestNominalAppHeight) {
6572 displayInfo.largestNominalAppHeight = height;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006573 }
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006574 }
6575
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006576 private int reduceConfigLayout(int curLayout, int rotation, float density,
6577 int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006578 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006579 // Get the app screen size at this rotation.
6580 int w = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
6581 int h = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
6582
6583 // Compute the screen layout size class for this rotation.
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006584 int longSize = w;
6585 int shortSize = h;
6586 if (longSize < shortSize) {
6587 int tmp = longSize;
6588 longSize = shortSize;
6589 shortSize = tmp;
6590 }
6591 longSize = (int)(longSize/density);
6592 shortSize = (int)(shortSize/density);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006593 return Configuration.reduceScreenLayout(curLayout, longSize, shortSize);
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006594 }
6595
Craig Mautner59c00972012-07-30 12:10:24 -07006596 private void computeSizeRangesAndScreenLayout(DisplayInfo displayInfo, boolean rotated,
6597 int dw, int dh, float density, Configuration outConfig) {
Craig Mautner69b08182012-09-05 13:07:13 -07006598 // TODO: Multidisplay: for now only use with default display.
6599
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006600 // We need to determine the smallest width that will occur under normal
6601 // operation. To this, start with the base screen size and compute the
6602 // width under the different possible rotations. We need to un-rotate
6603 // the current screen dimensions before doing this.
6604 int unrotDw, unrotDh;
6605 if (rotated) {
6606 unrotDw = dh;
6607 unrotDh = dw;
6608 } else {
6609 unrotDw = dw;
6610 unrotDh = dh;
6611 }
Craig Mautner59c00972012-07-30 12:10:24 -07006612 displayInfo.smallestNominalAppWidth = 1<<30;
6613 displayInfo.smallestNominalAppHeight = 1<<30;
6614 displayInfo.largestNominalAppWidth = 0;
6615 displayInfo.largestNominalAppHeight = 0;
6616 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, unrotDw, unrotDh);
6617 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, unrotDh, unrotDw);
6618 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, unrotDw, unrotDh);
6619 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, unrotDh, unrotDw);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006620 int sl = Configuration.resetScreenLayout(outConfig.screenLayout);
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006621 sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh);
6622 sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw);
6623 sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh);
6624 sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw);
Craig Mautner59c00972012-07-30 12:10:24 -07006625 outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006626 outConfig.screenLayout = sl;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006627 }
6628
Dianne Hackborn48a76512011-06-08 21:51:44 -07006629 private int reduceCompatConfigWidthSize(int curSize, int rotation, DisplayMetrics dm,
6630 int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006631 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn1f903c32011-09-13 19:18:06 -07006632 dm.noncompatWidthPixels = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
6633 dm.noncompatHeightPixels = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006634 float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
Dianne Hackborn2b31d532011-06-23 11:58:50 -07006635 int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006636 if (curSize == 0 || size < curSize) {
6637 curSize = size;
6638 }
6639 return curSize;
6640 }
6641
6642 private int computeCompatSmallestWidth(boolean rotated, DisplayMetrics dm, int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006643 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn48a76512011-06-08 21:51:44 -07006644 mTmpDisplayMetrics.setTo(dm);
Craig Mautner69b08182012-09-05 13:07:13 -07006645 final DisplayMetrics tmpDm = mTmpDisplayMetrics;
6646 final int unrotDw, unrotDh;
Dianne Hackborn48a76512011-06-08 21:51:44 -07006647 if (rotated) {
6648 unrotDw = dh;
6649 unrotDh = dw;
6650 } else {
6651 unrotDw = dw;
6652 unrotDh = dh;
6653 }
Craig Mautner69b08182012-09-05 13:07:13 -07006654 int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, tmpDm, unrotDw, unrotDh);
6655 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, tmpDm, unrotDh, unrotDw);
6656 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, tmpDm, unrotDw, unrotDh);
6657 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, tmpDm, unrotDh, unrotDw);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006658 return sw;
6659 }
6660
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006661 boolean computeScreenConfigurationLocked(Configuration config) {
Jeff Browne215f262012-09-10 16:01:14 -07006662 if (!mDisplayReady) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07006663 return false;
6664 }
Christopher Tateb696aee2010-04-02 19:08:30 -07006665
Craig Mautner59c00972012-07-30 12:10:24 -07006666 // TODO(multidisplay): For now, apply Configuration to main screen only.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006667 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07006668
Christopher Tateb696aee2010-04-02 19:08:30 -07006669 // Use the effective "visual" dimensions based on current rotation
6670 final boolean rotated = (mRotation == Surface.ROTATION_90
6671 || mRotation == Surface.ROTATION_270);
Craig Mautner59c00972012-07-30 12:10:24 -07006672 final int realdw = rotated ?
6673 displayContent.mBaseDisplayHeight : displayContent.mBaseDisplayWidth;
6674 final int realdh = rotated ?
6675 displayContent.mBaseDisplayWidth : displayContent.mBaseDisplayHeight;
Jeff Brownfa25bf52012-07-23 19:26:30 -07006676 int dw = realdw;
6677 int dh = realdh;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006678
Jeff Brownfa25bf52012-07-23 19:26:30 -07006679 if (mAltOrientation) {
6680 if (realdw > realdh) {
6681 // Turn landscape into portrait.
6682 int maxw = (int)(realdh/1.3f);
6683 if (maxw < realdw) {
6684 dw = maxw;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006685 }
6686 } else {
Jeff Brownfa25bf52012-07-23 19:26:30 -07006687 // Turn portrait into landscape.
6688 int maxh = (int)(realdw/1.3f);
6689 if (maxh < realdh) {
6690 dh = maxh;
6691 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006692 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006693 }
6694
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006695 if (config != null) {
Jeff Browne215f262012-09-10 16:01:14 -07006696 config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
6697 Configuration.ORIENTATION_LANDSCAPE;
Dianne Hackbornc485a602009-03-24 22:39:49 -07006698 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006699
Jeff Brownbc68a592011-07-25 12:58:12 -07006700 // Update application display metrics.
Dianne Hackborn1fbee792011-11-30 11:29:58 -08006701 final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation);
6702 final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006703 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
6704 synchronized(displayContent.mDisplaySizeLock) {
6705 displayInfo.rotation = mRotation;
6706 displayInfo.logicalWidth = dw;
6707 displayInfo.logicalHeight = dh;
Dianne Hackborndde331c2012-08-03 14:01:57 -07006708 displayInfo.logicalDensityDpi = displayContent.mBaseDisplayDensity;
Craig Mautner59c00972012-07-30 12:10:24 -07006709 displayInfo.appWidth = appWidth;
6710 displayInfo.appHeight = appHeight;
Craig Mautner48d0d182013-06-11 07:53:06 -07006711 displayInfo.getLogicalMetrics(mRealDisplayMetrics,
6712 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
6713 displayInfo.getAppMetrics(mDisplayMetrics);
Jeff Brown4ccb8232014-01-16 22:16:42 -08006714 mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
Jeff Brownbd6e1502012-08-28 03:27:37 -07006715 displayContent.getDisplayId(), displayInfo);
Dianne Hackborn1fbee792011-11-30 11:29:58 -08006716 }
Dianne Hackborn36991742011-10-11 21:35:26 -07006717 if (false) {
Jeff Brownfa25bf52012-07-23 19:26:30 -07006718 Slog.i(TAG, "Set app display size: " + appWidth + " x " + appHeight);
Dianne Hackborn36991742011-10-11 21:35:26 -07006719 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006720
Jeff Brownfa25bf52012-07-23 19:26:30 -07006721 final DisplayMetrics dm = mDisplayMetrics;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006722 mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm,
6723 mCompatDisplayMetrics);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006724
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006725 if (config != null) {
6726 config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation)
6727 / dm.density);
6728 config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation)
6729 / dm.density);
Craig Mautner59c00972012-07-30 12:10:24 -07006730 computeSizeRangesAndScreenLayout(displayInfo, rotated, dw, dh, dm.density, config);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006731
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006732 config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
6733 config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
6734 config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dm, dw, dh);
Dianne Hackborndde331c2012-08-03 14:01:57 -07006735 config.densityDpi = displayContent.mBaseDisplayDensity;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006736
Jeff Browndaa37532012-05-01 15:54:03 -07006737 // Update the configuration based on available input devices, lid switch,
6738 // and platform configuration.
6739 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
6740 config.keyboard = Configuration.KEYBOARD_NOKEYS;
6741 config.navigation = Configuration.NAVIGATION_NONAV;
6742
6743 int keyboardPresence = 0;
6744 int navigationPresence = 0;
Craig Mautner1d961d42012-05-27 12:02:11 -07006745 final InputDevice[] devices = mInputManager.getInputDevices();
6746 final int len = devices.length;
6747 for (int i = 0; i < len; i++) {
6748 InputDevice device = devices[i];
Jeff Browndaa37532012-05-01 15:54:03 -07006749 if (!device.isVirtual()) {
6750 final int sources = device.getSources();
6751 final int presenceFlag = device.isExternal() ?
6752 WindowManagerPolicy.PRESENCE_EXTERNAL :
6753 WindowManagerPolicy.PRESENCE_INTERNAL;
6754
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -07006755 if (mIsTouchDevice) {
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006756 if ((sources & InputDevice.SOURCE_TOUCHSCREEN) ==
6757 InputDevice.SOURCE_TOUCHSCREEN) {
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -07006758 config.touchscreen = Configuration.TOUCHSCREEN_FINGER;
6759 }
6760 } else {
6761 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
Jeff Browndaa37532012-05-01 15:54:03 -07006762 }
6763
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006764 if ((sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) {
Jeff Browndaa37532012-05-01 15:54:03 -07006765 config.navigation = Configuration.NAVIGATION_TRACKBALL;
6766 navigationPresence |= presenceFlag;
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006767 } else if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD
Jeff Browndaa37532012-05-01 15:54:03 -07006768 && config.navigation == Configuration.NAVIGATION_NONAV) {
6769 config.navigation = Configuration.NAVIGATION_DPAD;
6770 navigationPresence |= presenceFlag;
6771 }
6772
6773 if (device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) {
6774 config.keyboard = Configuration.KEYBOARD_QWERTY;
6775 keyboardPresence |= presenceFlag;
6776 }
6777 }
6778 }
6779
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006780 // Determine whether a hard keyboard is available and enabled.
6781 boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
6782 if (hardKeyboardAvailable != mHardKeyboardAvailable) {
6783 mHardKeyboardAvailable = hardKeyboardAvailable;
6784 mHardKeyboardEnabled = hardKeyboardAvailable;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006785 mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
6786 mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
6787 }
6788 if (!mHardKeyboardEnabled) {
6789 config.keyboard = Configuration.KEYBOARD_NOKEYS;
6790 }
6791
Jeff Browndaa37532012-05-01 15:54:03 -07006792 // Let the policy update hidden states.
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006793 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
6794 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
6795 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO;
Jeff Browndaa37532012-05-01 15:54:03 -07006796 mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence);
Jeff Brown2992ea72011-01-28 22:04:14 -08006797 }
Jeff Brown597eec82011-01-31 17:12:25 -08006798
Dianne Hackbornc485a602009-03-24 22:39:49 -07006799 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006800 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006801
Jeff Brown2992ea72011-01-28 22:04:14 -08006802 public boolean isHardKeyboardAvailable() {
6803 synchronized (mWindowMap) {
6804 return mHardKeyboardAvailable;
6805 }
6806 }
6807
6808 public boolean isHardKeyboardEnabled() {
6809 synchronized (mWindowMap) {
6810 return mHardKeyboardEnabled;
6811 }
6812 }
6813
6814 public void setHardKeyboardEnabled(boolean enabled) {
6815 synchronized (mWindowMap) {
6816 if (mHardKeyboardEnabled != enabled) {
6817 mHardKeyboardEnabled = enabled;
6818 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
6819 }
6820 }
6821 }
6822
6823 public void setOnHardKeyboardStatusChangeListener(
6824 OnHardKeyboardStatusChangeListener listener) {
6825 synchronized (mWindowMap) {
6826 mHardKeyboardStatusChangeListener = listener;
6827 }
6828 }
6829
6830 void notifyHardKeyboardStatusChange() {
6831 final boolean available, enabled;
6832 final OnHardKeyboardStatusChangeListener listener;
6833 synchronized (mWindowMap) {
6834 listener = mHardKeyboardStatusChangeListener;
6835 available = mHardKeyboardAvailable;
6836 enabled = mHardKeyboardEnabled;
6837 }
6838 if (listener != null) {
6839 listener.onHardKeyboardStatusChange(available, enabled);
6840 }
6841 }
6842
Christopher Tatea53146c2010-09-07 11:57:52 -07006843 // -------------------------------------------------------------
6844 // Drag and drop
6845 // -------------------------------------------------------------
6846
6847 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006848 int flags, int width, int height, Surface outSurface) {
Christopher Tatea53146c2010-09-07 11:57:52 -07006849 if (DEBUG_DRAG) {
6850 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006851 + " flags=" + Integer.toHexString(flags) + " win=" + window
Christopher Tatea53146c2010-09-07 11:57:52 -07006852 + " asbinder=" + window.asBinder());
6853 }
6854
6855 final int callerPid = Binder.getCallingPid();
6856 final long origId = Binder.clearCallingIdentity();
6857 IBinder token = null;
6858
6859 try {
6860 synchronized (mWindowMap) {
6861 try {
Christopher Tatea53146c2010-09-07 11:57:52 -07006862 if (mDragState == null) {
Jeff Browne215f262012-09-10 16:01:14 -07006863 // TODO(multi-display): support other displays
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006864 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07006865 final Display display = displayContent.getDisplay();
Mathias Agopian3866f0d2013-02-11 22:08:48 -08006866 SurfaceControl surface = new SurfaceControl(session, "drag surface",
6867 width, height, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
Jeff Browne215f262012-09-10 16:01:14 -07006868 surface.setLayerStack(display.getLayerStack());
Dianne Hackbornac1471a2011-02-03 13:46:06 -08006869 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DRAG "
6870 + surface + ": CREATE");
Christopher Tatea53146c2010-09-07 11:57:52 -07006871 outSurface.copyFrom(surface);
Chris Tate7b362e42010-11-04 16:02:52 -07006872 final IBinder winBinder = window.asBinder();
Christopher Tatea53146c2010-09-07 11:57:52 -07006873 token = new Binder();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006874 mDragState = new DragState(this, token, surface, /*flags*/ 0, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07006875 token = mDragState.mToken = new Binder();
6876
6877 // 5 second timeout for this window to actually begin the drag
Chris Tate7b362e42010-11-04 16:02:52 -07006878 mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
6879 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07006880 mH.sendMessageDelayed(msg, 5000);
6881 } else {
6882 Slog.w(TAG, "Drag already in progress");
6883 }
Igor Murashkina86ab6402013-08-30 12:58:36 -07006884 } catch (OutOfResourcesException e) {
Christopher Tatea53146c2010-09-07 11:57:52 -07006885 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
6886 if (mDragState != null) {
6887 mDragState.reset();
6888 mDragState = null;
6889 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006890 }
6891 }
6892 } finally {
6893 Binder.restoreCallingIdentity(origId);
6894 }
6895
6896 return token;
6897 }
6898
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006899 // -------------------------------------------------------------
6900 // Input Events and Focus Management
6901 // -------------------------------------------------------------
Craig Mautner6cfa7292013-01-15 09:05:42 -08006902
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006903 final InputMonitor mInputMonitor = new InputMonitor(this);
Jeff Brown08a746a2012-06-24 12:14:49 -07006904 private boolean mEventDispatchingEnabled;
6905
Craig Mautner6cfa7292013-01-15 09:05:42 -08006906 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006907 public void pauseKeyDispatching(IBinder _token) {
6908 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6909 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006910 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006911 }
6912
6913 synchronized (mWindowMap) {
6914 WindowToken token = mTokenMap.get(_token);
6915 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006916 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006917 }
6918 }
6919 }
6920
Craig Mautner6cfa7292013-01-15 09:05:42 -08006921 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006922 public void resumeKeyDispatching(IBinder _token) {
6923 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6924 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006925 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006926 }
6927
6928 synchronized (mWindowMap) {
6929 WindowToken token = mTokenMap.get(_token);
6930 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006931 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006932 }
6933 }
6934 }
6935
Craig Mautner6cfa7292013-01-15 09:05:42 -08006936 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006937 public void setEventDispatching(boolean enabled) {
6938 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner3d7b7d52012-05-24 11:28:26 -07006939 "setEventDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006940 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006941 }
6942
6943 synchronized (mWindowMap) {
Jeff Brown08a746a2012-06-24 12:14:49 -07006944 mEventDispatchingEnabled = enabled;
6945 if (mDisplayEnabled) {
6946 mInputMonitor.setEventDispatchingLw(enabled);
6947 }
Craig Mautner3d7b7d52012-05-24 11:28:26 -07006948 sendScreenStatusToClientsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006949 }
6950 }
Romain Guy06882f82009-06-10 13:36:04 -07006951
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006952 private WindowState getFocusedWindow() {
6953 synchronized (mWindowMap) {
6954 return getFocusedWindowLocked();
6955 }
6956 }
6957
6958 private WindowState getFocusedWindowLocked() {
6959 return mCurrentFocus;
6960 }
Romain Guy06882f82009-06-10 13:36:04 -07006961
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006962 public boolean detectSafeMode() {
Jeff Brownb09abc12011-01-13 21:08:27 -08006963 if (!mInputMonitor.waitForInputDevicesReady(
6964 INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
6965 Slog.w(TAG, "Devices still not ready after waiting "
Jeff Brownac143512012-04-05 18:57:33 -07006966 + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
6967 + " milliseconds before attempting to detect safe mode.");
Jeff Brownb09abc12011-01-13 21:08:27 -08006968 }
6969
Jeff Brownac143512012-04-05 18:57:33 -07006970 int menuState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
6971 KeyEvent.KEYCODE_MENU);
6972 int sState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, KeyEvent.KEYCODE_S);
6973 int dpadState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD,
6974 KeyEvent.KEYCODE_DPAD_CENTER);
6975 int trackballState = mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL,
Jeff Brownc458ce92012-04-30 14:58:40 -07006976 InputManagerService.BTN_MOUSE);
Jeff Brownac143512012-04-05 18:57:33 -07006977 int volumeDownState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
6978 KeyEvent.KEYCODE_VOLUME_DOWN);
6979 mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
6980 || volumeDownState > 0;
Dianne Hackborn19caadc2012-04-20 17:49:10 -07006981 try {
6982 if (SystemProperties.getInt(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, 0) != 0) {
6983 mSafeMode = true;
6984 SystemProperties.set(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, "");
6985 }
6986 } catch (IllegalArgumentException e) {
6987 }
Jeff Brownac143512012-04-05 18:57:33 -07006988 if (mSafeMode) {
6989 Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
6990 + " dpad=" + dpadState + " trackball=" + trackballState + ")");
6991 } else {
6992 Log.i(TAG, "SAFE MODE not enabled");
6993 }
6994 mPolicy.setSafeMode(mSafeMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006995 return mSafeMode;
6996 }
Romain Guy06882f82009-06-10 13:36:04 -07006997
Dianne Hackborn661cd522011-08-22 00:26:20 -07006998 public void displayReady() {
Jeff Browne215f262012-09-10 16:01:14 -07006999 displayReady(Display.DEFAULT_DISPLAY);
Craig Mautner4f67ba62012-08-02 11:23:00 -07007000
7001 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007002 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07007003 readForcedDisplaySizeAndDensityLocked(displayContent);
Jeff Browne215f262012-09-10 16:01:14 -07007004 mDisplayReady = true;
Craig Mautner67a60422013-07-24 09:19:44 -07007005 }
7006
7007 try {
7008 mActivityManager.updateConfiguration(null);
7009 } catch (RemoteException e) {
7010 }
7011
7012 synchronized(mWindowMap) {
Craig Mautner4f67ba62012-08-02 11:23:00 -07007013 mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
Jeff Browne215f262012-09-10 16:01:14 -07007014 PackageManager.FEATURE_TOUCHSCREEN);
Jeff Brownef981a42013-08-07 14:13:37 -07007015 configureDisplayPolicyLocked(getDefaultDisplayContentLocked());
Craig Mautner4f67ba62012-08-02 11:23:00 -07007016 }
Dianne Hackborn5a052a42012-08-15 18:49:23 -07007017
7018 try {
7019 mActivityManager.updateConfiguration(null);
7020 } catch (RemoteException e) {
7021 }
Craig Mautner59c00972012-07-30 12:10:24 -07007022 }
7023
Craig Mautner2d5618c2012-10-18 13:55:47 -07007024 private void displayReady(int displayId) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07007025 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007026 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007027 if (displayContent != null) {
7028 mAnimator.addDisplayLocked(displayId);
7029 synchronized(displayContent.mDisplaySizeLock) {
7030 // Bootstrap the default logical display from the display manager.
7031 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
Jeff Brown4ccb8232014-01-16 22:16:42 -08007032 DisplayInfo newDisplayInfo = mDisplayManagerInternal.getDisplayInfo(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007033 if (newDisplayInfo != null) {
7034 displayInfo.copyFrom(newDisplayInfo);
7035 }
7036 displayContent.mInitialDisplayWidth = displayInfo.logicalWidth;
7037 displayContent.mInitialDisplayHeight = displayInfo.logicalHeight;
7038 displayContent.mInitialDisplayDensity = displayInfo.logicalDensityDpi;
7039 displayContent.mBaseDisplayWidth = displayContent.mInitialDisplayWidth;
7040 displayContent.mBaseDisplayHeight = displayContent.mInitialDisplayHeight;
7041 displayContent.mBaseDisplayDensity = displayContent.mInitialDisplayDensity;
Craig Mautner6601b7b2013-04-29 10:29:11 -07007042 displayContent.mBaseDisplayRect.set(0, 0,
7043 displayContent.mBaseDisplayWidth, displayContent.mBaseDisplayHeight);
Jeff Brownbd6e1502012-08-28 03:27:37 -07007044 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007045 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07007046 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07007047 }
7048
Dianne Hackborn661cd522011-08-22 00:26:20 -07007049 public void systemReady() {
7050 mPolicy.systemReady();
7051 }
7052
Craig Mautner59c00972012-07-30 12:10:24 -07007053 // TODO(multidisplay): Call isScreenOn for each display.
Craig Mautner3d7b7d52012-05-24 11:28:26 -07007054 private void sendScreenStatusToClientsLocked() {
Craig Mautner59c00972012-07-30 12:10:24 -07007055 final boolean on = mPowerManager.isScreenOn();
Craig Mautnerf8924152013-07-16 09:10:55 -07007056 final int numDisplays = mDisplayContents.size();
7057 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
7058 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
7059 final int numWindows = windows.size();
7060 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
7061 try {
7062 windows.get(winNdx).mClient.dispatchScreenState(on);
7063 } catch (RemoteException e) {
7064 // Ignored
7065 }
Romain Guy7e4e5612012-03-05 14:37:29 -08007066 }
7067 }
7068 }
7069
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007070 // -------------------------------------------------------------
7071 // Async Handler
7072 // -------------------------------------------------------------
7073
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08007074 final class H extends Handler {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007075 public static final int REPORT_FOCUS_CHANGE = 2;
7076 public static final int REPORT_LOSING_FOCUS = 3;
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08007077 public static final int DO_TRAVERSAL = 4;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007078 public static final int ADD_STARTING = 5;
7079 public static final int REMOVE_STARTING = 6;
7080 public static final int FINISHED_STARTING = 7;
7081 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07007082 public static final int REPORT_APPLICATION_TOKEN_DRAWN = 9;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007083 public static final int WINDOW_FREEZE_TIMEOUT = 11;
Craig Mautner259328c2012-08-21 19:30:58 -07007084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007085 public static final int APP_TRANSITION_TIMEOUT = 13;
7086 public static final int PERSIST_ANIMATION_SCALE = 14;
7087 public static final int FORCE_GC = 15;
7088 public static final int ENABLE_SCREEN = 16;
7089 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007090 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07007091 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07007092 public static final int DRAG_START_TIMEOUT = 20;
Chris Tated4533f12010-10-19 15:15:08 -07007093 public static final int DRAG_END_TIMEOUT = 21;
Jeff Brown2992ea72011-01-28 22:04:14 -08007094 public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07007095 public static final int BOOT_TIMEOUT = 23;
Dianne Hackborn38e29a62011-09-18 14:43:08 -07007096 public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
Craig Mautner96868332012-12-04 14:29:11 -08007097 public static final int SHOW_STRICT_MODE_VIOLATION = 25;
7098 public static final int DO_ANIMATION_CALLBACK = 26;
Romain Guy06882f82009-06-10 13:36:04 -07007099
Craig Mautner96868332012-12-04 14:29:11 -08007100 public static final int DO_DISPLAY_ADDED = 27;
7101 public static final int DO_DISPLAY_REMOVED = 28;
7102 public static final int DO_DISPLAY_CHANGED = 29;
Craig Mautner722285e2012-09-07 13:55:58 -07007103
Craig Mautner96868332012-12-04 14:29:11 -08007104 public static final int CLIENT_FREEZE_TIMEOUT = 30;
Craig Mautnerd3c93382013-04-24 14:23:39 -07007105 public static final int TAP_OUTSIDE_STACK = 31;
Craig Mautner5eda9b32013-07-02 11:58:16 -07007106 public static final int NOTIFY_ACTIVITY_DRAWN = 32;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007107
Craig Mautner68cc2412013-10-01 10:39:43 -07007108 public static final int REMOVE_STARTING_TIMEOUT = 33;
7109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007110 @Override
7111 public void handleMessage(Message msg) {
Craig Mautner7d8df392012-04-06 15:26:23 -07007112 if (DEBUG_WINDOW_TRACE) {
7113 Slog.v(TAG, "handleMessage: entry what=" + msg.what);
7114 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007115 switch (msg.what) {
7116 case REPORT_FOCUS_CHANGE: {
7117 WindowState lastFocus;
7118 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07007119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007120 synchronized(mWindowMap) {
7121 lastFocus = mLastFocus;
7122 newFocus = mCurrentFocus;
7123 if (lastFocus == newFocus) {
7124 // Focus is not changing, so nothing to do.
7125 return;
7126 }
7127 mLastFocus = newFocus;
Craig Mautner58458122013-09-14 14:59:50 -07007128 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Focus moving from " + lastFocus +
7129 " to " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007130 if (newFocus != null && lastFocus != null
7131 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007132 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007133 mLosingFocus.add(lastFocus);
7134 lastFocus = null;
7135 }
7136 }
7137
Craig Mautnerb1885b82013-09-16 22:50:50 -07007138 //System.out.println("Changing focus from " + lastFocus
7139 // + " to " + newFocus);
7140 if (newFocus != null) {
7141 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Gaining focus: " + newFocus);
7142 newFocus.reportFocusChangedSerialized(true, mInTouchMode);
7143 notifyFocusChanged();
7144 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007145
Craig Mautnerb1885b82013-09-16 22:50:50 -07007146 if (lastFocus != null) {
7147 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Losing focus: " + lastFocus);
7148 lastFocus.reportFocusChangedSerialized(false, mInTouchMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007149 }
7150 } break;
7151
7152 case REPORT_LOSING_FOCUS: {
7153 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07007154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007155 synchronized(mWindowMap) {
7156 losers = mLosingFocus;
7157 mLosingFocus = new ArrayList<WindowState>();
7158 }
7159
7160 final int N = losers.size();
7161 for (int i=0; i<N; i++) {
Craig Mautner58458122013-09-14 14:59:50 -07007162 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Losing delayed focus: " +
7163 losers.get(i));
Dianne Hackborne3f23a32013-03-01 13:25:35 -08007164 losers.get(i).reportFocusChangedSerialized(false, mInTouchMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007165 }
7166 } break;
7167
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08007168 case DO_TRAVERSAL: {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007169 synchronized(mWindowMap) {
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08007170 mTraversalScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007171 performLayoutAndPlaceSurfacesLocked();
7172 }
7173 } break;
7174
7175 case ADD_STARTING: {
7176 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7177 final StartingData sd = wtoken.startingData;
7178
7179 if (sd == null) {
7180 // Animation has been canceled... do nothing.
7181 return;
7182 }
Romain Guy06882f82009-06-10 13:36:04 -07007183
Joe Onorato8a9b2202010-02-26 18:56:32 -08007184 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007185 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07007186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007187 View view = null;
7188 try {
7189 view = mPolicy.addStartingWindow(
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07007190 wtoken.token, sd.pkg, sd.theme, sd.compatInfo,
Adam Powell04fe6eb2013-05-31 14:39:48 -07007191 sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.logo, sd.windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007192 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007193 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007194 }
7195
7196 if (view != null) {
7197 boolean abort = false;
7198
7199 synchronized(mWindowMap) {
7200 if (wtoken.removed || wtoken.startingData == null) {
7201 // If the window was successfully added, then
7202 // we need to remove it.
7203 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007204 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007205 "Aborted starting " + wtoken
7206 + ": removed=" + wtoken.removed
7207 + " startingData=" + wtoken.startingData);
7208 wtoken.startingWindow = null;
7209 wtoken.startingData = null;
7210 abort = true;
7211 }
7212 } else {
7213 wtoken.startingView = view;
7214 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007215 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007216 "Added starting " + wtoken
7217 + ": startingWindow="
7218 + wtoken.startingWindow + " startingView="
7219 + wtoken.startingView);
7220 }
7221
7222 if (abort) {
7223 try {
7224 mPolicy.removeStartingWindow(wtoken.token, view);
7225 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007226 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007227 }
7228 }
7229 }
7230 } break;
7231
7232 case REMOVE_STARTING: {
7233 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7234 IBinder token = null;
7235 View view = null;
7236 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007237 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007238 + wtoken + ": startingWindow="
7239 + wtoken.startingWindow + " startingView="
7240 + wtoken.startingView);
7241 if (wtoken.startingWindow != null) {
7242 view = wtoken.startingView;
7243 token = wtoken.token;
7244 wtoken.startingData = null;
7245 wtoken.startingView = null;
7246 wtoken.startingWindow = null;
Craig Mautner38b24782012-07-02 16:21:28 -07007247 wtoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007248 }
7249 }
7250 if (view != null) {
7251 try {
7252 mPolicy.removeStartingWindow(token, view);
7253 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007254 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007255 }
7256 }
7257 } break;
7258
7259 case FINISHED_STARTING: {
7260 IBinder token = null;
7261 View view = null;
7262 while (true) {
7263 synchronized (mWindowMap) {
7264 final int N = mFinishedStarting.size();
7265 if (N <= 0) {
7266 break;
7267 }
7268 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
7269
Joe Onorato8a9b2202010-02-26 18:56:32 -08007270 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007271 "Finished starting " + wtoken
7272 + ": startingWindow=" + wtoken.startingWindow
7273 + " startingView=" + wtoken.startingView);
7274
7275 if (wtoken.startingWindow == null) {
7276 continue;
7277 }
7278
7279 view = wtoken.startingView;
7280 token = wtoken.token;
7281 wtoken.startingData = null;
7282 wtoken.startingView = null;
7283 wtoken.startingWindow = null;
Craig Mautner38b24782012-07-02 16:21:28 -07007284 wtoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007285 }
7286
7287 try {
7288 mPolicy.removeStartingWindow(token, view);
7289 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007290 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007291 }
7292 }
7293 } break;
7294
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07007295 case REPORT_APPLICATION_TOKEN_DRAWN: {
7296 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7297
7298 try {
7299 if (DEBUG_VISIBILITY) Slog.v(
7300 TAG, "Reporting drawn in " + wtoken);
7301 wtoken.appToken.windowsDrawn();
7302 } catch (RemoteException ex) {
7303 }
7304 } break;
7305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007306 case REPORT_APPLICATION_TOKEN_WINDOWS: {
7307 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7308
7309 boolean nowVisible = msg.arg1 != 0;
7310 boolean nowGone = msg.arg2 != 0;
7311
7312 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007313 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007314 TAG, "Reporting visible in " + wtoken
7315 + " visible=" + nowVisible
7316 + " gone=" + nowGone);
7317 if (nowVisible) {
7318 wtoken.appToken.windowsVisible();
7319 } else {
7320 wtoken.appToken.windowsGone();
7321 }
7322 } catch (RemoteException ex) {
7323 }
7324 } break;
Romain Guy06882f82009-06-10 13:36:04 -07007325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007326 case WINDOW_FREEZE_TIMEOUT: {
Craig Mautner59c00972012-07-30 12:10:24 -07007327 // TODO(multidisplay): Can non-default displays rotate?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007328 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007329 Slog.w(TAG, "Window freeze timeout expired.");
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007330 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07007331 int i = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007332 while (i > 0) {
7333 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07007334 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007335 if (w.mOrientationChanging) {
7336 w.mOrientationChanging = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07007337 w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
7338 - mDisplayFreezeTime);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007339 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007340 }
7341 }
7342 performLayoutAndPlaceSurfacesLocked();
7343 }
7344 break;
7345 }
Romain Guy06882f82009-06-10 13:36:04 -07007346
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007347 case APP_TRANSITION_TIMEOUT: {
7348 synchronized (mWindowMap) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08007349 if (mAppTransition.isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08007350 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** APP TRANSITION TIMEOUT");
7351 mAppTransition.setTimeout();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007352 performLayoutAndPlaceSurfacesLocked();
7353 }
7354 }
7355 break;
7356 }
Romain Guy06882f82009-06-10 13:36:04 -07007357
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007358 case PERSIST_ANIMATION_SCALE: {
Jeff Sharkey6e2bee72012-10-01 13:39:08 -07007359 Settings.Global.putFloat(mContext.getContentResolver(),
7360 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
7361 Settings.Global.putFloat(mContext.getContentResolver(),
7362 Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
7363 Settings.Global.putFloat(mContext.getContentResolver(),
7364 Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007365 break;
7366 }
Romain Guy06882f82009-06-10 13:36:04 -07007367
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007368 case FORCE_GC: {
Craig Mautner1caa3992012-06-22 09:46:48 -07007369 synchronized (mWindowMap) {
Craig Mautner96868332012-12-04 14:29:11 -08007370 // Since we're holding both mWindowMap and mAnimator we don't need to
7371 // hold mAnimator.mLayoutToAnim.
7372 if (mAnimator.mAnimating || mAnimationScheduled) {
7373 // If we are animating, don't do the gc now but
7374 // delay a bit so we don't interrupt the animation.
7375 sendEmptyMessageDelayed(H.FORCE_GC, 2000);
7376 return;
7377 }
7378 // If we are currently rotating the display, it will
7379 // schedule a new message when done.
7380 if (mDisplayFrozen) {
7381 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007382 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007383 }
7384 Runtime.getRuntime().gc();
7385 break;
7386 }
Romain Guy06882f82009-06-10 13:36:04 -07007387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007388 case ENABLE_SCREEN: {
7389 performEnableScreen();
7390 break;
7391 }
Romain Guy06882f82009-06-10 13:36:04 -07007392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007393 case APP_FREEZE_TIMEOUT: {
7394 synchronized (mWindowMap) {
Craig Mautner96868332012-12-04 14:29:11 -08007395 Slog.w(TAG, "App freeze timeout expired.");
Craig Mautnerdc548482014-02-05 13:35:24 -08007396 final int numStacks = mStackIdToStack.size();
7397 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
7398 final TaskStack stack = mStackIdToStack.valueAt(stackNdx);
7399 final ArrayList<Task> tasks = stack.getTasks();
7400 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
7401 AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
7402 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
7403 AppWindowToken tok = tokens.get(tokenNdx);
7404 if (tok.mAppAnimator.freezingScreen) {
7405 Slog.w(TAG, "Force clearing freeze: " + tok);
7406 unsetAppFreezingScreenLocked(tok, true, true);
7407 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08007408 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007409 }
7410 }
7411 }
7412 break;
7413 }
Romain Guy06882f82009-06-10 13:36:04 -07007414
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007415 case CLIENT_FREEZE_TIMEOUT: {
7416 synchronized (mWindowMap) {
7417 if (mClientFreezingScreen) {
7418 mClientFreezingScreen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07007419 mLastFinishedFreezeSource = "client-timeout";
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007420 stopFreezingDisplayLocked();
7421 }
7422 }
7423 break;
7424 }
7425
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007426 case SEND_NEW_CONFIGURATION: {
7427 removeMessages(SEND_NEW_CONFIGURATION);
7428 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07007429 break;
7430 }
Romain Guy06882f82009-06-10 13:36:04 -07007431
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07007432 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007433 if (mWindowsChanged) {
7434 synchronized (mWindowMap) {
7435 mWindowsChanged = false;
7436 }
7437 notifyWindowsChanged();
7438 }
7439 break;
7440 }
7441
Christopher Tatea53146c2010-09-07 11:57:52 -07007442 case DRAG_START_TIMEOUT: {
7443 IBinder win = (IBinder)msg.obj;
7444 if (DEBUG_DRAG) {
7445 Slog.w(TAG, "Timeout starting drag by win " + win);
7446 }
7447 synchronized (mWindowMap) {
7448 // !!! TODO: ANR the app that has failed to start the drag in time
7449 if (mDragState != null) {
Chris Tated4533f12010-10-19 15:15:08 -07007450 mDragState.unregister();
Jeff Brown2e44b072011-01-24 15:21:56 -08007451 mInputMonitor.updateInputWindowsLw(true /*force*/);
Christopher Tatea53146c2010-09-07 11:57:52 -07007452 mDragState.reset();
7453 mDragState = null;
7454 }
7455 }
Chris Tated4533f12010-10-19 15:15:08 -07007456 break;
Christopher Tatea53146c2010-09-07 11:57:52 -07007457 }
7458
Chris Tated4533f12010-10-19 15:15:08 -07007459 case DRAG_END_TIMEOUT: {
7460 IBinder win = (IBinder)msg.obj;
7461 if (DEBUG_DRAG) {
7462 Slog.w(TAG, "Timeout ending drag to win " + win);
7463 }
7464 synchronized (mWindowMap) {
7465 // !!! TODO: ANR the drag-receiving app
Christopher Tated9be36c2011-08-16 16:09:33 -07007466 if (mDragState != null) {
7467 mDragState.mDragResult = false;
7468 mDragState.endDragLw();
7469 }
Chris Tated4533f12010-10-19 15:15:08 -07007470 }
7471 break;
7472 }
Jeff Brown2992ea72011-01-28 22:04:14 -08007473
7474 case REPORT_HARD_KEYBOARD_STATUS_CHANGE: {
7475 notifyHardKeyboardStatusChange();
7476 break;
7477 }
Dianne Hackborn38e29a62011-09-18 14:43:08 -07007478
7479 case BOOT_TIMEOUT: {
7480 performBootTimeout();
7481 break;
7482 }
7483
7484 case WAITING_FOR_DRAWN_TIMEOUT: {
7485 Pair<WindowState, IRemoteCallback> pair;
7486 synchronized (mWindowMap) {
7487 pair = (Pair<WindowState, IRemoteCallback>)msg.obj;
7488 Slog.w(TAG, "Timeout waiting for drawn: " + pair.first);
7489 if (!mWaitingForDrawn.remove(pair)) {
7490 return;
7491 }
7492 }
7493 try {
7494 pair.second.sendResult(null);
7495 } catch (RemoteException e) {
7496 }
7497 break;
7498 }
Craig Mautnera608b882012-03-30 13:03:49 -07007499
Craig Mautner0447a812012-05-22 16:01:31 -07007500 case SHOW_STRICT_MODE_VIOLATION: {
Chris Craik3198ef32012-10-10 14:52:30 -07007501 showStrictModeViolation(msg.arg1, msg.arg2);
Craig Mautner0447a812012-05-22 16:01:31 -07007502 break;
7503 }
7504
Dianne Hackborn84375872012-06-01 19:03:50 -07007505 case DO_ANIMATION_CALLBACK: {
7506 try {
7507 ((IRemoteCallback)msg.obj).sendResult(null);
7508 } catch (RemoteException e) {
7509 }
7510 break;
7511 }
Craig Mautner722285e2012-09-07 13:55:58 -07007512
Craig Mautner722285e2012-09-07 13:55:58 -07007513 case DO_DISPLAY_ADDED:
Craig Mautnerad25fa32014-01-12 21:19:06 -08007514 handleDisplayAdded(msg.arg1);
Craig Mautner722285e2012-09-07 13:55:58 -07007515 break;
7516
7517 case DO_DISPLAY_REMOVED:
7518 synchronized (mWindowMap) {
7519 handleDisplayRemovedLocked(msg.arg1);
7520 }
7521 break;
7522
7523 case DO_DISPLAY_CHANGED:
7524 synchronized (mWindowMap) {
7525 handleDisplayChangedLocked(msg.arg1);
7526 }
7527 break;
Craig Mautnerd3c93382013-04-24 14:23:39 -07007528
Craig Mautnereb957862013-04-24 15:34:32 -07007529 case TAP_OUTSIDE_STACK: {
7530 int stackId;
Craig Mautnerd3c93382013-04-24 14:23:39 -07007531 synchronized (mWindowMap) {
Craig Mautnereb957862013-04-24 15:34:32 -07007532 stackId = ((DisplayContent)msg.obj).stackIdFromPoint(msg.arg1, msg.arg2);
7533 }
7534 if (stackId >= 0) {
7535 try {
7536 mActivityManager.setFocusedStack(stackId);
7537 } catch (RemoteException e) {
Craig Mautnerd3c93382013-04-24 14:23:39 -07007538 }
7539 }
Craig Mautnereb957862013-04-24 15:34:32 -07007540 }
Craig Mautner5eda9b32013-07-02 11:58:16 -07007541 break;
7542 case NOTIFY_ACTIVITY_DRAWN:
7543 try {
7544 mActivityManager.notifyActivityDrawn((IBinder) msg.obj);
7545 } catch (RemoteException e) {
7546 }
7547 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007548 }
Craig Mautner7d8df392012-04-06 15:26:23 -07007549 if (DEBUG_WINDOW_TRACE) {
7550 Slog.v(TAG, "handleMessage: exit");
7551 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007552 }
7553 }
7554
7555 // -------------------------------------------------------------
7556 // IWindowManager API
7557 // -------------------------------------------------------------
7558
Craig Mautner7d8df392012-04-06 15:26:23 -07007559 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007560 public IWindowSession openSession(IInputMethodClient client,
7561 IInputContext inputContext) {
7562 if (client == null) throw new IllegalArgumentException("null client");
7563 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08007564 Session session = new Session(this, client, inputContext);
Jeff Brown46b9ac02010-04-22 18:58:52 -07007565 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007566 }
7567
Craig Mautner7d8df392012-04-06 15:26:23 -07007568 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007569 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
7570 synchronized (mWindowMap) {
7571 // The focus for the client is the window immediately below
7572 // where we would place the input method window.
7573 int idx = findDesiredInputMethodWindowIndexLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007574 if (idx > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07007575 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007576 WindowState imFocus = getDefaultWindowListLocked().get(idx-1);
Dianne Hackbornac920872012-05-22 11:49:49 -07007577 if (DEBUG_INPUT_METHOD) {
7578 Slog.i(TAG, "Desired input method target: " + imFocus);
Craig Mautner59c00972012-07-30 12:10:24 -07007579 Slog.i(TAG, "Current focus: " + mCurrentFocus);
7580 Slog.i(TAG, "Last focus: " + mLastFocus);
Dianne Hackbornac920872012-05-22 11:49:49 -07007581 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007582 if (imFocus != null) {
Dianne Hackborne75d8722011-01-27 19:37:40 -08007583 // This may be a starting window, in which case we still want
7584 // to count it as okay.
7585 if (imFocus.mAttrs.type == LayoutParams.TYPE_APPLICATION_STARTING
7586 && imFocus.mAppToken != null) {
7587 // The client has definitely started, so it really should
7588 // have a window in this app token. Let's look for it.
7589 for (int i=0; i<imFocus.mAppToken.windows.size(); i++) {
7590 WindowState w = imFocus.mAppToken.windows.get(i);
7591 if (w != imFocus) {
Dianne Hackbornac920872012-05-22 11:49:49 -07007592 Log.i(TAG, "Switching to real app window: " + w);
Dianne Hackborne75d8722011-01-27 19:37:40 -08007593 imFocus = w;
7594 break;
7595 }
7596 }
7597 }
Dianne Hackbornac920872012-05-22 11:49:49 -07007598 if (DEBUG_INPUT_METHOD) {
7599 Slog.i(TAG, "IM target client: " + imFocus.mSession.mClient);
7600 if (imFocus.mSession.mClient != null) {
7601 Slog.i(TAG, "IM target client binder: "
7602 + imFocus.mSession.mClient.asBinder());
7603 Slog.i(TAG, "Requesting client binder: " + client.asBinder());
7604 }
7605 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007606 if (imFocus.mSession.mClient != null &&
7607 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
7608 return true;
7609 }
7610 }
7611 }
Craig Mautner59c00972012-07-30 12:10:24 -07007612
7613 // Okay, how about this... what is the current focus?
7614 // It seems in some cases we may not have moved the IM
7615 // target window, such as when it was in a pop-up window,
7616 // so let's also look at the current focus. (An example:
7617 // go to Gmail, start searching so the keyboard goes up,
7618 // press home. Sometimes the IME won't go down.)
7619 // Would be nice to fix this more correctly, but it's
7620 // way at the end of a release, and this should be good enough.
7621 if (mCurrentFocus != null && mCurrentFocus.mSession.mClient != null
7622 && mCurrentFocus.mSession.mClient.asBinder() == client.asBinder()) {
7623 return true;
7624 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007625 }
7626 return false;
7627 }
Romain Guy06882f82009-06-10 13:36:04 -07007628
Dianne Hackborn672cf452013-03-26 15:24:24 -07007629 @Override
Craig Mautner59c00972012-07-30 12:10:24 -07007630 public void getInitialDisplaySize(int displayId, Point size) {
Craig Mautner58106812012-12-28 12:27:40 -08007631 synchronized (mWindowMap) {
7632 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Jeff Browna506a6e2013-06-04 00:02:38 -07007633 if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
Craig Mautner58106812012-12-28 12:27:40 -08007634 synchronized(displayContent.mDisplaySizeLock) {
7635 size.x = displayContent.mInitialDisplayWidth;
7636 size.y = displayContent.mInitialDisplayHeight;
7637 }
Craig Mautner2d5618c2012-10-18 13:55:47 -07007638 }
Dianne Hackborn7d608422011-08-07 16:24:18 -07007639 }
7640 }
7641
Craig Mautner2d5618c2012-10-18 13:55:47 -07007642 @Override
Dianne Hackborn672cf452013-03-26 15:24:24 -07007643 public void getBaseDisplaySize(int displayId, Point size) {
7644 synchronized (mWindowMap) {
7645 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Jeff Browna506a6e2013-06-04 00:02:38 -07007646 if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
Dianne Hackborn672cf452013-03-26 15:24:24 -07007647 synchronized(displayContent.mDisplaySizeLock) {
7648 size.x = displayContent.mBaseDisplayWidth;
7649 size.y = displayContent.mBaseDisplayHeight;
7650 }
7651 }
7652 }
7653 }
7654
7655 @Override
Jeff Brown43aa1592012-09-10 17:36:31 -07007656 public void setForcedDisplaySize(int displayId, int width, int height) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08007657 if (mContext.checkCallingOrSelfPermission(
7658 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7659 PackageManager.PERMISSION_GRANTED) {
7660 throw new SecurityException("Must hold permission " +
7661 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7662 }
7663 if (displayId != Display.DEFAULT_DISPLAY) {
7664 throw new IllegalArgumentException("Can only set the default display");
7665 }
Dianne Hackborn0cca3db2013-10-23 10:23:39 -07007666 final long ident = Binder.clearCallingIdentity();
7667 try {
7668 synchronized(mWindowMap) {
7669 // Set some sort of reasonable bounds on the size of the display that we
7670 // will try to emulate.
7671 final int MIN_WIDTH = 200;
7672 final int MIN_HEIGHT = 200;
7673 final int MAX_SCALE = 2;
7674 final DisplayContent displayContent = getDisplayContentLocked(displayId);
7675 if (displayContent != null) {
7676 width = Math.min(Math.max(width, MIN_WIDTH),
7677 displayContent.mInitialDisplayWidth * MAX_SCALE);
7678 height = Math.min(Math.max(height, MIN_HEIGHT),
7679 displayContent.mInitialDisplayHeight * MAX_SCALE);
7680 setForcedDisplaySizeLocked(displayContent, width, height);
7681 Settings.Global.putString(mContext.getContentResolver(),
7682 Settings.Global.DISPLAY_SIZE_FORCED, width + "," + height);
7683 }
Craig Mautner2d5618c2012-10-18 13:55:47 -07007684 }
Dianne Hackborn0cca3db2013-10-23 10:23:39 -07007685 } finally {
7686 Binder.restoreCallingIdentity(ident);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007687 }
7688 }
7689
Dianne Hackborndde331c2012-08-03 14:01:57 -07007690 private void readForcedDisplaySizeAndDensityLocked(final DisplayContent displayContent) {
Colin Crossef96fd92013-07-18 17:09:56 -07007691 String sizeStr = Settings.Global.getString(mContext.getContentResolver(),
Jeff Brown43aa1592012-09-10 17:36:31 -07007692 Settings.Global.DISPLAY_SIZE_FORCED);
Dianne Hackborn635a6d52013-07-29 17:15:38 -07007693 if (sizeStr == null || sizeStr.length() == 0) {
Colin Crossef96fd92013-07-18 17:09:56 -07007694 sizeStr = SystemProperties.get(SIZE_OVERRIDE, null);
7695 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007696 if (sizeStr != null && sizeStr.length() > 0) {
7697 final int pos = sizeStr.indexOf(',');
7698 if (pos > 0 && sizeStr.lastIndexOf(',') == pos) {
7699 int width, height;
7700 try {
7701 width = Integer.parseInt(sizeStr.substring(0, pos));
7702 height = Integer.parseInt(sizeStr.substring(pos+1));
7703 synchronized(displayContent.mDisplaySizeLock) {
7704 if (displayContent.mBaseDisplayWidth != width
7705 || displayContent.mBaseDisplayHeight != height) {
Dianne Hackborndde331c2012-08-03 14:01:57 -07007706 Slog.i(TAG, "FORCED DISPLAY SIZE: " + width + "x" + height);
7707 displayContent.mBaseDisplayWidth = width;
7708 displayContent.mBaseDisplayHeight = height;
7709 }
7710 }
7711 } catch (NumberFormatException ex) {
7712 }
7713 }
Joe Onorato571ae902011-05-24 13:48:43 -07007714 }
Colin Crossef96fd92013-07-18 17:09:56 -07007715 String densityStr = Settings.Global.getString(mContext.getContentResolver(),
Jeff Brown43aa1592012-09-10 17:36:31 -07007716 Settings.Global.DISPLAY_DENSITY_FORCED);
Dianne Hackborn635a6d52013-07-29 17:15:38 -07007717 if (densityStr == null || densityStr.length() == 0) {
Colin Crossef96fd92013-07-18 17:09:56 -07007718 densityStr = SystemProperties.get(DENSITY_OVERRIDE, null);
7719 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007720 if (densityStr != null && densityStr.length() > 0) {
7721 int density;
7722 try {
7723 density = Integer.parseInt(densityStr);
7724 synchronized(displayContent.mDisplaySizeLock) {
7725 if (displayContent.mBaseDisplayDensity != density) {
Dianne Hackborndde331c2012-08-03 14:01:57 -07007726 Slog.i(TAG, "FORCED DISPLAY DENSITY: " + density);
7727 displayContent.mBaseDisplayDensity = density;
7728 }
7729 }
7730 } catch (NumberFormatException ex) {
7731 }
Joe Onorato571ae902011-05-24 13:48:43 -07007732 }
Joe Onorato571ae902011-05-24 13:48:43 -07007733 }
7734
Craig Mautner2d5618c2012-10-18 13:55:47 -07007735 // displayContent must not be null
Craig Mautner59c00972012-07-30 12:10:24 -07007736 private void setForcedDisplaySizeLocked(DisplayContent displayContent, int width, int height) {
Joe Onorato571ae902011-05-24 13:48:43 -07007737 Slog.i(TAG, "Using new display size: " + width + "x" + height);
7738
Craig Mautner59c00972012-07-30 12:10:24 -07007739 synchronized(displayContent.mDisplaySizeLock) {
7740 displayContent.mBaseDisplayWidth = width;
7741 displayContent.mBaseDisplayHeight = height;
Dianne Hackborn1fbee792011-11-30 11:29:58 -08007742 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007743 reconfigureDisplayLocked(displayContent);
7744 }
7745
Craig Mautner2d5618c2012-10-18 13:55:47 -07007746 @Override
Dianne Hackborndde331c2012-08-03 14:01:57 -07007747 public void clearForcedDisplaySize(int displayId) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08007748 if (mContext.checkCallingOrSelfPermission(
7749 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7750 PackageManager.PERMISSION_GRANTED) {
7751 throw new SecurityException("Must hold permission " +
7752 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7753 }
7754 if (displayId != Display.DEFAULT_DISPLAY) {
7755 throw new IllegalArgumentException("Can only set the default display");
7756 }
Dianne Hackborn0cca3db2013-10-23 10:23:39 -07007757 final long ident = Binder.clearCallingIdentity();
7758 try {
7759 synchronized(mWindowMap) {
7760 final DisplayContent displayContent = getDisplayContentLocked(displayId);
7761 if (displayContent != null) {
7762 setForcedDisplaySizeLocked(displayContent, displayContent.mInitialDisplayWidth,
7763 displayContent.mInitialDisplayHeight);
7764 Settings.Global.putString(mContext.getContentResolver(),
7765 Settings.Global.DISPLAY_SIZE_FORCED, "");
7766 }
Craig Mautner2d5618c2012-10-18 13:55:47 -07007767 }
Dianne Hackborn0cca3db2013-10-23 10:23:39 -07007768 } finally {
7769 Binder.restoreCallingIdentity(ident);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007770 }
7771 }
7772
Craig Mautner2d5618c2012-10-18 13:55:47 -07007773 @Override
Dianne Hackborn672cf452013-03-26 15:24:24 -07007774 public int getInitialDisplayDensity(int displayId) {
7775 synchronized (mWindowMap) {
7776 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Jeff Browna506a6e2013-06-04 00:02:38 -07007777 if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
Dianne Hackborn672cf452013-03-26 15:24:24 -07007778 synchronized(displayContent.mDisplaySizeLock) {
7779 return displayContent.mInitialDisplayDensity;
7780 }
7781 }
7782 }
7783 return -1;
7784 }
7785
7786 @Override
7787 public int getBaseDisplayDensity(int displayId) {
7788 synchronized (mWindowMap) {
7789 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Jeff Browna506a6e2013-06-04 00:02:38 -07007790 if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
Dianne Hackborn672cf452013-03-26 15:24:24 -07007791 synchronized(displayContent.mDisplaySizeLock) {
7792 return displayContent.mBaseDisplayDensity;
7793 }
7794 }
7795 }
7796 return -1;
7797 }
7798
7799 @Override
Dianne Hackborndde331c2012-08-03 14:01:57 -07007800 public void setForcedDisplayDensity(int displayId, int density) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08007801 if (mContext.checkCallingOrSelfPermission(
7802 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7803 PackageManager.PERMISSION_GRANTED) {
7804 throw new SecurityException("Must hold permission " +
7805 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7806 }
7807 if (displayId != Display.DEFAULT_DISPLAY) {
7808 throw new IllegalArgumentException("Can only set the default display");
7809 }
Dianne Hackborn0cca3db2013-10-23 10:23:39 -07007810 final long ident = Binder.clearCallingIdentity();
7811 try {
7812 synchronized(mWindowMap) {
7813 final DisplayContent displayContent = getDisplayContentLocked(displayId);
7814 if (displayContent != null) {
7815 setForcedDisplayDensityLocked(displayContent, density);
7816 Settings.Global.putString(mContext.getContentResolver(),
7817 Settings.Global.DISPLAY_DENSITY_FORCED, Integer.toString(density));
7818 }
Craig Mautner2d5618c2012-10-18 13:55:47 -07007819 }
Dianne Hackborn0cca3db2013-10-23 10:23:39 -07007820 } finally {
7821 Binder.restoreCallingIdentity(ident);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007822 }
7823 }
7824
Craig Mautner2d5618c2012-10-18 13:55:47 -07007825 // displayContent must not be null
Dianne Hackborndde331c2012-08-03 14:01:57 -07007826 private void setForcedDisplayDensityLocked(DisplayContent displayContent, int density) {
7827 Slog.i(TAG, "Using new display density: " + density);
7828
7829 synchronized(displayContent.mDisplaySizeLock) {
7830 displayContent.mBaseDisplayDensity = density;
7831 }
7832 reconfigureDisplayLocked(displayContent);
7833 }
7834
Craig Mautner2d5618c2012-10-18 13:55:47 -07007835 @Override
Dianne Hackborndde331c2012-08-03 14:01:57 -07007836 public void clearForcedDisplayDensity(int displayId) {
Dianne Hackbornc652de82013-02-15 16:32:56 -08007837 if (mContext.checkCallingOrSelfPermission(
7838 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7839 PackageManager.PERMISSION_GRANTED) {
7840 throw new SecurityException("Must hold permission " +
7841 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7842 }
7843 if (displayId != Display.DEFAULT_DISPLAY) {
7844 throw new IllegalArgumentException("Can only set the default display");
7845 }
Dianne Hackborn0cca3db2013-10-23 10:23:39 -07007846 final long ident = Binder.clearCallingIdentity();
7847 try {
7848 synchronized(mWindowMap) {
7849 final DisplayContent displayContent = getDisplayContentLocked(displayId);
7850 if (displayContent != null) {
7851 setForcedDisplayDensityLocked(displayContent,
7852 displayContent.mInitialDisplayDensity);
7853 Settings.Global.putString(mContext.getContentResolver(),
7854 Settings.Global.DISPLAY_DENSITY_FORCED, "");
7855 }
Craig Mautner2d5618c2012-10-18 13:55:47 -07007856 }
Dianne Hackborn0cca3db2013-10-23 10:23:39 -07007857 } finally {
7858 Binder.restoreCallingIdentity(ident);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007859 }
7860 }
7861
Craig Mautner2d5618c2012-10-18 13:55:47 -07007862 // displayContent must not be null
Dianne Hackborndde331c2012-08-03 14:01:57 -07007863 private void reconfigureDisplayLocked(DisplayContent displayContent) {
Craig Mautner69b08182012-09-05 13:07:13 -07007864 // TODO: Multidisplay: for now only use with default display.
Jeff Brownef981a42013-08-07 14:13:37 -07007865 configureDisplayPolicyLocked(displayContent);
Craig Mautner19d59bc2012-09-04 11:15:56 -07007866 displayContent.layoutNeeded = true;
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007867
7868 boolean configChanged = updateOrientationFromAppTokensLocked(false);
7869 mTempConfiguration.setToDefaults();
7870 mTempConfiguration.fontScale = mCurConfiguration.fontScale;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08007871 if (computeScreenConfigurationLocked(mTempConfiguration)) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007872 if (mCurConfiguration.diff(mTempConfiguration) != 0) {
7873 configChanged = true;
7874 }
7875 }
7876
7877 if (configChanged) {
7878 mWaitingForConfig = true;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007879 startFreezingDisplayLocked(false, 0, 0);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007880 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
7881 }
7882
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007883 performLayoutAndPlaceSurfacesLocked();
7884 }
7885
Jeff Brownef981a42013-08-07 14:13:37 -07007886 private void configureDisplayPolicyLocked(DisplayContent displayContent) {
7887 mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
7888 displayContent.mBaseDisplayWidth,
7889 displayContent.mBaseDisplayHeight,
7890 displayContent.mBaseDisplayDensity);
7891
7892 DisplayInfo displayInfo = displayContent.getDisplayInfo();
7893 mPolicy.setDisplayOverscan(displayContent.getDisplay(),
7894 displayInfo.overscanLeft, displayInfo.overscanTop,
7895 displayInfo.overscanRight, displayInfo.overscanBottom);
7896 }
7897
Craig Mautner11bf9a52013-02-19 14:08:51 -08007898 @Override
Dianne Hackbornc652de82013-02-15 16:32:56 -08007899 public void setOverscan(int displayId, int left, int top, int right, int bottom) {
7900 if (mContext.checkCallingOrSelfPermission(
7901 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7902 PackageManager.PERMISSION_GRANTED) {
7903 throw new SecurityException("Must hold permission " +
7904 android.Manifest.permission.WRITE_SECURE_SETTINGS);
7905 }
Dianne Hackborn0cca3db2013-10-23 10:23:39 -07007906 final long ident = Binder.clearCallingIdentity();
7907 try {
7908 synchronized(mWindowMap) {
7909 DisplayContent displayContent = getDisplayContentLocked(displayId);
7910 if (displayContent != null) {
7911 setOverscanLocked(displayContent, left, top, right, bottom);
7912 }
Dianne Hackbornc652de82013-02-15 16:32:56 -08007913 }
Dianne Hackborn0cca3db2013-10-23 10:23:39 -07007914 } finally {
7915 Binder.restoreCallingIdentity(ident);
Dianne Hackbornc652de82013-02-15 16:32:56 -08007916 }
7917 }
7918
Jeff Brownef981a42013-08-07 14:13:37 -07007919 private void setOverscanLocked(DisplayContent displayContent,
7920 int left, int top, int right, int bottom) {
7921 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
7922 synchronized (displayContent.mDisplaySizeLock) {
7923 displayInfo.overscanLeft = left;
7924 displayInfo.overscanTop = top;
7925 displayInfo.overscanRight = right;
7926 displayInfo.overscanBottom = bottom;
7927 }
7928
7929 mDisplaySettings.setOverscanLocked(displayInfo.name, left, top, right, bottom);
7930 mDisplaySettings.writeSettingsLocked();
7931
7932 reconfigureDisplayLocked(displayContent);
7933 }
7934
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007935 // -------------------------------------------------------------
7936 // Internals
7937 // -------------------------------------------------------------
7938
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007939 final WindowState windowForClientLocked(Session session, IWindow client,
7940 boolean throwOnError) {
7941 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007942 }
Romain Guy06882f82009-06-10 13:36:04 -07007943
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007944 final WindowState windowForClientLocked(Session session, IBinder client,
7945 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007946 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007947 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007948 TAG, "Looking up client " + client + ": " + win);
7949 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007950 RuntimeException ex = new IllegalArgumentException(
7951 "Requested window " + client + " does not exist");
7952 if (throwOnError) {
7953 throw ex;
7954 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007955 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007956 return null;
7957 }
7958 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007959 RuntimeException ex = new IllegalArgumentException(
7960 "Requested window " + client + " is in session " +
7961 win.mSession + ", not " + session);
7962 if (throwOnError) {
7963 throw ex;
7964 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007965 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007966 return null;
7967 }
7968
7969 return win;
7970 }
7971
Dianne Hackborna8f60182009-09-01 19:01:50 -07007972 final void rebuildAppWindowListLocked() {
Craig Mautner85689b92013-10-02 14:52:13 -07007973 rebuildAppWindowListLocked(getDefaultDisplayContentLocked());
Craig Mautner59c00972012-07-30 12:10:24 -07007974 }
7975
7976 private void rebuildAppWindowListLocked(final DisplayContent displayContent) {
7977 final WindowList windows = displayContent.getWindowList();
7978 int NW = windows.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07007979 int i;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07007980 int lastBelow = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007981 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007982
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007983 if (mRebuildTmp.length < NW) {
7984 mRebuildTmp = new WindowState[NW+10];
7985 }
7986
Dianne Hackborna8f60182009-09-01 19:01:50 -07007987 // First remove all existing app windows.
7988 i=0;
7989 while (i < NW) {
Craig Mautner59c00972012-07-30 12:10:24 -07007990 WindowState w = windows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007991 if (w.mAppToken != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07007992 WindowState win = windows.remove(i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007993 win.mRebuilding = true;
7994 mRebuildTmp[numRemoved] = win;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007995 mWindowsChanged = true;
Craig Mautnerde4ef022013-04-07 19:01:33 -07007996 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07007997 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007998 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07007999 continue;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008000 } else if (lastBelow == i-1) {
Craig Mautner65d11b32012-10-01 13:59:52 -07008001 if (w.mAttrs.type == TYPE_WALLPAPER || w.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008002 lastBelow = i;
8003 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07008004 }
8005 i++;
8006 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008007
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008008 // Keep whatever windows were below the app windows still below,
8009 // by skipping them.
8010 lastBelow++;
8011 i = lastBelow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008012
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008013 // First add all of the exiting app tokens... these are no longer
8014 // in the main app list, but still have windows shown. We put them
8015 // in the back because now that the animation is over we no longer
8016 // will care about them.
Craig Mautnerdc548482014-02-05 13:35:24 -08008017 final ArrayList<TaskStack> stacks = displayContent.getStacks();
8018 final int numStacks = stacks.size();
8019 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
8020 AppTokenList exitingAppTokens = stacks.get(stackNdx).mExitingAppTokens;
8021 int NT = exitingAppTokens.size();
8022 for (int j = 0; j < NT; j++) {
8023 i = reAddAppWindowsLocked(displayContent, i, exitingAppTokens.get(j));
8024 }
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008025 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008026
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008027 // And add in the still active app tokens in Z order.
Craig Mautnerdc548482014-02-05 13:35:24 -08008028 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
8029 final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
8030 final int numTasks = tasks.size();
8031 for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
8032 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
8033 final int numTokens = tokens.size();
8034 for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
8035 final AppWindowToken wtoken = tokens.get(tokenNdx);
Craig Mautnerac90c192014-02-12 12:37:17 -08008036 if (wtoken.mDeferRemoval) {
8037 continue;
8038 }
Craig Mautnerdc548482014-02-05 13:35:24 -08008039 i = reAddAppWindowsLocked(displayContent, i, wtoken);
8040 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08008041 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07008042 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008043
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008044 i -= lastBelow;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008045 if (i != numRemoved) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08008046 Slog.w(TAG, "On display=" + displayContent.getDisplayId() + " Rebuild removed " +
8047 numRemoved + " windows but added " + i,
Craig Mautner9e4f28c2013-04-03 10:53:23 -07008048 new RuntimeException("here").fillInStackTrace());
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008049 for (i=0; i<numRemoved; i++) {
8050 WindowState ws = mRebuildTmp[i];
8051 if (ws.mRebuilding) {
8052 StringWriter sw = new StringWriter();
Dianne Hackborn8c841092013-06-24 13:46:13 -07008053 PrintWriter pw = new FastPrintWriter(sw, false, 1024);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07008054 ws.dump(pw, "", true);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008055 pw.flush();
8056 Slog.w(TAG, "This window was lost: " + ws);
8057 Slog.w(TAG, sw.toString());
Craig Mautner96868332012-12-04 14:29:11 -08008058 ws.mWinAnimator.destroySurfaceLocked();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008059 }
8060 }
8061 Slog.w(TAG, "Current app token list:");
Craig Mautner496bdbb2013-02-14 09:32:55 -08008062 dumpAppTokensLocked();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008063 Slog.w(TAG, "Final window list:");
8064 dumpWindowsLocked();
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008065 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07008066 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008067
Craig Mautner59c00972012-07-30 12:10:24 -07008068 private final void assignLayersLocked(WindowList windows) {
8069 int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008070 int curBaseLayer = 0;
8071 int curLayer = 0;
8072 int i;
Romain Guy06882f82009-06-10 13:36:04 -07008073
Craig Mautner018be3d2013-08-27 13:25:17 -07008074 if (DEBUG_LAYERS) Slog.v(TAG, "Assigning layers based on windows=" + windows,
8075 new RuntimeException("here").fillInStackTrace());
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08008076
Svetoslav Ganov55468c62012-10-15 15:09:02 -07008077 boolean anyLayerChanged = false;
8078
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008079 for (i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07008080 final WindowState w = windows.get(i);
Craig Mautneracafd192012-05-10 10:41:02 -07008081 final WindowStateAnimator winAnimator = w.mWinAnimator;
8082 boolean layerChanged = false;
8083 int oldLayer = w.mLayer;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008084 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
8085 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008086 curLayer += WINDOW_LAYER_MULTIPLIER;
8087 w.mLayer = curLayer;
8088 } else {
8089 curBaseLayer = curLayer = w.mBaseLayer;
8090 w.mLayer = curLayer;
8091 }
Craig Mautneracafd192012-05-10 10:41:02 -07008092 if (w.mLayer != oldLayer) {
8093 layerChanged = true;
Svetoslav Ganov55468c62012-10-15 15:09:02 -07008094 anyLayerChanged = true;
Craig Mautneracafd192012-05-10 10:41:02 -07008095 }
Craig Mautnerf7666462013-04-28 08:58:21 -07008096 final AppWindowToken wtoken = w.mAppToken;
Craig Mautneracafd192012-05-10 10:41:02 -07008097 oldLayer = winAnimator.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008098 if (w.mTargetAppToken != null) {
Craig Mautneracafd192012-05-10 10:41:02 -07008099 winAnimator.mAnimLayer =
Craig Mautner59431632012-04-04 11:56:44 -07008100 w.mLayer + w.mTargetAppToken.mAppAnimator.animLayerAdjustment;
Craig Mautnerf7666462013-04-28 08:58:21 -07008101 } else if (wtoken != null) {
Craig Mautneracafd192012-05-10 10:41:02 -07008102 winAnimator.mAnimLayer =
Craig Mautnerf7666462013-04-28 08:58:21 -07008103 w.mLayer + wtoken.mAppAnimator.animLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008104 } else {
Craig Mautneracafd192012-05-10 10:41:02 -07008105 winAnimator.mAnimLayer = w.mLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008106 }
8107 if (w.mIsImWindow) {
Craig Mautneracafd192012-05-10 10:41:02 -07008108 winAnimator.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008109 } else if (w.mIsWallpaper) {
Craig Mautneracafd192012-05-10 10:41:02 -07008110 winAnimator.mAnimLayer += mWallpaperAnimLayerAdjustment;
8111 }
8112 if (winAnimator.mAnimLayer != oldLayer) {
8113 layerChanged = true;
Svetoslav Ganov55468c62012-10-15 15:09:02 -07008114 anyLayerChanged = true;
Craig Mautneracafd192012-05-10 10:41:02 -07008115 }
Craig Mautner05d29032013-05-03 13:40:13 -07008116 if (layerChanged && w.getStack().isDimming(winAnimator)) {
8117 // Force an animation pass just to update the mDimLayer layer.
Craig Mautner96868332012-12-04 14:29:11 -08008118 scheduleAnimationLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008119 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008120 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
Craig Mautner8863cca2012-09-18 15:04:34 -07008121 + "mBase=" + w.mBaseLayer
8122 + " mLayer=" + w.mLayer
Craig Mautnerf7666462013-04-28 08:58:21 -07008123 + (wtoken == null ?
8124 "" : " mAppLayer=" + wtoken.mAppAnimator.animLayerAdjustment)
Craig Mautner8863cca2012-09-18 15:04:34 -07008125 + " =mAnimLayer=" + winAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008126 //System.out.println(
8127 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
8128 }
Svetoslav Ganov55468c62012-10-15 15:09:02 -07008129
Svetoslav Ganov545252f2012-12-10 18:29:24 -08008130 //TODO (multidisplay): Magnification is supported only for the default display.
Svetoslav8e3feb12014-02-24 13:46:47 -08008131 if (mAccessibilityController != null && anyLayerChanged
Svetoslav Ganov545252f2012-12-10 18:29:24 -08008132 && windows.get(windows.size() - 1).getDisplayId() == Display.DEFAULT_DISPLAY) {
Svetoslav8e3feb12014-02-24 13:46:47 -08008133 mAccessibilityController.onWindowLayersChangedLocked();
Svetoslav Ganov55468c62012-10-15 15:09:02 -07008134 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008135 }
8136
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008137 private final void performLayoutAndPlaceSurfacesLocked() {
Dianne Hackborn7ad44382012-10-18 17:46:00 -07008138 int loopCount = 6;
Craig Mautnera13a41d2012-10-16 12:53:13 -07008139 do {
8140 mTraversalScheduled = false;
8141 performLayoutAndPlaceSurfacesLockedLoop();
8142 mH.removeMessages(H.DO_TRAVERSAL);
Dianne Hackborn7ad44382012-10-18 17:46:00 -07008143 loopCount--;
8144 } while (mTraversalScheduled && loopCount > 0);
Craig Mautner96868332012-12-04 14:29:11 -08008145 mInnerFields.mWallpaperActionPending = false;
Craig Mautnera13a41d2012-10-16 12:53:13 -07008146 }
8147
8148 private boolean mInLayout = false;
8149 private final void performLayoutAndPlaceSurfacesLockedLoop() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008150 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07008151 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008152 throw new RuntimeException("Recursive call!");
8153 }
Craig Mautneref25d7a2012-05-15 23:01:47 -07008154 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
8155 + Debug.getCallers(3));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008156 return;
8157 }
8158
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008159 if (mWaitingForConfig) {
8160 // Our configuration has changed (most likely rotation), but we
8161 // don't yet have the complete configuration to report to
8162 // applications. Don't do any window layout until we have it.
8163 return;
8164 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08008165
Jeff Browne215f262012-09-10 16:01:14 -07008166 if (!mDisplayReady) {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008167 // Not yet initialized, nothing to do.
8168 return;
8169 }
8170
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07008171 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008172 mInLayout = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008173 boolean recoveringMemory = false;
Craig Mautner6cfa7292013-01-15 09:05:42 -08008174
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008175 try {
8176 if (mForceRemoves != null) {
8177 recoveringMemory = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008178 // Wait a little bit for things to settle down, and off we go.
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008179 for (int i=0; i<mForceRemoves.size(); i++) {
8180 WindowState ws = mForceRemoves.get(i);
8181 Slog.i(TAG, "Force removing: " + ws);
8182 removeWindowInnerLocked(ws.mSession, ws);
8183 }
8184 mForceRemoves = null;
8185 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
8186 Object tmp = new Object();
8187 synchronized (tmp) {
8188 try {
8189 tmp.wait(250);
8190 } catch (InterruptedException e) {
8191 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008192 }
8193 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008194 } catch (RuntimeException e) {
Dianne Hackborn89620282011-09-11 12:47:45 -07008195 Log.wtf(TAG, "Unhandled exception while force removing for memory", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008196 }
Craig Mautner59c00972012-07-30 12:10:24 -07008197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008198 try {
Craig Mautner76a71652012-09-03 23:23:58 -07008199 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Craig Mautnerbb1449b2012-03-23 16:11:14 -07008200
Craig Mautner59c00972012-07-30 12:10:24 -07008201 mInLayout = false;
8202
Craig Mautner19d59bc2012-09-04 11:15:56 -07008203 if (needsLayout()) {
Craig Mautnerbb1449b2012-03-23 16:11:14 -07008204 if (++mLayoutRepeatCount < 6) {
8205 requestTraversalLocked();
8206 } else {
8207 Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
8208 mLayoutRepeatCount = 0;
8209 }
8210 } else {
8211 mLayoutRepeatCount = 0;
8212 }
Craig Mautnerbb1449b2012-03-23 16:11:14 -07008213
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008214 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008215 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
You Kimcb6291c2012-12-04 23:22:28 +09008216 mH.sendEmptyMessage(H.REPORT_WINDOWS_CHANGE);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008217 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008218 } catch (RuntimeException e) {
8219 mInLayout = false;
Dianne Hackborn89620282011-09-11 12:47:45 -07008220 Log.wtf(TAG, "Unhandled exception while laying out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008221 }
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07008222
8223 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008224 }
8225
Craig Mautner59c00972012-07-30 12:10:24 -07008226 private final void performLayoutLockedInner(final DisplayContent displayContent,
8227 boolean initial, boolean updateInputWindows) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07008228 if (!displayContent.layoutNeeded) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008229 return;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008230 }
Craig Mautner19d59bc2012-09-04 11:15:56 -07008231 displayContent.layoutNeeded = false;
Craig Mautner59c00972012-07-30 12:10:24 -07008232 WindowList windows = displayContent.getWindowList();
Craig Mautner69b08182012-09-05 13:07:13 -07008233 boolean isDefaultDisplay = displayContent.isDefaultDisplay;
Craig Mautner59c00972012-07-30 12:10:24 -07008234
8235 DisplayInfo displayInfo = displayContent.getDisplayInfo();
8236 final int dw = displayInfo.logicalWidth;
8237 final int dh = displayInfo.logicalHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008238
Dianne Hackborndf89e652011-10-06 22:35:11 -07008239 final int NFW = mFakeWindows.size();
8240 for (int i=0; i<NFW; i++) {
8241 mFakeWindows.get(i).layout(dw, dh);
8242 }
8243
Craig Mautner59c00972012-07-30 12:10:24 -07008244 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008245 int i;
8246
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008247 if (DEBUG_LAYOUT) {
8248 Slog.v(TAG, "-------------------------------------");
8249 Slog.v(TAG, "performLayout: needed="
Craig Mautner19d59bc2012-09-04 11:15:56 -07008250 + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008251 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008252
8253 WindowStateAnimator universeBackground = null;
8254
Craig Mautner69b08182012-09-05 13:07:13 -07008255 mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mRotation);
8256 if (isDefaultDisplay) {
8257 // Not needed on non-default displays.
John Spurlock46646232013-09-30 22:32:42 -04008258 mSystemDecorLayer = mPolicy.getSystemDecorLayerLw();
Craig Mautner69b08182012-09-05 13:07:13 -07008259 mScreenRect.set(0, 0, dw, dh);
8260 }
Romain Guy06882f82009-06-10 13:36:04 -07008261
John Spurlock4e92a7c2013-09-24 17:09:05 -04008262 mPolicy.getContentRectLw(mTmpContentRect);
Craig Mautnered6649f2013-12-02 14:08:25 -08008263 displayContent.resize(mTmpContentRect);
Craig Mautner967212c2013-04-13 21:10:58 -07008264
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008265 int seq = mLayoutSeq+1;
8266 if (seq < 0) seq = 0;
8267 mLayoutSeq = seq;
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008268
8269 boolean behindDream = false;
8270
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008271 // First perform layout of any root windows (not attached
8272 // to another window).
8273 int topAttached = -1;
8274 for (i = N-1; i >= 0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07008275 final WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008276
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008277 // Don't do layout of a window if it is not visible, or
8278 // soon won't be visible, to avoid wasting time and funky
8279 // changes while a window is animating away.
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008280 final boolean gone = (behindDream && mPolicy.canBeForceHidden(win, win.mAttrs))
Craig Mautnerae446592012-12-06 19:05:05 -08008281 || win.isGoneForLayoutLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008282
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008283 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008284 Slog.v(TAG, "1ST PASS " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008285 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
Craig Mautner812d2ca2012-09-27 15:35:34 -07008286 + " mLayoutAttached=" + win.mLayoutAttached
Craig Mautnera3f4bf52012-10-10 20:37:48 -07008287 + " screen changed=" + win.isConfigChanged());
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008288 final AppWindowToken atoken = win.mAppToken;
8289 if (gone) Slog.v(TAG, " GONE: mViewVisibility="
8290 + win.mViewVisibility + " mRelayoutCalled="
8291 + win.mRelayoutCalled + " hidden="
8292 + win.mRootToken.hidden + " hiddenRequested="
8293 + (atoken != null && atoken.hiddenRequested)
8294 + " mAttachedHidden=" + win.mAttachedHidden);
8295 else Slog.v(TAG, " VIS: mViewVisibility="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008296 + win.mViewVisibility + " mRelayoutCalled="
8297 + win.mRelayoutCalled + " hidden="
8298 + win.mRootToken.hidden + " hiddenRequested="
8299 + (atoken != null && atoken.hiddenRequested)
8300 + " mAttachedHidden=" + win.mAttachedHidden);
8301 }
Craig Mautner69b08182012-09-05 13:07:13 -07008302
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008303 // If this view is GONE, then skip it -- keep the current
8304 // frame, and let the caller know so they can ignore it
8305 // if they want. (We do the normal layout for INVISIBLE
8306 // windows, since that means "perform layout as normal,
8307 // just don't display").
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008308 if (!gone || !win.mHaveFrame || win.mLayoutNeeded
Craig Mautner4c5eb222013-11-18 12:59:05 -08008309 || ((win.isConfigChanged() || win.setInsetsChanged()) &&
8310 (win.mAttrs.type == TYPE_KEYGUARD ||
8311 win.mAppToken != null && win.mAppToken.layoutConfigChanges))
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008312 || win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008313 if (!win.mLayoutAttached) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008314 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08008315 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008316 win.mContentChanged = false;
8317 }
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008318 if (win.mAttrs.type == TYPE_DREAM) {
8319 // Don't layout windows behind a dream, so that if it
8320 // does stuff like hide the status bar we won't get a
8321 // bad transition when it goes away.
8322 behindDream = true;
8323 }
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008324 win.mLayoutNeeded = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008325 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008326 mPolicy.layoutWindowLw(win, win.mAttrs, null);
8327 win.mLayoutSeq = seq;
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008328 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008329 + win.mFrame + " mContainingFrame="
8330 + win.mContainingFrame + " mDisplayFrame="
8331 + win.mDisplayFrame);
8332 } else {
8333 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008334 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07008335 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008336 if (win.mViewVisibility == View.VISIBLE
8337 && win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND
8338 && universeBackground == null) {
8339 universeBackground = win.mWinAnimator;
8340 }
8341 }
8342
8343 if (mAnimator.mUniverseBackground != universeBackground) {
8344 mFocusMayChange = true;
8345 mAnimator.mUniverseBackground = universeBackground;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008346 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008347
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008348 boolean attachedBehindDream = false;
8349
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008350 // Now perform layout of attached windows, which usually
8351 // depend on the position of the window they are attached to.
8352 // XXX does not deal with windows that are attached to windows
8353 // that are themselves attached.
8354 for (i = topAttached; i >= 0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07008355 final WindowState win = windows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008356
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008357 if (win.mLayoutAttached) {
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008358 if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008359 + " mHaveFrame=" + win.mHaveFrame
8360 + " mViewVisibility=" + win.mViewVisibility
8361 + " mRelayoutCalled=" + win.mRelayoutCalled);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008362 // If this view is GONE, then skip it -- keep the current
8363 // frame, and let the caller know so they can ignore it
8364 // if they want. (We do the normal layout for INVISIBLE
8365 // windows, since that means "perform layout as normal,
8366 // just don't display").
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008367 if (attachedBehindDream && mPolicy.canBeForceHidden(win, win.mAttrs)) {
8368 continue;
8369 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008370 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008371 || !win.mHaveFrame || win.mLayoutNeeded) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008372 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08008373 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008374 win.mContentChanged = false;
8375 }
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008376 win.mLayoutNeeded = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008377 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008378 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
8379 win.mLayoutSeq = seq;
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008380 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008381 + win.mFrame + " mContainingFrame="
8382 + win.mContainingFrame + " mDisplayFrame="
8383 + win.mDisplayFrame);
8384 }
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008385 } else if (win.mAttrs.type == TYPE_DREAM) {
8386 // Don't layout windows behind a dream, so that if it
8387 // does stuff like hide the status bar we won't get a
8388 // bad transition when it goes away.
8389 attachedBehindDream = behindDream;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008390 }
8391 }
Craig Mautner6cfa7292013-01-15 09:05:42 -08008392
Jeff Brown349703e2010-06-22 01:27:15 -07008393 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown3a22cd92011-01-21 13:59:04 -08008394 mInputMonitor.setUpdateInputWindowsNeededLw();
8395 if (updateInputWindows) {
Jeff Brown2e44b072011-01-24 15:21:56 -08008396 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08008397 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008398
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008399 mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008400 }
Romain Guy06882f82009-06-10 13:36:04 -07008401
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008402 void makeWindowFreezingScreenIfNeededLocked(WindowState w) {
8403 // If the screen is currently frozen or off, then keep
8404 // it frozen/off until this window draws at its new
8405 // orientation.
Craig Mautner2fb98b12012-03-20 17:24:00 -07008406 if (!okToDisplay()) {
Craig Mautner34b73df2014-01-12 21:11:08 -08008407 if (DEBUG_ORIENTATION) Slog.v(TAG, "Changing surface while display frozen: " + w);
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008408 w.mOrientationChanging = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -07008409 w.mLastFreezeDuration = 0;
Craig Mautner3255a282012-04-16 15:42:47 -07008410 mInnerFields.mOrientationChangeComplete = false;
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008411 if (!mWindowsFreezingScreen) {
8412 mWindowsFreezingScreen = true;
8413 // XXX should probably keep timeout from
8414 // when we first froze the display.
8415 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
Craig Mautner6cfa7292013-01-15 09:05:42 -08008416 mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT,
You Kimcb6291c2012-12-04 23:22:28 +09008417 WINDOW_FREEZE_TIMEOUT_DURATION);
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008418 }
8419 }
8420 }
8421
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008422 /**
8423 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
Craig Mautner19d59bc2012-09-04 11:15:56 -07008424 * @param windows List of windows on default display.
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008425 * @return bitmap indicating if another pass through layout must be made.
8426 */
Craig Mautner59c00972012-07-30 12:10:24 -07008427 public int handleAppTransitionReadyLocked(WindowList windows) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008428 int changes = 0;
8429 int i;
8430 int NN = mOpeningApps.size();
8431 boolean goodToGo = true;
8432 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8433 "Checking " + NN + " opening apps (frozen="
8434 + mDisplayFrozen + " timeout="
Craig Mautner164d4bb2012-11-26 13:51:23 -08008435 + mAppTransition.isTimeout() + ")...");
8436 if (!mDisplayFrozen && !mAppTransition.isTimeout()) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008437 // If the display isn't frozen, wait to do anything until
8438 // all of the apps are ready. Otherwise just go because
8439 // we'll unfreeze the display when everyone is ready.
8440 for (i=0; i<NN && goodToGo; i++) {
8441 AppWindowToken wtoken = mOpeningApps.get(i);
8442 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Craig Mautner1d961d42012-05-27 12:02:11 -07008443 "Check opening app=" + wtoken + ": allDrawn="
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008444 + wtoken.allDrawn + " startingDisplayed="
Craig Mautner7358fbf2012-04-12 21:06:33 -07008445 + wtoken.startingDisplayed + " startingMoved="
8446 + wtoken.startingMoved);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008447 if (!wtoken.allDrawn && !wtoken.startingDisplayed
8448 && !wtoken.startingMoved) {
8449 goodToGo = false;
8450 }
8451 }
8452 }
8453 if (goodToGo) {
8454 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
Craig Mautner164d4bb2012-11-26 13:51:23 -08008455 int transit = mAppTransition.getAppTransition();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008456 if (mSkipAppTransitionAnimation) {
Craig Mautner4b71aa12012-12-27 17:20:01 -08008457 transit = AppTransition.TRANSIT_UNSET;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008458 }
Craig Mautner164d4bb2012-11-26 13:51:23 -08008459 mAppTransition.goodToGo();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008460 mStartingIconInTransition = false;
8461 mSkipAppTransitionAnimation = false;
8462
8463 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
8464
Craig Mautneref25d7a2012-05-15 23:01:47 -07008465 rebuildAppWindowListLocked();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008466
Craig Mautner0afddcb2012-05-08 15:38:00 -07008467 // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
Craig Mautner83339b42012-05-01 22:13:23 -07008468 WindowState oldWallpaper =
8469 mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
Craig Mautner0afddcb2012-05-08 15:38:00 -07008470 && !mWallpaperTarget.mWinAnimator.isDummyAnimation()
Craig Mautner83339b42012-05-01 22:13:23 -07008471 ? null : mWallpaperTarget;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008472
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008473 mInnerFields.mWallpaperMayChange = false;
8474
8475 // The top-most window will supply the layout params,
8476 // and we will determine it below.
8477 LayoutParams animLp = null;
8478 int bestAnimLayer = -1;
8479 boolean fullscreenAnim = false;
8480
8481 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8482 "New wallpaper target=" + mWallpaperTarget
Daniel Sandlerab886f52012-06-04 14:36:25 -04008483 + ", oldWallpaper=" + oldWallpaper
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008484 + ", lower target=" + mLowerWallpaperTarget
8485 + ", upper target=" + mUpperWallpaperTarget);
Craig Mautnerae446592012-12-06 19:05:05 -08008486
8487 boolean openingAppHasWallpaper = false;
8488 boolean closingAppHasWallpaper = false;
8489 final AppWindowToken lowerWallpaperAppToken;
8490 final AppWindowToken upperWallpaperAppToken;
8491 if (mLowerWallpaperTarget == null) {
8492 lowerWallpaperAppToken = upperWallpaperAppToken = null;
8493 } else {
8494 lowerWallpaperAppToken = mLowerWallpaperTarget.mAppToken;
8495 upperWallpaperAppToken = mUpperWallpaperTarget.mAppToken;
8496 }
8497
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008498 // Do a first pass through the tokens for two
8499 // things:
8500 // (1) Determine if both the closing and opening
8501 // app token sets are wallpaper targets, in which
8502 // case special animations are needed
8503 // (since the wallpaper needs to stay static
8504 // behind them).
8505 // (2) Find the layout params of the top-most
8506 // application window in the tokens, which is
8507 // what will control the animation theme.
8508 final int NC = mClosingApps.size();
8509 NN = NC + mOpeningApps.size();
8510 for (i=0; i<NN; i++) {
Craig Mautnerae446592012-12-06 19:05:05 -08008511 final AppWindowToken wtoken;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008512 if (i < NC) {
8513 wtoken = mClosingApps.get(i);
Craig Mautnerae446592012-12-06 19:05:05 -08008514 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
8515 closingAppHasWallpaper = true;
8516 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008517 } else {
Craig Mautnerae446592012-12-06 19:05:05 -08008518 wtoken = mOpeningApps.get(i - NC);
8519 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
8520 openingAppHasWallpaper = true;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008521 }
8522 }
Craig Mautnerae446592012-12-06 19:05:05 -08008523
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008524 if (wtoken.appFullscreen) {
8525 WindowState ws = wtoken.findMainWindow();
8526 if (ws != null) {
8527 animLp = ws.mAttrs;
8528 bestAnimLayer = ws.mLayer;
8529 fullscreenAnim = true;
8530 }
8531 } else if (!fullscreenAnim) {
8532 WindowState ws = wtoken.findMainWindow();
8533 if (ws != null) {
8534 if (ws.mLayer > bestAnimLayer) {
8535 animLp = ws.mAttrs;
8536 bestAnimLayer = ws.mLayer;
8537 }
8538 }
8539 }
8540 }
8541
Craig Mautner798adef2013-10-22 14:29:01 -07008542 mAnimateWallpaperWithTarget = false;
Craig Mautnerae446592012-12-06 19:05:05 -08008543 if (closingAppHasWallpaper && openingAppHasWallpaper) {
8544 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Wallpaper animation!");
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008545 switch (transit) {
Craig Mautner4b71aa12012-12-27 17:20:01 -08008546 case AppTransition.TRANSIT_ACTIVITY_OPEN:
8547 case AppTransition.TRANSIT_TASK_OPEN:
8548 case AppTransition.TRANSIT_TASK_TO_FRONT:
8549 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008550 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08008551 case AppTransition.TRANSIT_ACTIVITY_CLOSE:
8552 case AppTransition.TRANSIT_TASK_CLOSE:
8553 case AppTransition.TRANSIT_TASK_TO_BACK:
8554 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008555 break;
8556 }
Craig Mautnerae446592012-12-06 19:05:05 -08008557 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "New transit: " + transit);
Adam Lesinski76afd1f2013-10-23 10:45:28 -07008558 } else if ((oldWallpaper != null) && !mOpeningApps.isEmpty()
8559 && !mOpeningApps.contains(oldWallpaper.mAppToken)) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008560 // We are transitioning from an activity with
8561 // a wallpaper to one without.
Craig Mautner4b71aa12012-12-27 17:20:01 -08008562 transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008563 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8564 "New transit away from wallpaper: " + transit);
Craig Mautner8863cca2012-09-18 15:04:34 -07008565 } else if (mWallpaperTarget != null && mWallpaperTarget.isVisibleLw()) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008566 // We are transitioning from an activity without
8567 // a wallpaper to now showing the wallpaper
Craig Mautner4b71aa12012-12-27 17:20:01 -08008568 transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008569 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8570 "New transit into wallpaper: " + transit);
Craig Mautner798adef2013-10-22 14:29:01 -07008571 } else {
8572 mAnimateWallpaperWithTarget = true;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008573 }
8574
8575 // If all closing windows are obscured, then there is
8576 // no need to do an animation. This is the case, for
8577 // example, when this transition is being done behind
8578 // the lock screen.
8579 if (!mPolicy.allowAppAnimationsLw()) {
Craig Mautner28816302013-10-10 20:31:00 -07008580 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8581 "Animations disallowed by keyguard or dream.");
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008582 animLp = null;
8583 }
8584
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008585 AppWindowToken topOpeningApp = null;
8586 int topOpeningLayer = 0;
8587
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008588 NN = mOpeningApps.size();
8589 for (i=0; i<NN; i++) {
8590 AppWindowToken wtoken = mOpeningApps.get(i);
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008591 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Craig Mautnerbec53f72012-04-05 11:49:05 -07008592 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008593 appAnimator.clearThumbnail();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008594 wtoken.inPendingTransaction = false;
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008595 appAnimator.animation = null;
Craig Mautnerbec53f72012-04-05 11:49:05 -07008596 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008597 wtoken.updateReportedVisibilityLocked();
8598 wtoken.waitingToShow = false;
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008599
8600 appAnimator.mAllAppWinAnimators.clear();
8601 final int N = wtoken.allAppWindows.size();
8602 for (int j = 0; j < N; j++) {
8603 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
8604 }
8605 mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
8606
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008607 if (animLp != null) {
8608 int layer = -1;
8609 for (int j=0; j<wtoken.windows.size(); j++) {
8610 WindowState win = wtoken.windows.get(j);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07008611 if (win.mWinAnimator.mAnimLayer > layer) {
8612 layer = win.mWinAnimator.mAnimLayer;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008613 }
8614 }
8615 if (topOpeningApp == null || layer > topOpeningLayer) {
8616 topOpeningApp = wtoken;
8617 topOpeningLayer = layer;
8618 }
8619 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008620 }
8621 NN = mClosingApps.size();
8622 for (i=0; i<NN; i++) {
8623 AppWindowToken wtoken = mClosingApps.get(i);
Craig Mautner28816302013-10-10 20:31:00 -07008624 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
Craig Mautner59431632012-04-04 11:56:44 -07008625 wtoken.mAppAnimator.clearThumbnail();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008626 wtoken.inPendingTransaction = false;
Craig Mautner59431632012-04-04 11:56:44 -07008627 wtoken.mAppAnimator.animation = null;
Adam Lesinski76afd1f2013-10-23 10:45:28 -07008628 setTokenVisibilityLocked(wtoken, animLp, false, transit, false);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008629 wtoken.updateReportedVisibilityLocked();
8630 wtoken.waitingToHide = false;
8631 // Force the allDrawn flag, because we want to start
8632 // this guy's animations regardless of whether it's
8633 // gotten drawn.
8634 wtoken.allDrawn = true;
Craig Mautner7636dfb2012-11-16 15:24:11 -08008635 wtoken.deferClearAllDrawn = false;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008636 }
8637
Winson Chung399f6202014-03-19 10:47:20 -07008638 boolean useAlternateThumbnailAnimation =
8639 SystemProperties.getBoolean("persist.anim.use_alt_thumbnail", false);
Craig Mautner164d4bb2012-11-26 13:51:23 -08008640 AppWindowAnimator appAnimator =
8641 topOpeningApp == null ? null : topOpeningApp.mAppAnimator;
8642 Bitmap nextAppTransitionThumbnail = mAppTransition.getNextAppTransitionThumbnail();
Winson Chung399f6202014-03-19 10:47:20 -07008643 if (!useAlternateThumbnailAnimation && nextAppTransitionThumbnail != null
8644 && appAnimator != null && appAnimator.animation != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008645 // This thumbnail animation is very special, we need to have
8646 // an extra surface with the thumbnail included with the animation.
Craig Mautner164d4bb2012-11-26 13:51:23 -08008647 Rect dirty = new Rect(0, 0, nextAppTransitionThumbnail.getWidth(),
8648 nextAppTransitionThumbnail.getHeight());
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008649 try {
Jeff Browne215f262012-09-10 16:01:14 -07008650 // TODO(multi-display): support other displays
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008651 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07008652 final Display display = displayContent.getDisplay();
Mathias Agopian29479eb2013-02-14 14:36:04 -08008653 SurfaceControl surfaceControl = new SurfaceControl(mFxSession,
Jeff Brown64a55af2012-08-26 02:47:39 -07008654 "thumbnail anim",
Craig Mautner6881a102012-07-27 13:04:51 -07008655 dirty.width(), dirty.height(),
Mathias Agopian3866f0d2013-02-11 22:08:48 -08008656 PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
Mathias Agopian29479eb2013-02-14 14:36:04 -08008657 surfaceControl.setLayerStack(display.getLayerStack());
8658 appAnimator.thumbnail = surfaceControl;
8659 if (SHOW_TRANSACTIONS) Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008660 Surface drawSurface = new Surface();
Mathias Agopian29479eb2013-02-14 14:36:04 -08008661 drawSurface.copyFrom(surfaceControl);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008662 Canvas c = drawSurface.lockCanvas(dirty);
Craig Mautner164d4bb2012-11-26 13:51:23 -08008663 c.drawBitmap(nextAppTransitionThumbnail, 0, 0, null);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008664 drawSurface.unlockCanvasAndPost(c);
8665 drawSurface.release();
Craig Mautner164d4bb2012-11-26 13:51:23 -08008666 appAnimator.thumbnailLayer = topOpeningLayer;
8667 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Winson Chung399f6202014-03-19 10:47:20 -07008668 Animation anim = mAppTransition.createThumbnailScaleAnimationLocked(
8669 displayInfo.appWidth, displayInfo.appHeight, transit);
Craig Mautner164d4bb2012-11-26 13:51:23 -08008670 appAnimator.thumbnailAnimation = anim;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008671 anim.restrictDuration(MAX_ANIMATION_DURATION);
8672 anim.scaleCurrentDuration(mTransitionAnimationScale);
Craig Mautner164d4bb2012-11-26 13:51:23 -08008673 Point p = new Point();
8674 mAppTransition.getStartingPoint(p);
8675 appAnimator.thumbnailX = p.x;
8676 appAnimator.thumbnailY = p.y;
Igor Murashkina86ab6402013-08-30 12:58:36 -07008677 } catch (OutOfResourcesException e) {
8678 Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w=" + dirty.width()
Mathias Agopian3866f0d2013-02-11 22:08:48 -08008679 + " h=" + dirty.height(), e);
8680 appAnimator.clearThumbnail();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008681 }
8682 }
8683
Craig Mautner164d4bb2012-11-26 13:51:23 -08008684 mAppTransition.postAnimationCallback();
8685 mAppTransition.clear();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008686
8687 mOpeningApps.clear();
8688 mClosingApps.clear();
8689
8690 // This has changed the visibility of windows, so perform
8691 // a new layout to get them all up-to-date.
Craig Mautner39834192012-09-02 07:47:24 -07008692 changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008693 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008694 getDefaultDisplayContentLocked().layoutNeeded = true;
Craig Mautner59c00972012-07-30 12:10:24 -07008695
8696 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008697 if (windows == getDefaultWindowListLocked()
8698 && !moveInputMethodWindowsIfNeededLocked(true)) {
Craig Mautner59c00972012-07-30 12:10:24 -07008699 assignLayersLocked(windows);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008700 }
Craig Mautner59c00972012-07-30 12:10:24 -07008701 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, false /*updateInputWindows*/);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008702 mFocusMayChange = false;
8703 }
8704
8705 return changes;
8706 }
8707
8708 /**
8709 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008710 * @return bitmap indicating if another pass through layout must be made.
8711 */
Craig Mautner2f995a72012-02-21 09:53:21 -08008712 private int handleAnimatingStoppedAndTransitionLocked() {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008713 int changes = 0;
8714
Craig Mautner9a29a5d2012-12-27 19:03:40 -08008715 mAppTransition.setIdle();
Craig Mautneref25d7a2012-05-15 23:01:47 -07008716 // Restore window app tokens to the ActivityManager views
Craig Mautnerdc548482014-02-05 13:35:24 -08008717 ArrayList<TaskStack> stacks = getDefaultDisplayContentLocked().getStacks();
8718 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
8719 final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
8720 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
8721 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
8722 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
8723 tokens.get(tokenNdx).sendingToBottom = false;
8724 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08008725 }
Craig Mautner3f99fde2012-06-19 14:10:01 -07008726 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008727 rebuildAppWindowListLocked();
Craig Mautneref25d7a2012-05-15 23:01:47 -07008728
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008729 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Craig Mautnerae446592012-12-06 19:05:05 -08008730 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
8731 "Wallpaper layer changed: assigning layers + relayout");
Craig Mautneref25d7a2012-05-15 23:01:47 -07008732 moveInputMethodWindowsIfNeededLocked(true);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008733 mInnerFields.mWallpaperMayChange = true;
8734 // Since the window list has been rebuilt, focus might
8735 // have to be recomputed since the actual order of windows
8736 // might have changed again.
8737 mFocusMayChange = true;
8738
8739 return changes;
8740 }
8741
Craig Mautnere32c3072012-03-12 15:25:35 -07008742 private void updateResizingWindows(final WindowState w) {
Craig Mautnera608b882012-03-30 13:03:49 -07008743 final WindowStateAnimator winAnimator = w.mWinAnimator;
Craig Mautnerade0a9a2012-10-06 13:55:07 -07008744 if (w.mHasSurface && w.mLayoutSeq == mLayoutSeq) {
Craig Mautner4c5eb222013-11-18 12:59:05 -08008745 w.setInsetsChanged();
Craig Mautner812d2ca2012-09-27 15:35:34 -07008746 boolean configChanged = w.isConfigChanged();
Craig Mautnere32c3072012-03-12 15:25:35 -07008747 if (DEBUG_CONFIGURATION && configChanged) {
8748 Slog.v(TAG, "Win " + w + " config changed: "
8749 + mCurConfiguration);
8750 }
8751 if (localLOGV) Slog.v(TAG, "Resizing " + w
8752 + ": configChanged=" + configChanged
8753 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
8754 w.mLastFrame.set(w.mFrame);
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07008755 if (w.mContentInsetsChanged
Craig Mautnere32c3072012-03-12 15:25:35 -07008756 || w.mVisibleInsetsChanged
Craig Mautnera608b882012-03-30 13:03:49 -07008757 || winAnimator.mSurfaceResized
Craig Mautnere32c3072012-03-12 15:25:35 -07008758 || configChanged) {
8759 if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
Craig Mautnerc5a6e442013-06-05 17:22:35 -07008760 Slog.v(TAG, "Resize reasons for w=" + w + ": "
Craig Mautnere32c3072012-03-12 15:25:35 -07008761 + " contentInsetsChanged=" + w.mContentInsetsChanged
Craig Mautnerae446592012-12-06 19:05:05 -08008762 + " " + w.mContentInsets.toShortString()
Craig Mautnere32c3072012-03-12 15:25:35 -07008763 + " visibleInsetsChanged=" + w.mVisibleInsetsChanged
Craig Mautnerae446592012-12-06 19:05:05 -08008764 + " " + w.mVisibleInsets.toShortString()
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008765 + " surfaceResized=" + winAnimator.mSurfaceResized
Craig Mautnere32c3072012-03-12 15:25:35 -07008766 + " configChanged=" + configChanged);
8767 }
8768
Dianne Hackbornc4aad012013-02-22 15:05:25 -08008769 w.mLastOverscanInsets.set(w.mOverscanInsets);
Craig Mautnere32c3072012-03-12 15:25:35 -07008770 w.mLastContentInsets.set(w.mContentInsets);
8771 w.mLastVisibleInsets.set(w.mVisibleInsets);
8772 makeWindowFreezingScreenIfNeededLocked(w);
8773 // If the orientation is changing, then we need to
8774 // hold off on unfreezing the display until this
8775 // window has been redrawn; to do that, we need
8776 // to go through the process of getting informed
8777 // by the application when it has finished drawing.
8778 if (w.mOrientationChanging) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07008779 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautner83339b42012-05-01 22:13:23 -07008780 "Orientation start waiting for draw mDrawState=DRAW_PENDING in "
Mathias Agopian29479eb2013-02-14 14:36:04 -08008781 + w + ", surface " + winAnimator.mSurfaceControl);
Craig Mautner749a7bb2012-04-02 13:49:53 -07008782 winAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
Craig Mautnere32c3072012-03-12 15:25:35 -07008783 if (w.mAppToken != null) {
8784 w.mAppToken.allDrawn = false;
Craig Mautner7636dfb2012-11-16 15:24:11 -08008785 w.mAppToken.deferClearAllDrawn = false;
Craig Mautnere32c3072012-03-12 15:25:35 -07008786 }
8787 }
8788 if (!mResizingWindows.contains(w)) {
8789 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008790 "Resizing window " + w + " to " + winAnimator.mSurfaceW
8791 + "x" + winAnimator.mSurfaceH);
Craig Mautnere32c3072012-03-12 15:25:35 -07008792 mResizingWindows.add(w);
8793 }
8794 } else if (w.mOrientationChanging) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07008795 if (w.isDrawnLw()) {
Craig Mautnere32c3072012-03-12 15:25:35 -07008796 if (DEBUG_ORIENTATION) Slog.v(TAG,
8797 "Orientation not waiting for draw in "
Mathias Agopian29479eb2013-02-14 14:36:04 -08008798 + w + ", surface " + winAnimator.mSurfaceControl);
Craig Mautnere32c3072012-03-12 15:25:35 -07008799 w.mOrientationChanging = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07008800 w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
8801 - mDisplayFreezeTime);
Craig Mautnere32c3072012-03-12 15:25:35 -07008802 }
8803 }
8804 }
8805 }
8806
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008807 /**
8808 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
8809 *
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008810 * @param w WindowState this method is applied to.
8811 * @param currentTime The time which animations use for calculating transitions.
8812 * @param innerDw Width of app window.
8813 * @param innerDh Height of app window.
8814 */
8815 private void handleNotObscuredLocked(final WindowState w, final long currentTime,
8816 final int innerDw, final int innerDh) {
8817 final WindowManager.LayoutParams attrs = w.mAttrs;
8818 final int attrFlags = attrs.flags;
8819 final boolean canBeSeen = w.isDisplayedLw();
Jeff Brown4fd79172013-11-07 17:58:15 -08008820 final boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
8821
8822 if (opaqueDrawn && w.isFullscreen(innerDw, innerDh)) {
8823 // This window completely covers everything behind it,
8824 // so we want to leave all of them as undimmed (for
8825 // performance reasons).
8826 mInnerFields.mObscured = true;
8827 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008828
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07008829 if (w.mHasSurface) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008830 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
8831 mInnerFields.mHoldScreen = w.mSession;
8832 }
8833 if (!mInnerFields.mSyswin && w.mAttrs.screenBrightness >= 0
8834 && mInnerFields.mScreenBrightness < 0) {
8835 mInnerFields.mScreenBrightness = w.mAttrs.screenBrightness;
8836 }
8837 if (!mInnerFields.mSyswin && w.mAttrs.buttonBrightness >= 0
8838 && mInnerFields.mButtonBrightness < 0) {
8839 mInnerFields.mButtonBrightness = w.mAttrs.buttonBrightness;
8840 }
Jeff Brown1e3b98d2012-09-30 18:58:59 -07008841 if (!mInnerFields.mSyswin && w.mAttrs.userActivityTimeout >= 0
8842 && mInnerFields.mUserActivityTimeout < 0) {
8843 mInnerFields.mUserActivityTimeout = w.mAttrs.userActivityTimeout;
8844 }
8845
Craig Mautner65d11b32012-10-01 13:59:52 -07008846 final int type = attrs.type;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008847 if (canBeSeen
Craig Mautner65d11b32012-10-01 13:59:52 -07008848 && (type == TYPE_SYSTEM_DIALOG
Craig Mautner88400d32012-09-30 12:35:45 -07008849 || type == TYPE_RECENTS_OVERLAY
Craig Mautner65d11b32012-10-01 13:59:52 -07008850 || type == TYPE_KEYGUARD
8851 || type == TYPE_SYSTEM_ERROR)) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008852 mInnerFields.mSyswin = true;
8853 }
Craig Mautner65d11b32012-10-01 13:59:52 -07008854
8855 if (canBeSeen) {
Jeff Brown4fd79172013-11-07 17:58:15 -08008856 // This function assumes that the contents of the default display are
8857 // processed first before secondary displays.
Craig Mautnerdf88d732014-01-27 09:21:32 -08008858 final DisplayContent displayContent = w.getDisplayContent();
8859 if (displayContent != null && displayContent.isDefaultDisplay) {
Jeff Brown4fd79172013-11-07 17:58:15 -08008860 // While a dream or keyguard is showing, obscure ordinary application
8861 // content on secondary displays (by forcibly enabling mirroring unless
8862 // there is other content we want to show) but still allow opaque
8863 // keyguard dialogs to be shown.
8864 if (type == TYPE_DREAM || type == TYPE_KEYGUARD) {
8865 mInnerFields.mObscureApplicationContentOnSecondaryDisplays = true;
8866 }
8867 mInnerFields.mDisplayHasContent = true;
Craig Mautnerdf88d732014-01-27 09:21:32 -08008868 } else if (displayContent != null &&
8869 (!mInnerFields.mObscureApplicationContentOnSecondaryDisplays
8870 || (mInnerFields.mObscured && type == TYPE_KEYGUARD_DIALOG))) {
Jeff Brown4fd79172013-11-07 17:58:15 -08008871 // Allow full screen keyguard presentation dialogs to be seen.
8872 mInnerFields.mDisplayHasContent = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07008873 }
8874 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008875 }
Craig Mautner312eac42012-11-13 10:56:22 -08008876 }
8877
Craig Mautnerdc548482014-02-05 13:35:24 -08008878 private void handleFlagDimBehind(WindowState w) {
Craig Mautner312eac42012-11-13 10:56:22 -08008879 final WindowManager.LayoutParams attrs = w.mAttrs;
8880 if ((attrs.flags & FLAG_DIM_BEHIND) != 0
8881 && w.isDisplayedLw()
Craig Mautner236a35b2012-06-08 09:54:59 -07008882 && !w.mExiting) {
Craig Mautner312eac42012-11-13 10:56:22 -08008883 final WindowStateAnimator winAnimator = w.mWinAnimator;
Craig Mautner05d29032013-05-03 13:40:13 -07008884 final TaskStack stack = w.getStack();
8885 stack.setDimmingTag();
8886 if (!stack.isDimming(winAnimator)) {
Craig Mautner312eac42012-11-13 10:56:22 -08008887 if (localLOGV) Slog.v(TAG, "Win " + w + " start dimming.");
Craig Mautner05d29032013-05-03 13:40:13 -07008888 stack.startDimmingIfNeeded(winAnimator);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008889 }
8890 }
8891 }
8892
Craig Mautnerb1fd65c2013-02-05 13:34:57 -08008893 private void updateAllDrawnLocked(DisplayContent displayContent) {
Craig Mautner6fbda632012-07-03 09:26:39 -07008894 // See if any windows have been drawn, so they (and others
8895 // associated with them) can now be shown.
Craig Mautnerdc548482014-02-05 13:35:24 -08008896 ArrayList<TaskStack> stacks = displayContent.getStacks();
8897 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
8898 final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
8899 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
8900 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
8901 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
8902 final AppWindowToken wtoken = tokens.get(tokenNdx);
8903 if (!wtoken.allDrawn) {
8904 int numInteresting = wtoken.numInterestingWindows;
8905 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
8906 if (DEBUG_VISIBILITY) Slog.v(TAG,
8907 "allDrawn: " + wtoken
8908 + " interesting=" + numInteresting
8909 + " drawn=" + wtoken.numDrawnWindows);
8910 wtoken.allDrawn = true;
8911 mH.obtainMessage(H.NOTIFY_ACTIVITY_DRAWN, wtoken.token).sendToTarget();
8912 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08008913 }
Craig Mautner6fbda632012-07-03 09:26:39 -07008914 }
8915 }
8916 }
8917 }
8918
Brad Fitzpatrick68044332010-11-22 18:19:48 -08008919 // "Something has changed! Let's make it correct now."
Craig Mautner76a71652012-09-03 23:23:58 -07008920 private final void performLayoutAndPlaceSurfacesLockedInner(boolean recoveringMemory) {
Craig Mautner7d8df392012-04-06 15:26:23 -07008921 if (DEBUG_WINDOW_TRACE) {
Craig Mautner3255a282012-04-16 15:42:47 -07008922 Slog.v(TAG, "performLayoutAndPlaceSurfacesLockedInner: entry. Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -07008923 + Debug.getCallers(3));
Craig Mautner7d8df392012-04-06 15:26:23 -07008924 }
Joe Onorato34bcebc2010-07-07 18:05:01 -04008925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008926 final long currentTime = SystemClock.uptimeMillis();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008927
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008928 int i;
8929
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008930 if (mFocusMayChange) {
8931 mFocusMayChange = false;
Jeff Brown3a22cd92011-01-21 13:59:04 -08008932 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
8933 false /*updateInputWindows*/);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008934 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008936 // Initialize state of exiting tokens.
Craig Mautnerf8924152013-07-16 09:10:55 -07008937 final int numDisplays = mDisplayContents.size();
8938 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
8939 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautnerb1fd65c2013-02-05 13:34:57 -08008940 for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {
8941 displayContent.mExitingTokens.get(i).hasVisible = false;
8942 }
Craig Mautnerdc548482014-02-05 13:35:24 -08008943 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008944
Craig Mautnerdc548482014-02-05 13:35:24 -08008945 for (int stackNdx = mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
Craig Mautnerb1fd65c2013-02-05 13:34:57 -08008946 // Initialize state of exiting applications.
Craig Mautnerdc548482014-02-05 13:35:24 -08008947 final AppTokenList exitingAppTokens =
8948 mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
8949 for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
8950 exitingAppTokens.get(tokenNdx).hasVisible = false;
Craig Mautnerb1fd65c2013-02-05 13:34:57 -08008951 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008952 }
8953
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008954 mInnerFields.mHoldScreen = null;
8955 mInnerFields.mScreenBrightness = -1;
8956 mInnerFields.mButtonBrightness = -1;
Jeff Brown1e3b98d2012-09-30 18:58:59 -07008957 mInnerFields.mUserActivityTimeout = -1;
Jeff Brown4fd79172013-11-07 17:58:15 -08008958 mInnerFields.mObscureApplicationContentOnSecondaryDisplays = false;
Jeff Brown1e3b98d2012-09-30 18:58:59 -07008959
Craig Mautner6fbda632012-07-03 09:26:39 -07008960 mTransactionSequence++;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07008961
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008962 final DisplayContent defaultDisplay = getDefaultDisplayContentLocked();
Craig Mautner76a71652012-09-03 23:23:58 -07008963 final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
8964 final int defaultDw = defaultInfo.logicalWidth;
8965 final int defaultDh = defaultInfo.logicalHeight;
Craig Mautner76a71652012-09-03 23:23:58 -07008966
Dianne Hackborn36991742011-10-11 21:35:26 -07008967 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
8968 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
Mathias Agopian3866f0d2013-02-11 22:08:48 -08008969 SurfaceControl.openTransaction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008970 try {
Craig Mautner76a71652012-09-03 23:23:58 -07008971
Jeff Brown4ed8fe72012-08-30 18:18:29 -07008972 if (mWatermark != null) {
Craig Mautner76a71652012-09-03 23:23:58 -07008973 mWatermark.positionSurface(defaultDw, defaultDh);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07008974 }
8975 if (mStrictModeFlash != null) {
Craig Mautner76a71652012-09-03 23:23:58 -07008976 mStrictModeFlash.positionSurface(defaultDw, defaultDh);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07008977 }
8978
Craig Mautner7358fbf2012-04-12 21:06:33 -07008979 boolean focusDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008980
Craig Mautnerf8924152013-07-16 09:10:55 -07008981 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
8982 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautnerb1fd65c2013-02-05 13:34:57 -08008983 boolean updateAllDrawn = false;
Craig Mautner76a71652012-09-03 23:23:58 -07008984 WindowList windows = displayContent.getWindowList();
8985 DisplayInfo displayInfo = displayContent.getDisplayInfo();
Craig Mautner19d59bc2012-09-04 11:15:56 -07008986 final int displayId = displayContent.getDisplayId();
Craig Mautner76a71652012-09-03 23:23:58 -07008987 final int dw = displayInfo.logicalWidth;
8988 final int dh = displayInfo.logicalHeight;
8989 final int innerDw = displayInfo.appWidth;
8990 final int innerDh = displayInfo.appHeight;
Craig Mautner19d59bc2012-09-04 11:15:56 -07008991 final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008992
Jeff Brown4fd79172013-11-07 17:58:15 -08008993 // Reset for each display.
8994 mInnerFields.mDisplayHasContent = false;
Craig Mautner65d11b32012-10-01 13:59:52 -07008995
Craig Mautner76a71652012-09-03 23:23:58 -07008996 int repeats = 0;
8997 do {
8998 repeats++;
8999 if (repeats > 6) {
9000 Slog.w(TAG, "Animation repeat aborted after too many iterations");
Craig Mautner76a71652012-09-03 23:23:58 -07009001 displayContent.layoutNeeded = false;
9002 break;
Craig Mautner5702d4d2012-06-30 14:10:16 -07009003 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009004
Craig Mautner76a71652012-09-03 23:23:58 -07009005 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("On entry to LockedInner",
9006 displayContent.pendingLayoutChanges);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009007
Craig Mautner0bf6ec92012-12-18 08:33:27 -08009008 if ((displayContent.pendingLayoutChanges &
9009 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
9010 (adjustWallpaperWindowsLocked() &
9011 ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Craig Mautner76a71652012-09-03 23:23:58 -07009012 assignLayersLocked(windows);
Craig Mautner76a71652012-09-03 23:23:58 -07009013 displayContent.layoutNeeded = true;
9014 }
9015
9016 if (isDefaultDisplay && (displayContent.pendingLayoutChanges
9017 & WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
9018 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
9019 if (updateOrientationFromAppTokensLocked(true)) {
Craig Mautner76a71652012-09-03 23:23:58 -07009020 displayContent.layoutNeeded = true;
9021 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009022 }
9023 }
9024
Craig Mautner76a71652012-09-03 23:23:58 -07009025 if ((displayContent.pendingLayoutChanges
9026 & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
Craig Mautner76a71652012-09-03 23:23:58 -07009027 displayContent.layoutNeeded = true;
Craig Mautner6fbda632012-07-03 09:26:39 -07009028 }
Craig Mautner76a71652012-09-03 23:23:58 -07009029
9030 // FIRST LOOP: Perform a layout, if needed.
9031 if (repeats < 4) {
9032 performLayoutLockedInner(displayContent, repeats == 1,
9033 false /*updateInputWindows*/);
9034 } else {
9035 Slog.w(TAG, "Layout repeat skipped after too many iterations");
9036 }
9037
9038 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
9039 // it is animating.
9040 displayContent.pendingLayoutChanges = 0;
9041
9042 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("loop number "
9043 + mLayoutRepeatCount, displayContent.pendingLayoutChanges);
9044
Craig Mautner69b08182012-09-05 13:07:13 -07009045 if (isDefaultDisplay) {
9046 mPolicy.beginPostLayoutPolicyLw(dw, dh);
9047 for (i = windows.size() - 1; i >= 0; i--) {
9048 WindowState w = windows.get(i);
9049 if (w.mHasSurface) {
9050 mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs);
9051 }
Craig Mautner6fbda632012-07-03 09:26:39 -07009052 }
Craig Mautner69b08182012-09-05 13:07:13 -07009053 displayContent.pendingLayoutChanges |= mPolicy.finishPostLayoutPolicyLw();
9054 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
9055 "after finishPostLayoutPolicyLw", displayContent.pendingLayoutChanges);
Craig Mautner76a71652012-09-03 23:23:58 -07009056 }
Craig Mautner76a71652012-09-03 23:23:58 -07009057 } while (displayContent.pendingLayoutChanges != 0);
9058
9059 mInnerFields.mObscured = false;
Craig Mautner76a71652012-09-03 23:23:58 -07009060 mInnerFields.mSyswin = false;
Craig Mautner05d29032013-05-03 13:40:13 -07009061 displayContent.resetDimming();
Craig Mautner76a71652012-09-03 23:23:58 -07009062
9063 // Only used if default window
9064 final boolean someoneLosingFocus = !mLosingFocus.isEmpty();
9065
9066 final int N = windows.size();
9067 for (i=N-1; i>=0; i--) {
9068 WindowState w = windows.get(i);
Craig Mautnere0a38842013-12-16 16:14:02 -08009069 final TaskStack stack = w.getStack();
9070 if (stack == null) {
9071 continue;
9072 }
Craig Mautner76a71652012-09-03 23:23:58 -07009073
9074 final boolean obscuredChanged = w.mObscured != mInnerFields.mObscured;
9075
9076 // Update effect.
9077 w.mObscured = mInnerFields.mObscured;
9078 if (!mInnerFields.mObscured) {
9079 handleNotObscuredLocked(w, currentTime, innerDw, innerDh);
9080 }
9081
Craig Mautnere0a38842013-12-16 16:14:02 -08009082 if (!stack.testDimmingTag()) {
Craig Mautnerdc548482014-02-05 13:35:24 -08009083 handleFlagDimBehind(w);
Craig Mautner312eac42012-11-13 10:56:22 -08009084 }
9085
Craig Mautner76a71652012-09-03 23:23:58 -07009086 if (isDefaultDisplay && obscuredChanged && (mWallpaperTarget == w)
9087 && w.isVisibleLw()) {
9088 // This is the wallpaper target and its obscured state
9089 // changed... make sure the current wallaper's visibility
9090 // has been updated accordingly.
9091 updateWallpaperVisibilityLocked();
9092 }
9093
9094 final WindowStateAnimator winAnimator = w.mWinAnimator;
9095
9096 // If the window has moved due to its containing
9097 // content frame changing, then we'd like to animate
9098 // it.
9099 if (w.mHasSurface && w.shouldAnimateMove()) {
9100 // Frame has moved, containing content frame
9101 // has also moved, and we're not currently animating...
9102 // let's do something.
9103 Animation a = AnimationUtils.loadAnimation(mContext,
9104 com.android.internal.R.anim.window_move_from_decor);
9105 winAnimator.setAnimation(a);
9106 winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
9107 winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
9108 try {
9109 w.mClient.moved(w.mFrame.left, w.mFrame.top);
9110 } catch (RemoteException e) {
9111 }
9112 }
9113
9114 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
9115 w.mContentChanged = false;
9116
9117 // Moved from updateWindowsAndWallpaperLocked().
9118 if (w.mHasSurface) {
9119 // Take care of the window being ready to display.
Craig Mautner69b08182012-09-05 13:07:13 -07009120 final boolean committed =
9121 winAnimator.commitFinishDrawingLocked(currentTime);
9122 if (isDefaultDisplay && committed) {
Dianne Hackborn7ad44382012-10-18 17:46:00 -07009123 if (w.mAttrs.type == TYPE_DREAM) {
9124 // HACK: When a dream is shown, it may at that
9125 // point hide the lock screen. So we need to
9126 // redo the layout to let the phone window manager
9127 // make this happen.
9128 displayContent.pendingLayoutChanges |=
9129 WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
Craig Mautner11462cc2013-05-13 15:56:18 -07009130 if (DEBUG_LAYOUT_REPEATS) {
Dianne Hackborn7ad44382012-10-18 17:46:00 -07009131 debugLayoutRepeats(
9132 "dream and commitFinishDrawingLocked true",
9133 displayContent.pendingLayoutChanges);
9134 }
9135 }
Craig Mautner65d11b32012-10-01 13:59:52 -07009136 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07009137 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Craig Mautner76a71652012-09-03 23:23:58 -07009138 "First draw done in potential wallpaper target " + w);
9139 mInnerFields.mWallpaperMayChange = true;
9140 displayContent.pendingLayoutChanges |=
9141 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Craig Mautner11462cc2013-05-13 15:56:18 -07009142 if (DEBUG_LAYOUT_REPEATS) {
Craig Mautner76a71652012-09-03 23:23:58 -07009143 debugLayoutRepeats(
9144 "wallpaper and commitFinishDrawingLocked true",
9145 displayContent.pendingLayoutChanges);
Craig Mautner6fbda632012-07-03 09:26:39 -07009146 }
9147 }
Craig Mautner76a71652012-09-03 23:23:58 -07009148 }
9149
Craig Mautnera91f9e22012-09-14 16:22:08 -07009150 winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
Craig Mautner76a71652012-09-03 23:23:58 -07009151
9152 final AppWindowToken atoken = w.mAppToken;
Craig Mautner65d11b32012-10-01 13:59:52 -07009153 if (DEBUG_STARTING_WINDOW && atoken != null
9154 && w == atoken.startingWindow) {
Craig Mautner76a71652012-09-03 23:23:58 -07009155 Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen="
9156 + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
9157 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
9158 }
9159 if (atoken != null
9160 && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
9161 if (atoken.lastTransactionSequence != mTransactionSequence) {
9162 atoken.lastTransactionSequence = mTransactionSequence;
9163 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
9164 atoken.startingDisplayed = false;
9165 }
Craig Mautner65d11b32012-10-01 13:59:52 -07009166 if ((w.isOnScreen() || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
Craig Mautner76a71652012-09-03 23:23:58 -07009167 && !w.mExiting && !w.mDestroying) {
Craig Mautner11462cc2013-05-13 15:56:18 -07009168 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Craig Mautner76a71652012-09-03 23:23:58 -07009169 Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
9170 + ", isAnimating=" + winAnimator.isAnimating());
9171 if (!w.isDrawnLw()) {
Mathias Agopian29479eb2013-02-14 14:36:04 -08009172 Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceControl
Craig Mautner76a71652012-09-03 23:23:58 -07009173 + " pv=" + w.mPolicyVisibility
9174 + " mDrawState=" + winAnimator.mDrawState
9175 + " ah=" + w.mAttachedHidden
9176 + " th=" + atoken.hiddenRequested
9177 + " a=" + winAnimator.mAnimating);
Craig Mautner6fbda632012-07-03 09:26:39 -07009178 }
9179 }
Craig Mautner76a71652012-09-03 23:23:58 -07009180 if (w != atoken.startingWindow) {
9181 if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
9182 atoken.numInterestingWindows++;
9183 if (w.isDrawnLw()) {
9184 atoken.numDrawnWindows++;
Craig Mautner11462cc2013-05-13 15:56:18 -07009185 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautner76a71652012-09-03 23:23:58 -07009186 "tokenMayBeDrawn: " + atoken
9187 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen
9188 + " mAppFreezing=" + w.mAppFreezing);
9189 updateAllDrawn = true;
9190 }
9191 }
9192 } else if (w.isDrawnLw()) {
9193 atoken.startingDisplayed = true;
9194 }
Craig Mautner6fbda632012-07-03 09:26:39 -07009195 }
9196 }
9197 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009198
Craig Mautner76a71652012-09-03 23:23:58 -07009199 if (isDefaultDisplay && someoneLosingFocus && (w == mCurrentFocus)
9200 && w.isDisplayedLw()) {
9201 focusDisplayed = true;
9202 }
Craig Mautner51bb12b2012-04-27 14:39:53 -07009203
Craig Mautner76a71652012-09-03 23:23:58 -07009204 updateResizingWindows(w);
9205 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07009206
Jeff Brown4ccb8232014-01-16 22:16:42 -08009207 mDisplayManagerInternal.setDisplayHasContent(displayId,
Jeff Brown4fd79172013-11-07 17:58:15 -08009208 mInnerFields.mDisplayHasContent,
Craig Mautner65d11b32012-10-01 13:59:52 -07009209 true /* inTraversal, must call performTraversalInTrans... below */);
9210
Craig Mautner05d29032013-05-03 13:40:13 -07009211 getDisplayContentLocked(displayId).stopDimmingIfNeeded();
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009212
Craig Mautnerb1fd65c2013-02-05 13:34:57 -08009213 if (updateAllDrawn) {
9214 updateAllDrawnLocked(displayContent);
9215 }
Craig Mautner6fbda632012-07-03 09:26:39 -07009216 }
9217
Craig Mautner7358fbf2012-04-12 21:06:33 -07009218 if (focusDisplayed) {
9219 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
9220 }
Craig Mautner65d11b32012-10-01 13:59:52 -07009221
9222 // Give the display manager a chance to adjust properties
9223 // like display rotation if it needs to.
Jeff Brown4ccb8232014-01-16 22:16:42 -08009224 mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
Craig Mautner65d11b32012-10-01 13:59:52 -07009225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009226 } catch (RuntimeException e) {
Dianne Hackborn89620282011-09-11 12:47:45 -07009227 Log.wtf(TAG, "Unhandled exception in Window Manager", e);
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07009228 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -08009229 SurfaceControl.closeTransaction();
Chet Haased5d11af2012-10-31 08:57:17 -07009230 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
9231 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009232 }
9233
Craig Mautner76a71652012-09-03 23:23:58 -07009234 final WindowList defaultWindows = defaultDisplay.getWindowList();
9235
Craig Mautner764983d2012-03-22 11:37:36 -07009236 // If we are ready to perform an app transition, check through
9237 // all of the app tokens to be shown and see if they are ready
9238 // to go.
Craig Mautner164d4bb2012-11-26 13:51:23 -08009239 if (mAppTransition.isReady()) {
Craig Mautner76a71652012-09-03 23:23:58 -07009240 defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009241 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAppTransitionReadyLocked",
Craig Mautnerae446592012-12-06 19:05:05 -08009242 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009243 }
9244
Craig Mautner164d4bb2012-11-26 13:51:23 -08009245 if (!mAnimator.mAnimating && mAppTransition.isRunning()) {
Craig Mautner764983d2012-03-22 11:37:36 -07009246 // We have finished the animation of an app transition. To do
9247 // this, we have delayed a lot of operations like showing and
9248 // hiding apps, moving apps in Z-order, etc. The app token list
9249 // reflects the correct Z-order, but the window list may now
9250 // be out of sync with it. So here we will just rebuild the
9251 // entire app window list. Fun!
Craig Mautner76a71652012-09-03 23:23:58 -07009252 defaultDisplay.pendingLayoutChanges |= handleAnimatingStoppedAndTransitionLocked();
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009253 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAnimStopAndXitionLock",
Craig Mautner76a71652012-09-03 23:23:58 -07009254 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009255 }
9256
Craig Mautner76a71652012-09-03 23:23:58 -07009257 if (mInnerFields.mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
Craig Mautner164d4bb2012-11-26 13:51:23 -08009258 && !mAppTransition.isReady()) {
Craig Mautner764983d2012-03-22 11:37:36 -07009259 // At this point, there was a window with a wallpaper that
9260 // was force hiding other windows behind it, but now it
9261 // is going away. This may be simple -- just animate
9262 // away the wallpaper and its window -- or it may be
9263 // hard -- the wallpaper now needs to be shown behind
9264 // something that was hidden.
Craig Mautnerae446592012-12-06 19:05:05 -08009265 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009266 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animateAwayWallpaperLocked",
Craig Mautner76a71652012-09-03 23:23:58 -07009267 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009268 }
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009269 mInnerFields.mWallpaperForceHidingChanged = false;
Craig Mautner764983d2012-03-22 11:37:36 -07009270
Craig Mautnere7ae2502012-03-26 17:11:19 -07009271 if (mInnerFields.mWallpaperMayChange) {
Craig Mautner11462cc2013-05-13 15:56:18 -07009272 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Wallpaper may change! Adjusting");
Craig Mautnerae446592012-12-06 19:05:05 -08009273 defaultDisplay.pendingLayoutChanges |=
9274 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
9275 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
9276 defaultDisplay.pendingLayoutChanges);
Craig Mautnere7ae2502012-03-26 17:11:19 -07009277 }
9278
9279 if (mFocusMayChange) {
9280 mFocusMayChange = false;
9281 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
9282 false /*updateInputWindows*/)) {
Craig Mautner76a71652012-09-03 23:23:58 -07009283 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
Craig Mautnere7ae2502012-03-26 17:11:19 -07009284 }
9285 }
Craig Mautner764983d2012-03-22 11:37:36 -07009286
Craig Mautner19d59bc2012-09-04 11:15:56 -07009287 if (needsLayout()) {
Craig Mautner76a71652012-09-03 23:23:58 -07009288 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
9289 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
9290 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009291 }
9292
Craig Mautnerade0a9a2012-10-06 13:55:07 -07009293 for (i = mResizingWindows.size() - 1; i >= 0; i--) {
9294 WindowState win = mResizingWindows.get(i);
9295 if (win.mAppFreezing) {
9296 // Don't remove this window until rotation has completed.
9297 continue;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009298 }
Craig Mautnerdf88d732014-01-27 09:21:32 -08009299 win.reportResized();
Craig Mautnerade0a9a2012-10-06 13:55:07 -07009300 mResizingWindows.remove(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009301 }
Romain Guy06882f82009-06-10 13:36:04 -07009302
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009303 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
9304 "With display frozen, orientationChangeComplete="
9305 + mInnerFields.mOrientationChangeComplete);
9306 if (mInnerFields.mOrientationChangeComplete) {
9307 if (mWindowsFreezingScreen) {
9308 mWindowsFreezingScreen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009309 mLastFinishedFreezeSource = mInnerFields.mLastWindowFreezeSource;
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009310 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
9311 }
9312 stopFreezingDisplayLocked();
9313 }
9314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009315 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009316 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009317 i = mDestroySurface.size();
9318 if (i > 0) {
9319 do {
9320 i--;
9321 WindowState win = mDestroySurface.get(i);
9322 win.mDestroying = false;
9323 if (mInputMethodWindow == win) {
9324 mInputMethodWindow = null;
9325 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009326 if (win == mWallpaperTarget) {
9327 wallpaperDestroyed = true;
9328 }
Craig Mautner96868332012-12-04 14:29:11 -08009329 win.mWinAnimator.destroySurfaceLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009330 } while (i > 0);
9331 mDestroySurface.clear();
9332 }
9333
9334 // Time to remove any exiting tokens?
Craig Mautnerf8924152013-07-16 09:10:55 -07009335 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9336 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautnerb1fd65c2013-02-05 13:34:57 -08009337 ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
9338 for (i = exitingTokens.size() - 1; i >= 0; i--) {
9339 WindowToken token = exitingTokens.get(i);
9340 if (!token.hasVisible) {
9341 exitingTokens.remove(i);
9342 if (token.windowType == TYPE_WALLPAPER) {
9343 mWallpaperTokens.remove(token);
9344 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07009345 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009346 }
Craig Mautnerdc548482014-02-05 13:35:24 -08009347 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009348
Craig Mautnerdc548482014-02-05 13:35:24 -08009349 // Time to remove any exiting applications?
9350 for (int stackNdx = mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
9351 // Initialize state of exiting applications.
9352 final AppTokenList exitingAppTokens =
9353 mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
Craig Mautnerb1fd65c2013-02-05 13:34:57 -08009354 for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
9355 AppWindowToken token = exitingAppTokens.get(i);
Craig Mautner81481fc2014-03-18 14:26:36 -07009356 if (!token.hasVisible && !mClosingApps.contains(token) && !token.mDeferRemoval) {
Craig Mautnerb1fd65c2013-02-05 13:34:57 -08009357 // Make sure there is no animation running on this token,
9358 // so any windows associated with it will be removed as
9359 // soon as their animations are complete
9360 token.mAppAnimator.clearAnimation();
9361 token.mAppAnimator.animating = false;
9362 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
9363 "performLayout: App token exiting now removed" + token);
Craig Mautner9ef471f2014-02-07 13:11:47 -08009364 removeAppFromTaskLocked(token);
Craig Mautnerb1fd65c2013-02-05 13:34:57 -08009365 exitingAppTokens.remove(i);
9366 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009367 }
9368 }
9369
Dianne Hackborn12d3a942012-04-27 14:16:30 -07009370 if (!mAnimator.mAnimating && mRelayoutWhileAnimating.size() > 0) {
9371 for (int j=mRelayoutWhileAnimating.size()-1; j>=0; j--) {
9372 try {
9373 mRelayoutWhileAnimating.get(j).mClient.doneAnimating();
9374 } catch (RemoteException e) {
9375 }
9376 }
9377 mRelayoutWhileAnimating.clear();
9378 }
9379
Craig Mautnerae446592012-12-06 19:05:05 -08009380 if (wallpaperDestroyed) {
9381 defaultDisplay.pendingLayoutChanges |=
9382 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
9383 defaultDisplay.layoutNeeded = true;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009384 }
Craig Mautner76a71652012-09-03 23:23:58 -07009385
Craig Mautnerf8924152013-07-16 09:10:55 -07009386 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9387 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautner76a71652012-09-03 23:23:58 -07009388 if (displayContent.pendingLayoutChanges != 0) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009389 displayContent.layoutNeeded = true;
Craig Mautner76a71652012-09-03 23:23:58 -07009390 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009391 }
Jeff Browneb857f12010-07-16 10:06:33 -07009392
Jeff Brown3a22cd92011-01-21 13:59:04 -08009393 // Finally update all input windows now that the window changes have stabilized.
Jeff Brown2e44b072011-01-24 15:21:56 -08009394 mInputMonitor.updateInputWindowsLw(true /*force*/);
Jeff Browneb857f12010-07-16 10:06:33 -07009395
Craig Mautner259328c2012-08-21 19:30:58 -07009396 setHoldScreenLocked(mInnerFields.mHoldScreen);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009397 if (!mDisplayFrozen) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009398 if (mInnerFields.mScreenBrightness < 0 || mInnerFields.mScreenBrightness > 1.0f) {
Jeff Brown6f357d32014-01-15 20:40:55 -08009399 mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009400 } else {
Jeff Brown6f357d32014-01-15 20:40:55 -08009401 mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
Jeff Brown96307042012-07-27 15:51:34 -07009402 toBrightnessOverride(mInnerFields.mScreenBrightness));
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009403 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009404 if (mInnerFields.mButtonBrightness < 0 || mInnerFields.mButtonBrightness > 1.0f) {
Jeff Brown6f357d32014-01-15 20:40:55 -08009405 mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009406 } else {
Jeff Brown6f357d32014-01-15 20:40:55 -08009407 mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
Jeff Brown96307042012-07-27 15:51:34 -07009408 toBrightnessOverride(mInnerFields.mButtonBrightness));
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009409 }
Jeff Brown6f357d32014-01-15 20:40:55 -08009410 mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
Jeff Brown1e3b98d2012-09-30 18:58:59 -07009411 mInnerFields.mUserActivityTimeout);
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009412 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009413
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009414 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009415 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Jeff Brown96307042012-07-27 15:51:34 -07009416 mPowerManager.wakeUp(SystemClock.uptimeMillis());
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009417 mTurnOnScreen = false;
9418 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009419
Craig Mautnera608b882012-03-30 13:03:49 -07009420 if (mInnerFields.mUpdateRotation) {
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009421 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009422 if (updateRotationUncheckedLocked(false)) {
Dianne Hackborn3e4f9d02011-02-04 14:05:55 -08009423 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07009424 } else {
Craig Mautnera608b882012-03-30 13:03:49 -07009425 mInnerFields.mUpdateRotation = false;
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009426 }
9427 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009428
Craig Mautner19d59bc2012-09-04 11:15:56 -07009429 if (mInnerFields.mOrientationChangeComplete && !defaultDisplay.layoutNeeded
9430 && !mInnerFields.mUpdateRotation) {
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07009431 checkDrawnWindowsLocked();
9432 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009433
Craig Mautner76a71652012-09-03 23:23:58 -07009434 final int N = mPendingRemove.size();
9435 if (N > 0) {
9436 if (mPendingRemoveTmp.length < N) {
9437 mPendingRemoveTmp = new WindowState[N+10];
9438 }
9439 mPendingRemove.toArray(mPendingRemoveTmp);
9440 mPendingRemove.clear();
9441 DisplayContentList displayList = new DisplayContentList();
9442 for (i = 0; i < N; i++) {
9443 WindowState w = mPendingRemoveTmp[i];
9444 removeWindowInnerLocked(w.mSession, w);
Craig Mautnerdf88d732014-01-27 09:21:32 -08009445 final DisplayContent displayContent = w.getDisplayContent();
9446 if (displayContent != null && !displayList.contains(displayContent)) {
9447 displayList.add(displayContent);
Craig Mautner76a71652012-09-03 23:23:58 -07009448 }
9449 }
9450
9451 for (DisplayContent displayContent : displayList) {
9452 assignLayersLocked(displayContent.getWindowList());
Craig Mautner19d59bc2012-09-04 11:15:56 -07009453 displayContent.layoutNeeded = true;
Craig Mautner76a71652012-09-03 23:23:58 -07009454 }
Craig Mautner76a71652012-09-03 23:23:58 -07009455 }
9456
Craig Mautner95da1082014-02-24 17:54:35 -08009457 // Remove all deferred displays stacks, tasks, and activities.
9458 for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
9459 mDisplayContents.valueAt(displayNdx).checkForDeferredActions();
Craig Mautner9ef471f2014-02-07 13:11:47 -08009460 }
9461
Craig Mautnerf7666462013-04-28 08:58:21 -07009462 setFocusedStackFrame();
Craig Mautnerc5a6e442013-06-05 17:22:35 -07009463
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08009464 // Check to see if we are now in a state where the screen should
9465 // be enabled, because the window obscured flags have changed.
9466 enableScreenIfNeededLocked();
Craig Mautner7d8df392012-04-06 15:26:23 -07009467
Craig Mautner96868332012-12-04 14:29:11 -08009468 scheduleAnimationLocked();
Craig Mautner7d8df392012-04-06 15:26:23 -07009469
9470 if (DEBUG_WINDOW_TRACE) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009471 Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: animating="
9472 + mAnimator.mAnimating);
Craig Mautner7d8df392012-04-06 15:26:23 -07009473 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009474 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009475
Jeff Brown96307042012-07-27 15:51:34 -07009476 private int toBrightnessOverride(float value) {
9477 return (int)(value * PowerManager.BRIGHTNESS_ON);
9478 }
9479
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009480 void checkDrawnWindowsLocked() {
9481 if (mWaitingForDrawn.size() > 0) {
9482 for (int j=mWaitingForDrawn.size()-1; j>=0; j--) {
9483 Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(j);
9484 WindowState win = pair.first;
9485 //Slog.i(TAG, "Waiting for drawn " + win + ": removed="
9486 // + win.mRemoved + " visible=" + win.isVisibleLw()
9487 // + " shown=" + win.mSurfaceShown);
Craig Mautner4e8a19c2013-10-08 17:26:08 -07009488 if (win.mRemoved) {
9489 // Window has been removed; no draw will now happen, so stop waiting.
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009490 Slog.w(TAG, "Aborted waiting for drawn: " + pair.first);
9491 try {
9492 pair.second.sendResult(null);
9493 } catch (RemoteException e) {
9494 }
9495 mWaitingForDrawn.remove(pair);
9496 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009497 } else if (win.mWinAnimator.mSurfaceShown) {
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009498 // Window is now drawn (and shown).
9499 try {
9500 pair.second.sendResult(null);
9501 } catch (RemoteException e) {
9502 }
9503 mWaitingForDrawn.remove(pair);
9504 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9505 }
9506 }
9507 }
9508 }
9509
Craig Mautner2268e7e2012-12-13 15:40:00 -08009510 @Override
Jeff Brownc38c9be2012-10-04 13:16:19 -07009511 public boolean waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
9512 if (token != null && callback != null) {
9513 synchronized (mWindowMap) {
9514 WindowState win = windowForClientLocked(null, token, true);
9515 if (win != null) {
9516 Pair<WindowState, IRemoteCallback> pair =
9517 new Pair<WindowState, IRemoteCallback>(win, callback);
9518 Message m = mH.obtainMessage(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9519 mH.sendMessageDelayed(m, 2000);
9520 mWaitingForDrawn.add(pair);
9521 checkDrawnWindowsLocked();
9522 return true;
9523 }
Craig Mautner4e8a19c2013-10-08 17:26:08 -07009524 Slog.i(TAG, "waitForWindowDrawn: win null");
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009525 }
9526 }
Jeff Brownc38c9be2012-10-04 13:16:19 -07009527 return false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009528 }
9529
Craig Mautner259328c2012-08-21 19:30:58 -07009530 void setHoldScreenLocked(final Session newHoldScreen) {
9531 final boolean hold = newHoldScreen != null;
9532
9533 if (hold && mHoldingScreenOn != newHoldScreen) {
9534 mHoldingScreenWakeLock.setWorkSource(new WorkSource(newHoldScreen.mUid));
9535 }
9536 mHoldingScreenOn = newHoldScreen;
9537
9538 final boolean state = mHoldingScreenWakeLock.isHeld();
9539 if (hold != state) {
9540 if (hold) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07009541 mHoldingScreenWakeLock.acquire();
Jeff Brownc38c9be2012-10-04 13:16:19 -07009542 mPolicy.keepScreenOnStartedLw();
Jeff Brown46b9ac02010-04-22 18:58:52 -07009543 } else {
Jeff Brownc38c9be2012-10-04 13:16:19 -07009544 mPolicy.keepScreenOnStoppedLw();
Jeff Brown46b9ac02010-04-22 18:58:52 -07009545 mHoldingScreenWakeLock.release();
9546 }
9547 }
9548 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009549
Jeff Brown4ccb8232014-01-16 22:16:42 -08009550 void requestTraversal() {
Jeff Brown4ed8fe72012-08-30 18:18:29 -07009551 synchronized (mWindowMap) {
9552 requestTraversalLocked();
9553 }
9554 }
9555
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08009556 void requestTraversalLocked() {
9557 if (!mTraversalScheduled) {
9558 mTraversalScheduled = true;
9559 mH.sendEmptyMessage(H.DO_TRAVERSAL);
9560 }
9561 }
9562
Craig Mautner711f90a2012-07-03 18:43:52 -07009563 /** Note that Locked in this case is on mLayoutToAnim */
Jeff Brown4a06c802012-02-15 15:06:01 -08009564 void scheduleAnimationLocked() {
Craig Mautner96868332012-12-04 14:29:11 -08009565 if (!mAnimationScheduled) {
9566 mAnimationScheduled = true;
Craig Mautner711f90a2012-07-03 18:43:52 -07009567 mChoreographer.postCallback(
9568 Choreographer.CALLBACK_ANIMATION, mAnimator.mAnimationRunnable, null);
9569 }
9570 }
9571
Craig Mautner19d59bc2012-09-04 11:15:56 -07009572 private boolean needsLayout() {
Craig Mautnerf8924152013-07-16 09:10:55 -07009573 final int numDisplays = mDisplayContents.size();
9574 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9575 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
9576 if (displayContent.layoutNeeded) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009577 return true;
9578 }
9579 }
9580 return false;
9581 }
9582
Craig Mautner96868332012-12-04 14:29:11 -08009583 boolean copyAnimToLayoutParamsLocked() {
Craig Mautner322e4032012-07-13 13:35:20 -07009584 boolean doRequest = false;
Craig Mautner322e4032012-07-13 13:35:20 -07009585
Craig Mautner96868332012-12-04 14:29:11 -08009586 final int bulkUpdateParams = mAnimator.mBulkUpdateParams;
Craig Mautner96868332012-12-04 14:29:11 -08009587 if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) {
9588 mInnerFields.mUpdateRotation = true;
9589 doRequest = true;
Craig Mautner322e4032012-07-13 13:35:20 -07009590 }
Craig Mautner96868332012-12-04 14:29:11 -08009591 if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
9592 mInnerFields.mWallpaperMayChange = true;
9593 doRequest = true;
9594 }
9595 if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
9596 mInnerFields.mWallpaperForceHidingChanged = true;
9597 doRequest = true;
9598 }
9599 if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
9600 mInnerFields.mOrientationChangeComplete = false;
9601 } else {
9602 mInnerFields.mOrientationChangeComplete = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009603 mInnerFields.mLastWindowFreezeSource = mAnimator.mLastWindowFreezeSource;
Craig Mautner96868332012-12-04 14:29:11 -08009604 if (mWindowsFreezingScreen) {
9605 doRequest = true;
9606 }
9607 }
9608 if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
9609 mTurnOnScreen = true;
9610 }
9611 if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_ACTION_PENDING) != 0) {
9612 mInnerFields.mWallpaperActionPending = true;
9613 }
9614
Craig Mautner322e4032012-07-13 13:35:20 -07009615 return doRequest;
9616 }
9617
Craig Mautner6201c2a2013-08-09 18:48:48 -07009618 /** If a window that has an animation specifying a colored background and the current wallpaper
9619 * is visible, then the color goes *below* the wallpaper so we don't cause the wallpaper to
Craig Mautner05d29032013-05-03 13:40:13 -07009620 * suddenly disappear. */
9621 int adjustAnimationBackground(WindowStateAnimator winAnimator) {
Craig Mautner6201c2a2013-08-09 18:48:48 -07009622 WindowList windows = winAnimator.mWin.getWindowList();
9623 for (int i = windows.size() - 1; i >= 0; --i) {
9624 WindowState testWin = windows.get(i);
9625 if (testWin.mIsWallpaper && testWin.isVisibleNow()) {
9626 return testWin.mWinAnimator.mAnimLayer;
Craig Mautner05d29032013-05-03 13:40:13 -07009627 }
9628 }
9629 return winAnimator.mAnimLayer;
9630 }
9631
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009632 boolean reclaimSomeSurfaceMemoryLocked(WindowStateAnimator winAnimator, String operation,
9633 boolean secure) {
Mathias Agopian29479eb2013-02-14 14:36:04 -08009634 final SurfaceControl surface = winAnimator.mSurfaceControl;
Dianne Hackborn64825172011-03-02 21:32:58 -08009635 boolean leakedSurface = false;
9636 boolean killedApps = false;
Romain Guy06882f82009-06-10 13:36:04 -07009637
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009638 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
9639 winAnimator.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -07009640
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009641 if (mForceRemoves == null) {
9642 mForceRemoves = new ArrayList<WindowState>();
9643 }
Romain Guy06882f82009-06-10 13:36:04 -07009644
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009645 long callingIdentity = Binder.clearCallingIdentity();
9646 try {
9647 // There was some problem... first, do a sanity check of the
9648 // window list to make sure we haven't left any dangling surfaces
9649 // around.
Craig Mautner59c00972012-07-30 12:10:24 -07009650
Joe Onorato8a9b2202010-02-26 18:56:32 -08009651 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
Craig Mautnerf8924152013-07-16 09:10:55 -07009652 final int numDisplays = mDisplayContents.size();
9653 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9654 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
9655 final int numWindows = windows.size();
9656 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
9657 final WindowState ws = windows.get(winNdx);
9658 WindowStateAnimator wsa = ws.mWinAnimator;
9659 if (wsa.mSurfaceControl != null) {
9660 if (!mSessions.contains(wsa.mSession)) {
9661 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
9662 + ws + " surface=" + wsa.mSurfaceControl
9663 + " token=" + ws.mToken
9664 + " pid=" + ws.mSession.mPid
9665 + " uid=" + ws.mSession.mUid);
9666 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
9667 wsa.mSurfaceControl.destroy();
9668 wsa.mSurfaceShown = false;
9669 wsa.mSurfaceControl = null;
9670 ws.mHasSurface = false;
9671 mForceRemoves.add(ws);
9672 leakedSurface = true;
9673 } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
9674 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
9675 + ws + " surface=" + wsa.mSurfaceControl
9676 + " token=" + ws.mAppToken);
9677 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
9678 wsa.mSurfaceControl.destroy();
9679 wsa.mSurfaceShown = false;
9680 wsa.mSurfaceControl = null;
9681 ws.mHasSurface = false;
9682 leakedSurface = true;
9683 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009684 }
9685 }
9686 }
Romain Guy06882f82009-06-10 13:36:04 -07009687
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009688 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009689 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009690 SparseIntArray pidCandidates = new SparseIntArray();
Craig Mautnerf8924152013-07-16 09:10:55 -07009691 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9692 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
9693 final int numWindows = windows.size();
9694 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
9695 final WindowState ws = windows.get(winNdx);
9696 if (mForceRemoves.contains(ws)) {
9697 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009698 }
Craig Mautnerf8924152013-07-16 09:10:55 -07009699 WindowStateAnimator wsa = ws.mWinAnimator;
9700 if (wsa.mSurfaceControl != null) {
9701 pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
9702 }
9703 }
9704 if (pidCandidates.size() > 0) {
9705 int[] pids = new int[pidCandidates.size()];
9706 for (int i=0; i<pids.length; i++) {
9707 pids[i] = pidCandidates.keyAt(i);
9708 }
9709 try {
9710 if (mActivityManager.killPids(pids, "Free memory", secure)) {
9711 killedApps = true;
9712 }
9713 } catch (RemoteException e) {
9714 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009715 }
9716 }
9717 }
Romain Guy06882f82009-06-10 13:36:04 -07009718
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009719 if (leakedSurface || killedApps) {
9720 // We managed to reclaim some memory, so get rid of the trouble
9721 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -08009722 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009723 if (surface != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009724 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
Dianne Hackborn5fd21692011-06-07 14:09:47 -07009725 "RECOVER DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009726 surface.destroy();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009727 winAnimator.mSurfaceShown = false;
Mathias Agopian29479eb2013-02-14 14:36:04 -08009728 winAnimator.mSurfaceControl = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009729 winAnimator.mWin.mHasSurface = false;
Craig Mautner68cc2412013-10-01 10:39:43 -07009730 scheduleRemoveStartingWindow(winAnimator.mWin.mAppToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009731 }
Romain Guy06882f82009-06-10 13:36:04 -07009732
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009733 try {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009734 winAnimator.mWin.mClient.dispatchGetNewSurface();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009735 } catch (RemoteException e) {
9736 }
9737 }
9738 } finally {
9739 Binder.restoreCallingIdentity(callingIdentity);
9740 }
Dianne Hackborn64825172011-03-02 21:32:58 -08009741
9742 return leakedSurface || killedApps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009743 }
Romain Guy06882f82009-06-10 13:36:04 -07009744
Jeff Brown3a22cd92011-01-21 13:59:04 -08009745 private boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009746 WindowState newFocus = computeFocusedWindowLocked();
9747 if (mCurrentFocus != newFocus) {
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07009748 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009749 // This check makes sure that we don't already have the focus
9750 // change message pending.
9751 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
9752 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Satoshi Kataoka02679f62013-05-20 16:13:44 +09009753 // TODO(multidisplay): Focused windows on default display only.
9754 final DisplayContent displayContent = getDefaultDisplayContentLocked();
9755 final boolean imWindowChanged = moveInputMethodWindowsIfNeededLocked(
9756 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS
9757 && mode != UPDATE_FOCUS_WILL_PLACE_SURFACES);
9758 if (imWindowChanged) {
9759 displayContent.layoutNeeded = true;
9760 newFocus = computeFocusedWindowLocked();
9761 }
9762
Craig Mautnera7f2bd42013-10-15 16:13:50 -07009763 if (DEBUG_FOCUS_LIGHT || localLOGV) Slog.v(TAG, "Changing focus from " +
Craig Mautnerb3370ce2013-09-19 12:02:09 -07009764 mCurrentFocus + " to " + newFocus + " Callers=" + Debug.getCallers(4));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009765 final WindowState oldFocus = mCurrentFocus;
9766 mCurrentFocus = newFocus;
9767 mLosingFocus.remove(newFocus);
Svetoslav8e3feb12014-02-24 13:46:47 -08009768
9769 if (mAccessibilityController != null) {
9770 mAccessibilityController.onWindowFocusChangedLocked();
9771 }
9772
Dianne Hackborndf89e652011-10-06 22:35:11 -07009773 int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus);
Romain Guy06882f82009-06-10 13:36:04 -07009774
Satoshi Kataoka12afe142013-05-21 06:19:27 +09009775 if (imWindowChanged && oldFocus != mInputMethodWindow) {
Satoshi Kataoka02679f62013-05-20 16:13:44 +09009776 // Focus of the input method window changed. Perform layout if needed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009777 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Craig Mautner59c00972012-07-30 12:10:24 -07009778 performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009779 focusChanged &= ~WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009780 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
9781 // Client will do the layout, but we need to assign layers
9782 // for handleNewWindowLocked() below.
Craig Mautner59c00972012-07-30 12:10:24 -07009783 assignLayersLocked(displayContent.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009784 }
9785 }
Dianne Hackborndf89e652011-10-06 22:35:11 -07009786
Craig Mautner39834192012-09-02 07:47:24 -07009787 if ((focusChanged & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07009788 // The change in focus caused us to need to do a layout. Okay.
Jeff Brown20337632012-09-24 14:25:54 -07009789 displayContent.layoutNeeded = true;
Dianne Hackborndf89e652011-10-06 22:35:11 -07009790 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Craig Mautner59c00972012-07-30 12:10:24 -07009791 performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009792 }
9793 }
9794
Jeff Brown349703e2010-06-22 01:27:15 -07009795 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
9796 // If we defer assigning layers, then the caller is responsible for
9797 // doing this part.
Jeff Brown3a22cd92011-01-21 13:59:04 -08009798 finishUpdateFocusedWindowAfterAssignLayersLocked(updateInputWindows);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009799 }
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07009800
9801 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009802 return true;
9803 }
9804 return false;
9805 }
Craig Mautner66f78d72012-12-04 16:46:50 -08009806
Jeff Brown3a22cd92011-01-21 13:59:04 -08009807 private void finishUpdateFocusedWindowAfterAssignLayersLocked(boolean updateInputWindows) {
9808 mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows);
Jeff Brown349703e2010-06-22 01:27:15 -07009809 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009810
9811 private WindowState computeFocusedWindowLocked() {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07009812 if (mAnimator.mUniverseBackground != null
9813 && mAnimator.mUniverseBackground.mWin.canReceiveKeys()) {
9814 return mAnimator.mUniverseBackground.mWin;
9815 }
9816
Jeff Brown20337632012-09-24 14:25:54 -07009817 final int displayCount = mDisplayContents.size();
9818 for (int i = 0; i < displayCount; i++) {
9819 final DisplayContent displayContent = mDisplayContents.valueAt(i);
9820 WindowState win = findFocusedWindowLocked(displayContent);
9821 if (win != null) {
9822 return win;
9823 }
9824 }
9825 return null;
9826 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009827
Jeff Brown20337632012-09-24 14:25:54 -07009828 private WindowState findFocusedWindowLocked(DisplayContent displayContent) {
Jeff Brown20337632012-09-24 14:25:54 -07009829 final WindowList windows = displayContent.getWindowList();
Craig Mautner59c00972012-07-30 12:10:24 -07009830 for (int i = windows.size() - 1; i >= 0; i--) {
Jeff Brown20337632012-09-24 14:25:54 -07009831 final WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009832
Joe Onorato8a9b2202010-02-26 18:56:32 -08009833 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009834 TAG, "Looking for focus: " + i
9835 + " = " + win
9836 + ", flags=" + win.mAttrs.flags
9837 + ", canReceive=" + win.canReceiveKeys());
9838
Craig Mautnerac565142013-09-23 17:37:09 -07009839 AppWindowToken wtoken = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -07009840
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009841 // If this window's application has been removed, just skip it.
Craig Mautnerac565142013-09-23 17:37:09 -07009842 if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) {
9843 if (DEBUG_FOCUS) Slog.v(TAG, "Skipping " + wtoken + " because "
9844 + (wtoken.removed ? "removed" : "sendingToBottom"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009845 continue;
9846 }
Romain Guy06882f82009-06-10 13:36:04 -07009847
Craig Mautnerac565142013-09-23 17:37:09 -07009848 if (!win.canReceiveKeys()) {
9849 continue;
9850 }
9851
9852 // Descend through all of the app tokens and find the first that either matches
9853 // win.mAppToken (return win) or mFocusedApp (return null).
9854 if (wtoken != null && win.mAttrs.type != TYPE_APPLICATION_STARTING &&
9855 mFocusedApp != null) {
9856 ArrayList<Task> tasks = displayContent.getTasks();
9857 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
9858 AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
9859 int tokenNdx = tokens.size() - 1;
Craig Mautnerf81b90872013-02-26 13:02:43 -08009860 for ( ; tokenNdx >= 0; --tokenNdx) {
Craig Mautnerac565142013-09-23 17:37:09 -07009861 final AppWindowToken token = tokens.get(tokenNdx);
9862 if (wtoken == token) {
Craig Mautnerf81b90872013-02-26 13:02:43 -08009863 break;
9864 }
Craig Mautnerac565142013-09-23 17:37:09 -07009865 if (mFocusedApp == token) {
9866 // Whoops, we are below the focused app... no focus for you!
9867 if (localLOGV || DEBUG_FOCUS_LIGHT) Slog.v(TAG,
9868 "findFocusedWindow: Reached focused app=" + mFocusedApp);
9869 return null;
9870 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009871 }
Craig Mautnerac565142013-09-23 17:37:09 -07009872 if (tokenNdx >= 0) {
9873 // Early exit from loop, must have found the matching token.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009874 break;
9875 }
9876 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009877 }
9878
Craig Mautnerac565142013-09-23 17:37:09 -07009879 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "findFocusedWindow: Found new focus @ " + i +
9880 " = " + win);
9881 return win;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009882 }
Craig Mautnerac565142013-09-23 17:37:09 -07009883
Craig Mautner58458122013-09-14 14:59:50 -07009884 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "findFocusedWindow: No focusable windows.");
Jeff Brown20337632012-09-24 14:25:54 -07009885 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009886 }
9887
Craig Mautner3c174372013-02-21 17:54:37 -08009888 private void startFreezingDisplayLocked(boolean inTransaction, int exitAnim, int enterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009889 if (mDisplayFrozen) {
9890 return;
9891 }
Romain Guy06882f82009-06-10 13:36:04 -07009892
Jeff Browne215f262012-09-10 16:01:14 -07009893 if (!mDisplayReady || !mPolicy.isScreenOnFully()) {
Dianne Hackborn8e8d65f2011-08-11 19:36:18 -07009894 // No need to freeze the screen before the system is ready or if
9895 // the screen is off.
9896 return;
9897 }
9898
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009899 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -07009900
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009901 mDisplayFrozen = true;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009902 mDisplayFreezeTime = SystemClock.elapsedRealtime();
9903 mLastFinishedFreezeSource = null;
Craig Mautner7d8df392012-04-06 15:26:23 -07009904
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009905 mInputMonitor.freezeInputDispatchingLw();
Craig Mautner7d8df392012-04-06 15:26:23 -07009906
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07009907 // Clear the last input window -- that is just used for
9908 // clean transitions between IMEs, and if we are freezing
9909 // the screen then the whole world is changing behind the scenes.
9910 mPolicy.setLastInputMethodWindowLw(null, null);
9911
Craig Mautner164d4bb2012-11-26 13:51:23 -08009912 if (mAppTransition.isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08009913 mAppTransition.freeze();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009914 }
Romain Guy06882f82009-06-10 13:36:04 -07009915
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009916 if (PROFILE_ORIENTATION) {
9917 File file = new File("/data/system/frozen");
9918 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
9919 }
Dianne Hackborna1111872010-11-23 20:55:11 -08009920
9921 if (CUSTOM_SCREEN_ROTATION) {
Craig Mautner3c174372013-02-21 17:54:37 -08009922 mExitAnimId = exitAnim;
9923 mEnterAnimId = enterAnim;
Craig Mautnera91f9e22012-09-14 16:22:08 -07009924 final DisplayContent displayContent = getDefaultDisplayContentLocked();
9925 final int displayId = displayContent.getDisplayId();
9926 ScreenRotationAnimation screenRotationAnimation =
9927 mAnimator.getScreenRotationAnimationLocked(displayId);
9928 if (screenRotationAnimation != null) {
9929 screenRotationAnimation.kill();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08009930 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07009931
Craig Mautnerb98ee1e2014-03-24 14:38:33 +00009932 // Check whether the current screen contains any secure content.
9933 boolean isSecure = false;
9934 final WindowList windows = getDefaultWindowListLocked();
9935 final int N = windows.size();
9936 for (int i = 0; i < N; i++) {
9937 WindowState ws = windows.get(i);
9938 if (ws.isOnScreen() && (ws.mAttrs.flags & FLAG_SECURE) != 0) {
9939 isSecure = true;
9940 break;
9941 }
9942 }
9943
Craig Mautner59c00972012-07-30 12:10:24 -07009944 // TODO(multidisplay): rotation on main screen only.
Craig Mautnerb660b9d2014-02-13 10:59:16 -08009945 displayContent.updateDisplayInfo();
Craig Mautner46ac6fa2013-08-01 10:06:34 -07009946 screenRotationAnimation = new ScreenRotationAnimation(mContext, displayContent,
Craig Mautnerb98ee1e2014-03-24 14:38:33 +00009947 mFxSession, inTransaction, mPolicy.isDefaultOrientationForced(), isSecure);
Craig Mautnera91f9e22012-09-14 16:22:08 -07009948 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackborna1111872010-11-23 20:55:11 -08009949 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009950 }
Romain Guy06882f82009-06-10 13:36:04 -07009951
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009952 private void stopFreezingDisplayLocked() {
9953 if (!mDisplayFrozen) {
9954 return;
9955 }
Romain Guy06882f82009-06-10 13:36:04 -07009956
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009957 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen
9958 || mClientFreezingScreen) {
Craig Mautnerd87946b2012-03-29 18:00:19 -07009959 if (DEBUG_ORIENTATION) Slog.d(TAG,
9960 "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + mWaitingForConfig
9961 + ", mAppsFreezingScreen=" + mAppsFreezingScreen
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009962 + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen
9963 + ", mClientFreezingScreen=" + mClientFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009964 return;
9965 }
Craig Mautner66f78d72012-12-04 16:46:50 -08009966
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009967 mDisplayFrozen = false;
Dianne Hackborna57c6952013-03-29 14:46:40 -07009968 mLastDisplayFreezeDuration = (int)(SystemClock.elapsedRealtime() - mDisplayFreezeTime);
9969 StringBuilder sb = new StringBuilder(128);
9970 sb.append("Screen frozen for ");
9971 TimeUtils.formatDuration(mLastDisplayFreezeDuration, sb);
9972 if (mLastFinishedFreezeSource != null) {
9973 sb.append(" due to ");
9974 sb.append(mLastFinishedFreezeSource);
9975 }
9976 Slog.i(TAG, sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009977 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07009978 mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009979 if (PROFILE_ORIENTATION) {
9980 Debug.stopMethodTracing();
9981 }
Dianne Hackborna1111872010-11-23 20:55:11 -08009982
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009983 boolean updateRotation = false;
Craig Mautner59c00972012-07-30 12:10:24 -07009984
Craig Mautnera91f9e22012-09-14 16:22:08 -07009985 final DisplayContent displayContent = getDefaultDisplayContentLocked();
9986 final int displayId = displayContent.getDisplayId();
9987 ScreenRotationAnimation screenRotationAnimation =
9988 mAnimator.getScreenRotationAnimationLocked(displayId);
9989 if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
9990 && screenRotationAnimation.hasScreenshot()) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07009991 if (DEBUG_ORIENTATION) Slog.i(TAG, "**** Dismissing screen rotation animation");
Craig Mautner59c00972012-07-30 12:10:24 -07009992 // TODO(multidisplay): rotation on main screen only.
Craig Mautnera91f9e22012-09-14 16:22:08 -07009993 DisplayInfo displayInfo = displayContent.getDisplayInfo();
Craig Mautner3c174372013-02-21 17:54:37 -08009994 // Get rotation animation again, with new top window
Craig Mautner05d29032013-05-03 13:40:13 -07009995 boolean isDimming = displayContent.isDimming();
Craig Mautner3c174372013-02-21 17:54:37 -08009996 if (!mPolicy.validateRotationAnimationLw(mExitAnimId, mEnterAnimId, isDimming)) {
9997 mExitAnimId = mEnterAnimId = 0;
9998 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07009999 if (screenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
Craig Mautner59c00972012-07-30 12:10:24 -070010000 mTransitionAnimationScale, displayInfo.logicalWidth,
Craig Mautner3c174372013-02-21 17:54:37 -080010001 displayInfo.logicalHeight, mExitAnimId, mEnterAnimId)) {
Craig Mautner96868332012-12-04 14:29:11 -080010002 scheduleAnimationLocked();
Dianne Hackbornde75cb42011-03-02 17:11:21 -080010003 } else {
Craig Mautnera91f9e22012-09-14 16:22:08 -070010004 screenRotationAnimation.kill();
10005 screenRotationAnimation = null;
10006 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -080010007 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -080010008 }
10009 } else {
Craig Mautnera91f9e22012-09-14 16:22:08 -070010010 if (screenRotationAnimation != null) {
10011 screenRotationAnimation.kill();
10012 screenRotationAnimation = null;
10013 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -080010014 }
10015 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -080010016 }
Romain Guy06882f82009-06-10 13:36:04 -070010017
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010018 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010019
Dianne Hackborn420829e2011-01-28 11:30:35 -080010020 boolean configChanged;
Craig Mautner0bf6ec92012-12-18 08:33:27 -080010021
Christopher Tateb696aee2010-04-02 19:08:30 -070010022 // While the display is frozen we don't re-compute the orientation
10023 // to avoid inconsistent states. However, something interesting
10024 // could have actually changed during that time so re-evaluate it
10025 // now to catch that.
Dianne Hackborn420829e2011-01-28 11:30:35 -080010026 configChanged = updateOrientationFromAppTokensLocked(false);
Christopher Tateb696aee2010-04-02 19:08:30 -070010027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010028 // A little kludge: a lot could have happened while the
10029 // display was frozen, so now that we are coming back we
10030 // do a gc so that any remote references the system
10031 // processes holds on others can be released if they are
10032 // no longer needed.
10033 mH.removeMessages(H.FORCE_GC);
You Kimcb6291c2012-12-04 23:22:28 +090010034 mH.sendEmptyMessageDelayed(H.FORCE_GC, 2000);
Romain Guy06882f82009-06-10 13:36:04 -070010035
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010036 mScreenFrozenLock.release();
Craig Mautner6cfa7292013-01-15 09:05:42 -080010037
Dianne Hackborn89ba6752011-01-23 16:51:16 -080010038 if (updateRotation) {
10039 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Jeff Brown01a98dd2011-09-20 15:08:29 -070010040 configChanged |= updateRotationUncheckedLocked(false);
Dianne Hackborn420829e2011-01-28 11:30:35 -080010041 }
Craig Mautner6cfa7292013-01-15 09:05:42 -080010042
Dianne Hackborn420829e2011-01-28 11:30:35 -080010043 if (configChanged) {
10044 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackborn89ba6752011-01-23 16:51:16 -080010045 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010046 }
Romain Guy06882f82009-06-10 13:36:04 -070010047
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010048 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
10049 DisplayMetrics dm) {
10050 if (index < tokens.length) {
10051 String str = tokens[index];
10052 if (str != null && str.length() > 0) {
10053 try {
10054 int val = Integer.parseInt(str);
10055 return val;
10056 } catch (Exception e) {
10057 }
10058 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010059 }
10060 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
10061 return defDps;
10062 }
10063 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
10064 return val;
10065 }
10066
Jeff Brown4ed8fe72012-08-30 18:18:29 -070010067 void createWatermarkInTransaction() {
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010068 if (mWatermark != null) {
10069 return;
10070 }
10071
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010072 File file = new File("/system/etc/setup.conf");
10073 FileInputStream in = null;
Craig Mautner2268e7e2012-12-13 15:40:00 -080010074 DataInputStream ind = null;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010075 try {
10076 in = new FileInputStream(file);
Craig Mautner2268e7e2012-12-13 15:40:00 -080010077 ind = new DataInputStream(in);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010078 String line = ind.readLine();
10079 if (line != null) {
10080 String[] toks = line.split("%");
10081 if (toks != null && toks.length > 0) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010082 mWatermark = new Watermark(getDefaultDisplayContentLocked().getDisplay(),
Jeff Browne215f262012-09-10 16:01:14 -070010083 mRealDisplayMetrics, mFxSession, toks);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010084 }
10085 }
10086 } catch (FileNotFoundException e) {
10087 } catch (IOException e) {
10088 } finally {
Craig Mautner2268e7e2012-12-13 15:40:00 -080010089 if (ind != null) {
10090 try {
10091 ind.close();
10092 } catch (IOException e) {
10093 }
Craig Mautner0bf6ec92012-12-18 08:33:27 -080010094 } else if (in != null) {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010095 try {
10096 in.close();
10097 } catch (IOException e) {
10098 }
10099 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010100 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010101 }
10102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010103 @Override
Joe Onorato664644d2011-01-23 17:53:23 -080010104 public void statusBarVisibilityChanged(int visibility) {
Dianne Hackborndf89e652011-10-06 22:35:11 -070010105 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
10106 != PackageManager.PERMISSION_GRANTED) {
10107 throw new SecurityException("Caller does not hold permission "
10108 + android.Manifest.permission.STATUS_BAR);
10109 }
Dianne Hackborn9a230e02011-10-06 11:51:27 -070010110
Joe Onorato664644d2011-01-23 17:53:23 -080010111 synchronized (mWindowMap) {
Dianne Hackborndf89e652011-10-06 22:35:11 -070010112 mLastStatusBarVisibility = visibility;
10113 visibility = mPolicy.adjustSystemUiVisibilityLw(visibility);
10114 updateStatusBarVisibilityLocked(visibility);
10115 }
10116 }
10117
Craig Mautner59c00972012-07-30 12:10:24 -070010118 // TOOD(multidisplay): StatusBar on multiple screens?
Dianne Hackborndf89e652011-10-06 22:35:11 -070010119 void updateStatusBarVisibilityLocked(int visibility) {
10120 mInputManager.setSystemUiVisibility(visibility);
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010121 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -070010122 final int N = windows.size();
Dianne Hackborndf89e652011-10-06 22:35:11 -070010123 for (int i = 0; i < N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -070010124 WindowState ws = windows.get(i);
Dianne Hackborndf89e652011-10-06 22:35:11 -070010125 try {
10126 int curValue = ws.mSystemUiVisibility;
10127 int diff = curValue ^ visibility;
10128 // We are only interested in differences of one of the
10129 // clearable flags...
10130 diff &= View.SYSTEM_UI_CLEARABLE_FLAGS;
10131 // ...if it has actually been cleared.
10132 diff &= ~visibility;
10133 int newValue = (curValue&~diff) | (visibility&diff);
10134 if (newValue != curValue) {
10135 ws.mSeq++;
10136 ws.mSystemUiVisibility = newValue;
10137 }
10138 if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) {
10139 ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq,
10140 visibility, newValue, diff);
10141 }
10142 } catch (RemoteException e) {
10143 // so sorry
10144 }
10145 }
10146 }
Craig Mautner6cfa7292013-01-15 09:05:42 -080010147
Dianne Hackborndf89e652011-10-06 22:35:11 -070010148 @Override
10149 public void reevaluateStatusBarVisibility() {
10150 synchronized (mWindowMap) {
10151 int visibility = mPolicy.adjustSystemUiVisibilityLw(mLastStatusBarVisibility);
10152 updateStatusBarVisibilityLocked(visibility);
10153 performLayoutAndPlaceSurfacesLocked();
10154 }
10155 }
10156
10157 @Override
Jeff Brown32cbc38552011-12-01 14:01:49 -080010158 public FakeWindow addFakeWindow(Looper looper,
10159 InputEventReceiver.Factory inputEventReceiverFactory,
Adam Lesinski95c42972013-10-02 10:13:27 -070010160 String name, int windowType, int layoutParamsFlags, int layoutParamsPrivateFlags,
10161 boolean canReceiveKeys, boolean hasFocus, boolean touchFullscreen) {
Dianne Hackborndf89e652011-10-06 22:35:11 -070010162 synchronized (mWindowMap) {
Jeff Brown32cbc38552011-12-01 14:01:49 -080010163 FakeWindowImpl fw = new FakeWindowImpl(this, looper, inputEventReceiverFactory,
10164 name, windowType,
Adam Lesinski95c42972013-10-02 10:13:27 -070010165 layoutParamsFlags, layoutParamsPrivateFlags, canReceiveKeys,
10166 hasFocus, touchFullscreen);
Dianne Hackborndf89e652011-10-06 22:35:11 -070010167 int i=0;
10168 while (i<mFakeWindows.size()) {
10169 if (mFakeWindows.get(i).mWindowLayer <= fw.mWindowLayer) {
10170 break;
Joe Onorato664644d2011-01-23 17:53:23 -080010171 }
10172 }
Dianne Hackborndf89e652011-10-06 22:35:11 -070010173 mFakeWindows.add(i, fw);
10174 mInputMonitor.updateInputWindowsLw(true);
10175 return fw;
10176 }
10177 }
10178
10179 boolean removeFakeWindowLocked(FakeWindow window) {
10180 synchronized (mWindowMap) {
10181 if (mFakeWindows.remove(window)) {
10182 mInputMonitor.updateInputWindowsLw(true);
10183 return true;
10184 }
10185 return false;
Joe Onorato664644d2011-01-23 17:53:23 -080010186 }
10187 }
10188
satoke0a99412012-05-10 02:22:58 +090010189 // It is assumed that this method is called only by InputMethodManagerService.
10190 public void saveLastInputMethodWindowForTransition() {
10191 synchronized (mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -070010192 // TODO(multidisplay): Pass in the displayID.
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010193 DisplayContent displayContent = getDefaultDisplayContentLocked();
satoke0a99412012-05-10 02:22:58 +090010194 if (mInputMethodWindow != null) {
10195 mPolicy.setLastInputMethodWindowLw(mInputMethodWindow, mInputMethodTarget);
10196 }
10197 }
10198 }
10199
Satoshi Kataoka658c7b82013-10-10 17:03:51 +090010200 public int getInputMethodWindowVisibleHeight() {
10201 synchronized (mWindowMap) {
10202 return mPolicy.getInputMethodWindowVisibleHeightLw();
10203 }
10204 }
10205
Daniel Sandler0c4ccff2011-10-19 16:39:14 -040010206 @Override
10207 public boolean hasNavigationBar() {
10208 return mPolicy.hasNavigationBar();
10209 }
10210
Craig Mautner96868332012-12-04 14:29:11 -080010211 @Override
Adam Cohenf7522022012-10-03 20:03:18 -070010212 public void lockNow(Bundle options) {
10213 mPolicy.lockNow(options);
Jim Miller93c518e2012-01-17 15:55:31 -080010214 }
Craig Mautner6cfa7292013-01-15 09:05:42 -080010215
Craig Mautner96868332012-12-04 14:29:11 -080010216 @Override
Jim Millerbfec0a82012-11-05 20:05:22 -080010217 public boolean isSafeModeEnabled() {
10218 return mSafeMode;
10219 }
Jim Miller93c518e2012-01-17 15:55:31 -080010220
Jeff Brownd7a04de2012-06-17 14:17:52 -070010221 void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010222 pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010223 mPolicy.dump(" ", pw, args);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010224 }
10225
Dianne Hackborn529e7442012-11-01 14:22:28 -070010226 void dumpAnimatorLocked(PrintWriter pw, String[] args, boolean dumpAll) {
10227 pw.println("WINDOW MANAGER ANIMATOR STATE (dumpsys window animator)");
10228 mAnimator.dumpLocked(pw, " ", dumpAll);
10229 }
10230
Jeff Brownd7a04de2012-06-17 14:17:52 -070010231 void dumpTokensLocked(PrintWriter pw, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010232 pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
10233 if (mTokenMap.size() > 0) {
10234 pw.println(" All tokens:");
10235 Iterator<WindowToken> it = mTokenMap.values().iterator();
10236 while (it.hasNext()) {
10237 WindowToken token = it.next();
Dianne Hackbornef03a7f2012-10-29 18:46:52 -070010238 pw.print(" "); pw.print(token);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010239 if (dumpAll) {
10240 pw.println(':');
10241 token.dump(pw, " ");
10242 } else {
10243 pw.println();
10244 }
10245 }
10246 }
10247 if (mWallpaperTokens.size() > 0) {
10248 pw.println();
10249 pw.println(" Wallpaper tokens:");
10250 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
10251 WindowToken token = mWallpaperTokens.get(i);
10252 pw.print(" Wallpaper #"); pw.print(i);
10253 pw.print(' '); pw.print(token);
10254 if (dumpAll) {
10255 pw.println(':');
10256 token.dump(pw, " ");
10257 } else {
10258 pw.println();
10259 }
10260 }
10261 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010262 if (mFinishedStarting.size() > 0) {
10263 pw.println();
10264 pw.println(" Finishing start of application tokens:");
10265 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
10266 WindowToken token = mFinishedStarting.get(i);
10267 pw.print(" Finished Starting #"); pw.print(i);
10268 pw.print(' '); pw.print(token);
10269 if (dumpAll) {
10270 pw.println(':');
10271 token.dump(pw, " ");
10272 } else {
10273 pw.println();
10274 }
10275 }
10276 }
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010277 if (mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
10278 pw.println();
10279 if (mOpeningApps.size() > 0) {
10280 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
10281 }
10282 if (mClosingApps.size() > 0) {
10283 pw.print(" mClosingApps="); pw.println(mClosingApps);
10284 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010285 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010286 }
10287
Jeff Brownd7a04de2012-06-17 14:17:52 -070010288 void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010289 pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
10290 if (mSessions.size() > 0) {
10291 Iterator<Session> it = mSessions.iterator();
10292 while (it.hasNext()) {
10293 Session s = it.next();
10294 pw.print(" Session "); pw.print(s); pw.println(':');
10295 s.dump(pw, " ");
10296 }
10297 }
10298 }
10299
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010300 void dumpDisplayContentsLocked(PrintWriter pw, boolean dumpAll) {
10301 pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)");
10302 if (mDisplayReady) {
Craig Mautnerf8924152013-07-16 09:10:55 -070010303 final int numDisplays = mDisplayContents.size();
10304 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10305 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautner127299f2013-11-12 17:57:47 +000010306 displayContent.dump(" ", pw);
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010307 }
10308 } else {
10309 pw.println(" NO DISPLAY");
10310 }
10311 }
10312
Jeff Brownd7a04de2012-06-17 14:17:52 -070010313 void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010314 ArrayList<WindowState> windows) {
10315 pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010316 dumpWindowsNoHeaderLocked(pw, dumpAll, windows);
10317 }
10318
10319 void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll,
10320 ArrayList<WindowState> windows) {
Craig Mautnerf8924152013-07-16 09:10:55 -070010321 final int numDisplays = mDisplayContents.size();
10322 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10323 final WindowList windowList = mDisplayContents.valueAt(displayNdx).getWindowList();
10324 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
10325 final WindowState w = windowList.get(winNdx);
10326 if (windows == null || windows.contains(w)) {
Craig Mautnerb1885b82013-09-16 22:50:50 -070010327 pw.print(" Window #"); pw.print(winNdx); pw.print(' ');
Craig Mautnerf8924152013-07-16 09:10:55 -070010328 pw.print(w); pw.println(":");
10329 w.dump(pw, " ", dumpAll || windows != null);
10330 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010331 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010332 }
10333 if (mInputMethodDialogs.size() > 0) {
10334 pw.println();
10335 pw.println(" Input method dialogs:");
10336 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
10337 WindowState w = mInputMethodDialogs.get(i);
10338 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010339 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010340 }
10341 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010342 }
10343 if (mPendingRemove.size() > 0) {
10344 pw.println();
10345 pw.println(" Remove pending for:");
10346 for (int i=mPendingRemove.size()-1; i>=0; i--) {
10347 WindowState w = mPendingRemove.get(i);
10348 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010349 pw.print(" Remove #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010350 pw.print(w);
10351 if (dumpAll) {
10352 pw.println(":");
10353 w.dump(pw, " ", true);
10354 } else {
10355 pw.println();
10356 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010357 }
10358 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010359 }
10360 if (mForceRemoves != null && mForceRemoves.size() > 0) {
10361 pw.println();
10362 pw.println(" Windows force removing:");
10363 for (int i=mForceRemoves.size()-1; i>=0; i--) {
10364 WindowState w = mForceRemoves.get(i);
10365 pw.print(" Removing #"); pw.print(i); pw.print(' ');
10366 pw.print(w);
10367 if (dumpAll) {
10368 pw.println(":");
10369 w.dump(pw, " ", true);
10370 } else {
10371 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010372 }
10373 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010374 }
10375 if (mDestroySurface.size() > 0) {
10376 pw.println();
10377 pw.println(" Windows waiting to destroy their surface:");
10378 for (int i=mDestroySurface.size()-1; i>=0; i--) {
10379 WindowState w = mDestroySurface.get(i);
10380 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010381 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010382 pw.print(w);
10383 if (dumpAll) {
10384 pw.println(":");
10385 w.dump(pw, " ", true);
10386 } else {
10387 pw.println();
10388 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010389 }
10390 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010391 }
10392 if (mLosingFocus.size() > 0) {
10393 pw.println();
10394 pw.println(" Windows losing focus:");
10395 for (int i=mLosingFocus.size()-1; i>=0; i--) {
10396 WindowState w = mLosingFocus.get(i);
10397 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010398 pw.print(" Losing #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010399 pw.print(w);
10400 if (dumpAll) {
10401 pw.println(":");
10402 w.dump(pw, " ", true);
10403 } else {
10404 pw.println();
10405 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010406 }
10407 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010408 }
10409 if (mResizingWindows.size() > 0) {
10410 pw.println();
10411 pw.println(" Windows waiting to resize:");
10412 for (int i=mResizingWindows.size()-1; i>=0; i--) {
10413 WindowState w = mResizingWindows.get(i);
10414 if (windows == null || windows.contains(w)) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010415 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010416 pw.print(w);
10417 if (dumpAll) {
10418 pw.println(":");
10419 w.dump(pw, " ", true);
10420 } else {
10421 pw.println();
10422 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010423 }
10424 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010425 }
Dianne Hackborn38e29a62011-09-18 14:43:08 -070010426 if (mWaitingForDrawn.size() > 0) {
10427 pw.println();
10428 pw.println(" Clients waiting for these windows to be drawn:");
10429 for (int i=mWaitingForDrawn.size()-1; i>=0; i--) {
10430 Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(i);
10431 pw.print(" Waiting #"); pw.print(i); pw.print(' '); pw.print(pair.first);
10432 pw.print(": "); pw.println(pair.second);
10433 }
10434 }
Dianne Hackborn77119bc2012-10-23 14:32:48 -070010435 pw.println();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010436 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
10437 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
10438 if (mLastFocus != mCurrentFocus) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010439 pw.print(" mLastFocus="); pw.println(mLastFocus);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010440 }
10441 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
10442 if (mInputMethodTarget != null) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010443 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010444 }
10445 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
10446 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborna57c6952013-03-29 14:46:40 -070010447 pw.print(" mLastDisplayFreezeDuration=");
10448 TimeUtils.formatDuration(mLastDisplayFreezeDuration, pw);
10449 if ( mLastFinishedFreezeSource != null) {
10450 pw.print(" due to ");
10451 pw.print(mLastFinishedFreezeSource);
10452 }
10453 pw.println();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010454 if (dumpAll) {
Craig Mautner28816302013-10-10 20:31:00 -070010455 pw.print(" mSystemDecorLayer="); pw.print(mSystemDecorLayer);
Dianne Hackbornc652de82013-02-15 16:32:56 -080010456 pw.print(" mScreenRect="); pw.println(mScreenRect.toShortString());
Dianne Hackborndf89e652011-10-06 22:35:11 -070010457 if (mLastStatusBarVisibility != 0) {
10458 pw.print(" mLastStatusBarVisibility=0x");
10459 pw.println(Integer.toHexString(mLastStatusBarVisibility));
10460 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010461 if (mInputMethodWindow != null) {
10462 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
10463 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -070010464 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn529e7442012-11-01 14:22:28 -070010465 if (mLowerWallpaperTarget != null || mUpperWallpaperTarget != null) {
Dianne Hackborn284ac932009-08-28 10:34:25 -070010466 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
10467 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
10468 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010469 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
10470 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
10471 if (mInputMethodAnimLayerAdjustment != 0 ||
10472 mWallpaperAnimLayerAdjustment != 0) {
10473 pw.print(" mInputMethodAnimLayerAdjustment=");
10474 pw.print(mInputMethodAnimLayerAdjustment);
10475 pw.print(" mWallpaperAnimLayerAdjustment=");
10476 pw.println(mWallpaperAnimLayerAdjustment);
10477 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010478 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
10479 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
Craig Mautner19d59bc2012-09-04 11:15:56 -070010480 if (needsLayout()) {
10481 pw.print(" layoutNeeded on displays=");
Craig Mautnerf8924152013-07-16 09:10:55 -070010482 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10483 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
Craig Mautner19d59bc2012-09-04 11:15:56 -070010484 if (displayContent.layoutNeeded) {
10485 pw.print(displayContent.getDisplayId());
10486 }
10487 }
10488 pw.println();
10489 }
Craig Mautner69b08182012-09-05 13:07:13 -070010490 pw.print(" mTransactionSequence="); pw.println(mTransactionSequence);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010491 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -070010492 pw.print(" windows="); pw.print(mWindowsFreezingScreen);
10493 pw.print(" client="); pw.print(mClientFreezingScreen);
10494 pw.print(" apps="); pw.print(mAppsFreezingScreen);
10495 pw.print(" waitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010496 pw.print(" mRotation="); pw.print(mRotation);
Dianne Hackborndacea8c2011-04-21 17:26:39 -070010497 pw.print(" mAltOrientation="); pw.println(mAltOrientation);
Craig Mautnerf20588f2012-04-11 17:06:21 -070010498 pw.print(" mLastWindowForcedOrientation="); pw.print(mLastWindowForcedOrientation);
Dianne Hackbornbc7386c2011-06-06 17:27:54 -070010499 pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation);
Jeff Brown01a98dd2011-09-20 15:08:29 -070010500 pw.print(" mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
Dianne Hackborn4dcece82012-02-10 14:50:32 -080010501 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
10502 pw.print(" mTransitionWindowAnimationScale="); pw.print(mTransitionAnimationScale);
Chet Haasec38fa1f2012-02-01 16:37:46 -080010503 pw.print(" mAnimatorDurationScale="); pw.println(mAnimatorDurationScale);
Craig Mautner164d4bb2012-11-26 13:51:23 -080010504 pw.print(" mTraversalScheduled="); pw.println(mTraversalScheduled);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010505 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010506 pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Dianne Hackborn529e7442012-11-01 14:22:28 -070010507 pw.println(" mLayoutToAnim:");
Craig Mautner164d4bb2012-11-26 13:51:23 -080010508 mAppTransition.dump(pw);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010509 }
10510 }
10511
Jeff Brownd7a04de2012-06-17 14:17:52 -070010512 boolean dumpWindows(PrintWriter pw, String name, String[] args,
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010513 int opti, boolean dumpAll) {
Craig Mautner722285e2012-09-07 13:55:58 -070010514 WindowList windows = new WindowList();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010515 if ("visible".equals(name)) {
10516 synchronized(mWindowMap) {
Craig Mautnerf8924152013-07-16 09:10:55 -070010517 final int numDisplays = mDisplayContents.size();
10518 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10519 final WindowList windowList =
10520 mDisplayContents.valueAt(displayNdx).getWindowList();
10521 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
10522 final WindowState w = windowList.get(winNdx);
10523 if (w.mWinAnimator.mSurfaceShown) {
10524 windows.add(w);
10525 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010526 }
10527 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010528 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010529 } else {
10530 int objectId = 0;
10531 // See if this is an object ID.
10532 try {
10533 objectId = Integer.parseInt(name, 16);
10534 name = null;
10535 } catch (RuntimeException e) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010536 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010537 synchronized(mWindowMap) {
Craig Mautnerf8924152013-07-16 09:10:55 -070010538 final int numDisplays = mDisplayContents.size();
10539 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10540 final WindowList windowList =
10541 mDisplayContents.valueAt(displayNdx).getWindowList();
10542 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
10543 final WindowState w = windowList.get(winNdx);
10544 if (name != null) {
10545 if (w.mAttrs.getTitle().toString().contains(name)) {
10546 windows.add(w);
10547 }
10548 } else if (System.identityHashCode(w) == objectId) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010549 windows.add(w);
10550 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010551 }
10552 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010553 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010554 }
10555
10556 if (windows.size() <= 0) {
10557 return false;
10558 }
10559
10560 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010561 dumpWindowsLocked(pw, dumpAll, windows);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010562 }
10563 return true;
10564 }
10565
Jeff Brownd7a04de2012-06-17 14:17:52 -070010566 void dumpLastANRLocked(PrintWriter pw) {
10567 pw.println("WINDOW MANAGER LAST ANR (dumpsys window lastanr)");
10568 if (mLastANRState == null) {
10569 pw.println(" <no ANR has occurred since boot>");
10570 } else {
10571 pw.println(mLastANRState);
10572 }
10573 }
10574
10575 /**
10576 * Saves information about the state of the window manager at
10577 * the time an ANR occurred before anything else in the system changes
10578 * in response.
10579 *
Jeff Brownee172412012-06-18 12:58:03 -070010580 * @param appWindowToken The application that ANR'd, may be null.
Jeff Brownd7a04de2012-06-17 14:17:52 -070010581 * @param windowState The window that ANR'd, may be null.
Jeff Brownbd181bb2013-09-10 16:44:24 -070010582 * @param reason The reason for the ANR, may be null.
Jeff Brownd7a04de2012-06-17 14:17:52 -070010583 */
Jeff Brownbd181bb2013-09-10 16:44:24 -070010584 public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState,
10585 String reason) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010586 StringWriter sw = new StringWriter();
Dianne Hackborn8c841092013-06-24 13:46:13 -070010587 PrintWriter pw = new FastPrintWriter(sw, false, 1024);
Jeff Brownd7a04de2012-06-17 14:17:52 -070010588 pw.println(" ANR time: " + DateFormat.getInstance().format(new Date()));
Jeff Brownee172412012-06-18 12:58:03 -070010589 if (appWindowToken != null) {
10590 pw.println(" Application at fault: " + appWindowToken.stringName);
10591 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010592 if (windowState != null) {
10593 pw.println(" Window at fault: " + windowState.mAttrs.getTitle());
10594 }
Jeff Brownbd181bb2013-09-10 16:44:24 -070010595 if (reason != null) {
10596 pw.println(" Reason: " + reason);
10597 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010598 pw.println();
10599 dumpWindowsNoHeaderLocked(pw, true, null);
10600 pw.close();
10601 mLastANRState = sw.toString();
10602 }
10603
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010604 @Override
10605 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10606 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
10607 != PackageManager.PERMISSION_GRANTED) {
10608 pw.println("Permission Denial: can't dump WindowManager from from pid="
10609 + Binder.getCallingPid()
10610 + ", uid=" + Binder.getCallingUid());
10611 return;
10612 }
10613
10614 boolean dumpAll = false;
10615
10616 int opti = 0;
10617 while (opti < args.length) {
10618 String opt = args[opti];
10619 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10620 break;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010621 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010622 opti++;
10623 if ("-a".equals(opt)) {
10624 dumpAll = true;
10625 } else if ("-h".equals(opt)) {
10626 pw.println("Window manager dump options:");
10627 pw.println(" [-a] [-h] [cmd] ...");
10628 pw.println(" cmd may be one of:");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010629 pw.println(" l[astanr]: last ANR information");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010630 pw.println(" p[policy]: policy state");
Dianne Hackborn529e7442012-11-01 14:22:28 -070010631 pw.println(" a[animator]: animator state");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010632 pw.println(" s[essions]: active sessions");
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010633 pw.println(" d[isplays]: active display contents");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010634 pw.println(" t[okens]: token list");
10635 pw.println(" w[indows]: window list");
10636 pw.println(" cmd may also be a NAME to dump windows. NAME may");
10637 pw.println(" be a partial substring in a window name, a");
10638 pw.println(" Window hex object identifier, or");
10639 pw.println(" \"all\" for all windows, or");
10640 pw.println(" \"visible\" for the visible windows.");
10641 pw.println(" -a: include all available server state.");
10642 return;
Dianne Hackborn87fc3082010-12-03 13:09:12 -080010643 } else {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010644 pw.println("Unknown argument: " + opt + "; use -h for help");
Dianne Hackborn87fc3082010-12-03 13:09:12 -080010645 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010646 }
10647
10648 // Is the caller requesting to dump a particular piece of data?
10649 if (opti < args.length) {
10650 String cmd = args[opti];
10651 opti++;
Jeff Brownd7a04de2012-06-17 14:17:52 -070010652 if ("lastanr".equals(cmd) || "l".equals(cmd)) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010653 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010654 dumpLastANRLocked(pw);
10655 }
10656 return;
10657 } else if ("policy".equals(cmd) || "p".equals(cmd)) {
10658 synchronized(mWindowMap) {
10659 dumpPolicyLocked(pw, args, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010660 }
10661 return;
Dianne Hackborn529e7442012-11-01 14:22:28 -070010662 } else if ("animator".equals(cmd) || "a".equals(cmd)) {
10663 synchronized(mWindowMap) {
10664 dumpAnimatorLocked(pw, args, true);
10665 }
10666 return;
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010667 } else if ("sessions".equals(cmd) || "s".equals(cmd)) {
10668 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010669 dumpSessionsLocked(pw, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010670 }
10671 return;
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010672 } else if ("displays".equals(cmd) || "d".equals(cmd)) {
10673 synchronized(mWindowMap) {
10674 dumpDisplayContentsLocked(pw, true);
10675 }
10676 return;
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010677 } else if ("tokens".equals(cmd) || "t".equals(cmd)) {
10678 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010679 dumpTokensLocked(pw, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010680 }
10681 return;
10682 } else if ("windows".equals(cmd) || "w".equals(cmd)) {
10683 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010684 dumpWindowsLocked(pw, true, null);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010685 }
10686 return;
10687 } else if ("all".equals(cmd) || "a".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 {
10693 // Dumping a single name?
Jeff Brownd7a04de2012-06-17 14:17:52 -070010694 if (!dumpWindows(pw, cmd, args, opti, dumpAll)) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010695 pw.println("Bad window command, or no windows match: " + cmd);
10696 pw.println("Use -h for help.");
10697 }
10698 return;
10699 }
10700 }
10701
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010702 synchronized(mWindowMap) {
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010703 pw.println();
10704 if (dumpAll) {
10705 pw.println("-------------------------------------------------------------------------------");
10706 }
10707 dumpLastANRLocked(pw);
10708 pw.println();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010709 if (dumpAll) {
10710 pw.println("-------------------------------------------------------------------------------");
10711 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010712 dumpPolicyLocked(pw, args, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010713 pw.println();
10714 if (dumpAll) {
10715 pw.println("-------------------------------------------------------------------------------");
10716 }
Dianne Hackborn529e7442012-11-01 14:22:28 -070010717 dumpAnimatorLocked(pw, args, dumpAll);
10718 pw.println();
10719 if (dumpAll) {
10720 pw.println("-------------------------------------------------------------------------------");
10721 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010722 dumpSessionsLocked(pw, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010723 pw.println();
10724 if (dumpAll) {
10725 pw.println("-------------------------------------------------------------------------------");
10726 }
Dianne Hackbornc4aad012013-02-22 15:05:25 -080010727 dumpDisplayContentsLocked(pw, dumpAll);
10728 pw.println();
10729 if (dumpAll) {
10730 pw.println("-------------------------------------------------------------------------------");
10731 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010732 dumpTokensLocked(pw, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010733 pw.println();
10734 if (dumpAll) {
10735 pw.println("-------------------------------------------------------------------------------");
10736 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010737 dumpWindowsLocked(pw, dumpAll, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010738 }
10739 }
10740
Jeff Brown349703e2010-06-22 01:27:15 -070010741 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
Craig Mautner96868332012-12-04 14:29:11 -080010742 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010743 public void monitor() {
10744 synchronized (mWindowMap) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070010745 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010746
Jeff Brown2992ea72011-01-28 22:04:14 -080010747 public interface OnHardKeyboardStatusChangeListener {
10748 public void onHardKeyboardStatusChange(boolean available, boolean enabled);
10749 }
Craig Mautnera2c77052012-03-26 12:14:43 -070010750
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070010751 void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
Craig Mautnercf8cbbe2012-03-25 21:54:36 -070010752 if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070010753 Slog.v(TAG, "Layouts looping: " + msg + ", mPendingLayoutChanges = 0x" +
10754 Integer.toHexString(pendingLayoutChanges));
Craig Mautnercf8cbbe2012-03-25 21:54:36 -070010755 }
10756 }
Craig Mautner59c00972012-07-30 12:10:24 -070010757
Dianne Hackbornc652de82013-02-15 16:32:56 -080010758 private DisplayContent newDisplayContentLocked(final Display display) {
Craig Mautner9d808b12013-08-06 18:00:25 -070010759 DisplayContent displayContent = new DisplayContent(display, this);
Craig Mautnercf910b02013-04-23 11:23:27 -070010760 final int displayId = display.getDisplayId();
Craig Mautner95da1082014-02-24 17:54:35 -080010761 if (DEBUG_DISPLAY) Slog.v(TAG, "Adding display=" + display);
Craig Mautnercf910b02013-04-23 11:23:27 -070010762 mDisplayContents.put(displayId, displayContent);
Jeff Brownef981a42013-08-07 14:13:37 -070010763
10764 DisplayInfo displayInfo = displayContent.getDisplayInfo();
Dianne Hackbornc652de82013-02-15 16:32:56 -080010765 final Rect rect = new Rect();
Jeff Brownef981a42013-08-07 14:13:37 -070010766 mDisplaySettings.getOverscanLocked(displayInfo.name, rect);
10767 synchronized (displayContent.mDisplaySizeLock) {
10768 displayInfo.overscanLeft = rect.left;
10769 displayInfo.overscanTop = rect.top;
10770 displayInfo.overscanRight = rect.right;
10771 displayInfo.overscanBottom = rect.bottom;
Jeff Brown4ccb8232014-01-16 22:16:42 -080010772 mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
Jeff Brownef981a42013-08-07 14:13:37 -070010773 displayId, displayInfo);
10774 }
10775 configureDisplayPolicyLocked(displayContent);
Craig Mautnercf910b02013-04-23 11:23:27 -070010776
10777 // TODO: Create an input channel for each display with touch capability.
10778 if (displayId == Display.DEFAULT_DISPLAY) {
Craig Mautner037aa8d2013-06-07 10:35:44 -070010779 displayContent.mTapDetector = new StackTapPointerEventListener(this, displayContent);
10780 registerPointerEventListener(displayContent.mTapDetector);
Craig Mautnercf910b02013-04-23 11:23:27 -070010781 }
10782
Dianne Hackbornc652de82013-02-15 16:32:56 -080010783 return displayContent;
10784 }
10785
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010786 public void createDisplayContentLocked(final Display display) {
Craig Mautner722285e2012-09-07 13:55:58 -070010787 if (display == null) {
10788 throw new IllegalArgumentException("getDisplayContent: display must not be null");
10789 }
keunyoung1eb06372013-08-09 14:32:36 -070010790 getDisplayContentLocked(display.getDisplayId());
Craig Mautner722285e2012-09-07 13:55:58 -070010791 }
10792
Craig Mautner2d5618c2012-10-18 13:55:47 -070010793 /**
10794 * Retrieve the DisplayContent for the specified displayId. Will create a new DisplayContent if
10795 * there is a Display for the displayId.
10796 * @param displayId The display the caller is interested in.
10797 * @return The DisplayContent associated with displayId or null if there is no Display for it.
10798 */
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010799 public DisplayContent getDisplayContentLocked(final int displayId) {
Craig Mautner59c00972012-07-30 12:10:24 -070010800 DisplayContent displayContent = mDisplayContents.get(displayId);
10801 if (displayContent == null) {
Craig Mautner2d5618c2012-10-18 13:55:47 -070010802 final Display display = mDisplayManager.getDisplay(displayId);
10803 if (display != null) {
Dianne Hackbornc652de82013-02-15 16:32:56 -080010804 displayContent = newDisplayContentLocked(display);
Craig Mautner2d5618c2012-10-18 13:55:47 -070010805 }
Craig Mautner59c00972012-07-30 12:10:24 -070010806 }
10807 return displayContent;
10808 }
10809
Craig Mautner2d5618c2012-10-18 13:55:47 -070010810 // There is an inherent assumption that this will never return null.
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010811 public DisplayContent getDefaultDisplayContentLocked() {
10812 return getDisplayContentLocked(Display.DEFAULT_DISPLAY);
Craig Mautner59c00972012-07-30 12:10:24 -070010813 }
10814
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010815 public WindowList getDefaultWindowListLocked() {
10816 return getDefaultDisplayContentLocked().getWindowList();
Craig Mautner59c00972012-07-30 12:10:24 -070010817 }
10818
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010819 public DisplayInfo getDefaultDisplayInfoLocked() {
10820 return getDefaultDisplayContentLocked().getDisplayInfo();
Craig Mautner59c00972012-07-30 12:10:24 -070010821 }
10822
Craig Mautner2d5618c2012-10-18 13:55:47 -070010823 /**
10824 * Return the list of WindowStates associated on the passed display.
10825 * @param display The screen to return windows from.
10826 * @return The list of WindowStates on the screen, or null if the there is no screen.
10827 */
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010828 public WindowList getWindowListLocked(final Display display) {
Craig Mautner96868332012-12-04 14:29:11 -080010829 return getWindowListLocked(display.getDisplayId());
10830 }
10831
10832 /**
10833 * Return the list of WindowStates associated on the passed display.
10834 * @param displayId The screen to return windows from.
10835 * @return The list of WindowStates on the screen, or null if the there is no screen.
10836 */
10837 public WindowList getWindowListLocked(final int displayId) {
10838 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -070010839 return displayContent != null ? displayContent.getWindowList() : null;
Craig Mautner39834192012-09-02 07:47:24 -070010840 }
Craig Mautner722285e2012-09-07 13:55:58 -070010841
Craig Mautner722285e2012-09-07 13:55:58 -070010842 public void onDisplayAdded(int displayId) {
10843 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_ADDED, displayId, 0));
10844 }
10845
Craig Mautnerad25fa32014-01-12 21:19:06 -080010846 public void handleDisplayAdded(int displayId) {
10847 synchronized (mWindowMap) {
10848 final Display display = mDisplayManager.getDisplay(displayId);
10849 if (display != null) {
10850 createDisplayContentLocked(display);
10851 displayReady(displayId);
10852 }
Craig Mautner2d5618c2012-10-18 13:55:47 -070010853 }
Craig Mautner722285e2012-09-07 13:55:58 -070010854 }
10855
Craig Mautner722285e2012-09-07 13:55:58 -070010856 public void onDisplayRemoved(int displayId) {
10857 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_REMOVED, displayId, 0));
10858 }
10859
10860 private void handleDisplayRemovedLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010861 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -070010862 if (displayContent != null) {
Craig Mautner95da1082014-02-24 17:54:35 -080010863 if (displayContent.isAnimating()) {
10864 displayContent.mDeferredRemoval = true;
Craig Mautner1bf2b872014-02-05 15:37:40 -080010865 return;
10866 }
Craig Mautner95da1082014-02-24 17:54:35 -080010867 if (DEBUG_DISPLAY) Slog.v(TAG, "Removing display=" + displayContent);
Craig Mautner2d5618c2012-10-18 13:55:47 -070010868 mDisplayContents.delete(displayId);
Craig Mautner2eb15342013-08-07 13:13:35 -070010869 displayContent.close();
Craig Mautner037aa8d2013-06-07 10:35:44 -070010870 if (displayId == Display.DEFAULT_DISPLAY) {
10871 unregisterPointerEventListener(displayContent.mTapDetector);
Andreas Huberb551c6d2013-04-26 11:54:53 -070010872 }
Craig Mautner722285e2012-09-07 13:55:58 -070010873 }
Craig Mautnera91f9e22012-09-14 16:22:08 -070010874 mAnimator.removeDisplayLocked(displayId);
Craig Mautner722285e2012-09-07 13:55:58 -070010875 }
10876
Craig Mautner722285e2012-09-07 13:55:58 -070010877 public void onDisplayChanged(int displayId) {
10878 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_CHANGED, displayId, 0));
10879 }
10880
10881 private void handleDisplayChangedLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010882 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner722285e2012-09-07 13:55:58 -070010883 if (displayContent != null) {
10884 displayContent.updateDisplayInfo();
10885 }
10886 }
John Spurlock04db1762013-05-13 12:46:41 -040010887
10888 @Override
10889 public Object getWindowManagerLock() {
10890 return mWindowMap;
10891 }
Jeff Brown4ccb8232014-01-16 22:16:42 -080010892
10893 private final class LocalService extends WindowManagerInternal {
10894 @Override
10895 public void requestTraversalFromDisplayManager() {
10896 requestTraversal();
10897 }
Svetoslav8e3feb12014-02-24 13:46:47 -080010898
10899 @Override
10900 public void setMagnificationSpec(MagnificationSpec spec) {
10901 synchronized (mWindowMap) {
10902 if (mAccessibilityController != null) {
10903 mAccessibilityController.setMagnificationSpecLocked(spec);
10904 } else {
10905 throw new IllegalStateException("Magnification callbacks not set!");
10906 }
10907 }
10908 if (Binder.getCallingPid() != android.os.Process.myPid()) {
10909 spec.recycle();
10910 }
10911 }
10912
10913 @Override
10914 public MagnificationSpec getCompatibleMagnificationSpecForWindow(IBinder windowToken) {
10915 synchronized (mWindowMap) {
10916 WindowState windowState = mWindowMap.get(windowToken);
10917 if (windowState == null) {
10918 return null;
10919 }
10920 MagnificationSpec spec = null;
10921 if (mAccessibilityController != null) {
10922 spec = mAccessibilityController.getMagnificationSpecForWindowLocked(windowState);
10923 }
10924 if ((spec == null || spec.isNop()) && windowState.mGlobalScale == 1.0f) {
10925 return null;
10926 }
10927 spec = (spec == null) ? MagnificationSpec.obtain() : MagnificationSpec.obtain(spec);
10928 spec.scale *= windowState.mGlobalScale;
10929 return spec;
10930 }
10931 }
10932
10933 @Override
10934 public void setMagnificationCallbacks(MagnificationCallbacks callbacks) {
10935 synchronized (mWindowMap) {
10936 if (mAccessibilityController == null) {
10937 mAccessibilityController = new AccessibilityController(
10938 WindowManagerService.this);
10939 }
10940 mAccessibilityController.setMagnificationCallbacksLocked(callbacks);
10941 if (!mAccessibilityController.hasCallbacksLocked()) {
10942 mAccessibilityController = null;
10943 }
10944 }
10945 }
10946
10947 @Override
10948 public void setWindowsForAccessibilityCallback(WindowsForAccessibilityCallback callback) {
10949 synchronized (mWindowMap) {
10950 if (mAccessibilityController == null) {
10951 mAccessibilityController = new AccessibilityController(
10952 WindowManagerService.this);
10953 }
10954 mAccessibilityController.setWindowsForAccessibilityCallback(callback);
10955 if (!mAccessibilityController.hasCallbacksLocked()) {
10956 mAccessibilityController = null;
10957 }
10958 }
10959 }
10960
10961 @Override
10962 public void setInputFilter(IInputFilter filter) {
10963 mInputManager.setInputFilter(filter);
10964 }
10965
10966 @Override
10967 public IBinder getFocusedWindowToken() {
10968 synchronized (mWindowMap) {
10969 WindowState windowState = getFocusedWindowLocked();
10970 if (windowState != null) {
10971 return windowState.mClient.asBinder();
10972 }
10973 return null;
10974 }
10975 }
10976
10977 @Override
10978 public boolean isKeyguardLocked() {
10979 return isKeyguardLocked();
10980 }
10981
10982 @Override
10983 public void getWindowFrame(IBinder token, Rect outBounds) {
10984 synchronized (mWindowMap) {
10985 WindowState windowState = mWindowMap.get(token);
10986 if (windowState != null) {
10987 outBounds.set(windowState.mFrame);
10988 } else {
10989 outBounds.setEmpty();
10990 }
10991 }
10992 }
Jeff Brown4ccb8232014-01-16 22:16:42 -080010993 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010994}