blob: 68f0e66dfdac807d767021e290556e64915b203c [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080017package com.android.server.wm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080019import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
20import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
21import static android.view.WindowManager.LayoutParams.FLAG_BLUR_BEHIND;
Dianne Hackborn5fd21692011-06-07 14:09:47 -070022import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
24import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
26import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070027import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
29import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
31import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
32import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
33import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070034import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035
36import com.android.internal.app.IBatteryStats;
37import com.android.internal.policy.PolicyManager;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080038import com.android.internal.policy.impl.PhoneWindowManager;
Christopher Tatea53146c2010-09-07 11:57:52 -070039import com.android.internal.view.BaseInputHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import com.android.internal.view.IInputContext;
41import com.android.internal.view.IInputMethodClient;
42import com.android.internal.view.IInputMethodManager;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080043import com.android.internal.view.WindowManagerPolicyThread;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080044import com.android.server.AttributeCache;
45import com.android.server.EventLogTags;
46import com.android.server.PowerManagerService;
47import com.android.server.Watchdog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import com.android.server.am.BatteryStatsService;
49
50import android.Manifest;
51import android.app.ActivityManagerNative;
52import android.app.IActivityManager;
Joe Onoratoac0ee892011-01-30 15:38:30 -080053import android.app.StatusBarManager;
Jim Millerd6b57052010-06-07 17:52:42 -070054import android.app.admin.DevicePolicyManager;
Jim Miller284b62e2010-06-08 14:27:42 -070055import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056import android.content.Context;
Jim Miller284b62e2010-06-08 14:27:42 -070057import android.content.Intent;
58import android.content.IntentFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059import android.content.pm.ActivityInfo;
60import android.content.pm.PackageManager;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070061import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import android.content.res.Configuration;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080063import android.graphics.Bitmap;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070064import android.graphics.Canvas;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import android.graphics.Matrix;
66import android.graphics.PixelFormat;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -070067import android.graphics.Point;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068import android.graphics.Rect;
69import android.graphics.Region;
70import android.os.BatteryStats;
71import android.os.Binder;
Dianne Hackborn75804932009-10-20 20:15:20 -070072import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.os.Debug;
74import android.os.Handler;
75import android.os.IBinder;
Dianne Hackborn38e29a62011-09-18 14:43:08 -070076import android.os.IRemoteCallback;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077import android.os.LocalPowerManager;
78import android.os.Looper;
79import android.os.Message;
80import android.os.Parcel;
81import android.os.ParcelFileDescriptor;
82import android.os.Power;
83import android.os.PowerManager;
84import android.os.Process;
85import android.os.RemoteException;
86import android.os.ServiceManager;
Brad Fitzpatrickec062f62010-11-03 09:56:54 -070087import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088import android.os.SystemClock;
89import android.os.SystemProperties;
90import android.os.TokenWatcher;
91import android.provider.Settings;
Dianne Hackborn723738c2009-06-25 19:48:04 -070092import android.util.DisplayMetrics;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093import android.util.EventLog;
Jim Millerd6b57052010-06-07 17:52:42 -070094import android.util.Log;
Dianne Hackborn38e29a62011-09-18 14:43:08 -070095import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -080096import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097import android.util.SparseIntArray;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070098import android.util.TypedValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099import android.view.Display;
Adam Powelldfee59a2011-08-05 20:48:30 -0700100import android.view.Gravity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101import android.view.IApplicationToken;
102import android.view.IOnKeyguardExitResult;
103import android.view.IRotationWatcher;
104import android.view.IWindow;
105import android.view.IWindowManager;
106import android.view.IWindowSession;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700107import android.view.InputChannel;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700108import android.view.InputDevice;
Jeff Brownbbda99d2010-07-28 15:48:59 -0700109import android.view.InputEvent;
Christopher Tatea53146c2010-09-07 11:57:52 -0700110import android.view.InputHandler;
111import android.view.InputQueue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112import android.view.KeyEvent;
113import android.view.MotionEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114import android.view.Surface;
115import android.view.SurfaceSession;
116import android.view.View;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117import android.view.WindowManager;
118import android.view.WindowManagerImpl;
119import android.view.WindowManagerPolicy;
120import android.view.WindowManager.LayoutParams;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700121import android.view.WindowManagerPolicy.FakeWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122import android.view.animation.Animation;
123import android.view.animation.AnimationUtils;
124import android.view.animation.Transformation;
125
126import java.io.BufferedWriter;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700127import java.io.DataInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128import java.io.File;
129import java.io.FileDescriptor;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700130import java.io.FileInputStream;
131import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132import java.io.IOException;
133import java.io.OutputStream;
134import java.io.OutputStreamWriter;
135import java.io.PrintWriter;
136import java.io.StringWriter;
137import java.net.Socket;
138import java.util.ArrayList;
139import java.util.HashMap;
140import java.util.HashSet;
141import java.util.Iterator;
142import java.util.List;
143
144/** {@hide} */
Dianne Hackbornddca3ee2009-07-23 19:01:31 -0700145public class WindowManagerService extends IWindowManager.Stub
Dianne Hackborndf89e652011-10-06 22:35:11 -0700146 implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 static final String TAG = "WindowManager";
148 static final boolean DEBUG = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800149 static final boolean DEBUG_ADD_REMOVE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 static final boolean DEBUG_FOCUS = false;
151 static final boolean DEBUG_ANIM = false;
Dianne Hackborn9b52a212009-12-11 14:51:35 -0800152 static final boolean DEBUG_LAYOUT = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800153 static final boolean DEBUG_RESIZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154 static final boolean DEBUG_LAYERS = false;
155 static final boolean DEBUG_INPUT = false;
156 static final boolean DEBUG_INPUT_METHOD = false;
157 static final boolean DEBUG_VISIBILITY = false;
Dianne Hackbornbdd52b22009-09-02 21:46:19 -0700158 static final boolean DEBUG_WINDOW_MOVEMENT = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800159 static final boolean DEBUG_TOKEN_MOVEMENT = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 static final boolean DEBUG_ORIENTATION = false;
Dianne Hackbornbc7386c2011-06-06 17:27:54 -0700161 static final boolean DEBUG_APP_ORIENTATION = false;
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700162 static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 static final boolean DEBUG_APP_TRANSITIONS = false;
164 static final boolean DEBUG_STARTING_WINDOW = false;
165 static final boolean DEBUG_REORDER = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700166 static final boolean DEBUG_WALLPAPER = false;
Christopher Tate994ef922011-01-12 20:06:07 -0800167 static final boolean DEBUG_DRAG = false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700168 static final boolean DEBUG_SCREEN_ON = false;
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -0700169 static final boolean DEBUG_SCREENSHOT = false;
Dianne Hackborn38cc8962011-10-13 11:33:55 -0700170 static final boolean DEBUG_BOOT = false;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700171 static final boolean SHOW_SURFACE_ALLOC = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 static final boolean SHOW_TRANSACTIONS = false;
Dianne Hackborn36991742011-10-11 21:35:26 -0700173 static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700174 static final boolean HIDE_STACK_CRAWLS = true;
Michael Chan53071d62009-05-13 17:29:48 -0700175
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176 static final boolean PROFILE_ORIENTATION = false;
177 static final boolean BLUR = true;
Dave Bortcfe65242009-04-09 14:51:04 -0700178 static final boolean localLOGV = DEBUG;
Romain Guy06882f82009-06-10 13:36:04 -0700179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800180 /** How much to multiply the policy's type layer, to reserve room
181 * for multiple windows of the same type and Z-ordering adjustment
182 * with TYPE_LAYER_OFFSET. */
183 static final int TYPE_LAYER_MULTIPLIER = 10000;
Romain Guy06882f82009-06-10 13:36:04 -0700184
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
186 * or below others in the same layer. */
187 static final int TYPE_LAYER_OFFSET = 1000;
Romain Guy06882f82009-06-10 13:36:04 -0700188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189 /** How much to increment the layer for each window, to reserve room
190 * for effect surfaces between them.
191 */
192 static final int WINDOW_LAYER_MULTIPLIER = 5;
Romain Guy06882f82009-06-10 13:36:04 -0700193
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800194 /**
195 * Dim surface layer is immediately below target window.
196 */
197 static final int LAYER_OFFSET_DIM = 1;
198
199 /**
200 * Blur surface layer is immediately below dim layer.
201 */
202 static final int LAYER_OFFSET_BLUR = 2;
203
Dianne Hackborn7916ac62011-05-16 20:45:48 -0700204 /**
205 * Layer at which to put the rotation freeze snapshot.
206 */
207 static final int FREEZE_LAYER = (TYPE_LAYER_MULTIPLIER * 200) + 1;
208
209 /**
210 * Layer at which to put the mask for emulated screen sizes.
211 */
212 static final int MASK_LAYER = TYPE_LAYER_MULTIPLIER * 200;
213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214 /** The maximum length we will accept for a loaded animation duration:
215 * this is 10 seconds.
216 */
217 static final int MAX_ANIMATION_DURATION = 10*1000;
218
219 /** Amount of time (in milliseconds) to animate the dim surface from one
220 * value to another, when no window animation is driving it.
221 */
222 static final int DEFAULT_DIM_DURATION = 200;
223
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700224 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
225 * compatible windows.
226 */
227 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
228
Dianne Hackborna1111872010-11-23 20:55:11 -0800229 /**
230 * If true, the window manager will do its own custom freezing and general
231 * management of the screen during rotation.
232 */
233 static final boolean CUSTOM_SCREEN_ROTATION = true;
234
Jeff Brown7fbdc842010-06-17 20:52:56 -0700235 // Maximum number of milliseconds to wait for input event injection.
236 // FIXME is this value reasonable?
237 private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000;
Jeff Brownb09abc12011-01-13 21:08:27 -0800238
239 // Maximum number of milliseconds to wait for input devices to be enumerated before
240 // proceding with safe mode detection.
241 private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
Jim Miller28637ba2011-07-06 19:57:05 -0700242
Jeff Brown349703e2010-06-22 01:27:15 -0700243 // Default input dispatching timeout in nanoseconds.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800244 static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
Romain Guy06882f82009-06-10 13:36:04 -0700245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246 static final int UPDATE_FOCUS_NORMAL = 0;
247 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
248 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
249 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700252 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253
254 /**
255 * Condition waited on by {@link #reenableKeyguard} to know the call to
256 * the window policy has finished.
Mike Lockwood983ee092009-11-22 01:42:24 -0500257 * This is set to true only if mKeyguardTokenWatcher.acquired() has
258 * actually disabled the keyguard.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 */
Mike Lockwood983ee092009-11-22 01:42:24 -0500260 private boolean mKeyguardDisabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261
Jim Miller284b62e2010-06-08 14:27:42 -0700262 private static final int ALLOW_DISABLE_YES = 1;
263 private static final int ALLOW_DISABLE_NO = 0;
264 private static final int ALLOW_DISABLE_UNKNOWN = -1; // check with DevicePolicyManager
265 private int mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN; // sync'd by mKeyguardTokenWatcher
266
Mike Lockwood983ee092009-11-22 01:42:24 -0500267 final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher(
268 new Handler(), "WindowManagerService.mKeyguardTokenWatcher") {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269 public void acquired() {
Jim Miller284b62e2010-06-08 14:27:42 -0700270 if (shouldAllowDisableKeyguard()) {
271 mPolicy.enableKeyguard(false);
272 mKeyguardDisabled = true;
273 } else {
274 Log.v(TAG, "Not disabling keyguard since device policy is enforced");
275 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 }
277 public void released() {
Dianne Hackborna33e3f72009-09-29 17:28:24 -0700278 mPolicy.enableKeyguard(true);
Mike Lockwood983ee092009-11-22 01:42:24 -0500279 synchronized (mKeyguardTokenWatcher) {
280 mKeyguardDisabled = false;
281 mKeyguardTokenWatcher.notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800282 }
283 }
284 };
285
Jim Miller284b62e2010-06-08 14:27:42 -0700286 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
287 @Override
288 public void onReceive(Context context, Intent intent) {
289 mPolicy.enableKeyguard(true);
290 synchronized(mKeyguardTokenWatcher) {
291 // lazily evaluate this next time we're asked to disable keyguard
292 mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
293 mKeyguardDisabled = false;
294 }
295 }
296 };
297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800298 final Context mContext;
299
300 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700301
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700302 final boolean mAllowBootMessages;
303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
307
308 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700309
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700311
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312 /**
313 * All currently active sessions with clients.
314 */
315 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 /**
318 * Mapping from an IWindow IBinder to the server's Window object.
319 * This is also used as the lock for all of our state.
320 */
321 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
322
323 /**
324 * Mapping from a token IBinder to a WindowToken object.
325 */
326 final HashMap<IBinder, WindowToken> mTokenMap =
327 new HashMap<IBinder, WindowToken>();
328
329 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 * Window tokens that are in the process of exiting, but still
331 * on screen for animations.
332 */
333 final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
334
335 /**
336 * Z-ordered (bottom-most first) list of all application tokens, for
337 * controlling the ordering of windows in different applications. This
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800338 * contains AppWindowToken objects.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339 */
340 final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
341
342 /**
343 * Application tokens that are in the process of exiting, but still
344 * on screen for animations.
345 */
346 final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
347
348 /**
349 * List of window tokens that have finished starting their application,
350 * and now need to have the policy remove their windows.
351 */
352 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
353
354 /**
355 * Z-ordered (bottom-most first) list of all Window objects.
356 */
Jeff Browne33348b2010-07-15 23:54:05 -0700357 final ArrayList<WindowState> mWindows = new ArrayList<WindowState>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358
359 /**
Dianne Hackborndf89e652011-10-06 22:35:11 -0700360 * Fake windows added to the window manager. Note: ordered from top to
361 * bottom, opposite of mWindows.
362 */
363 final ArrayList<FakeWindowImpl> mFakeWindows = new ArrayList<FakeWindowImpl>();
364
365 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 * Windows that are being resized. Used so we can tell the client about
367 * the resize after closing the transaction in which we resized the
368 * underlying surface.
369 */
370 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
371
372 /**
373 * Windows whose animations have ended and now must be removed.
374 */
375 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
376
377 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800378 * Used when processing mPendingRemove to avoid working on the original array.
379 */
380 WindowState[] mPendingRemoveTmp = new WindowState[20];
381
382 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800383 * Windows whose surface should be destroyed.
384 */
385 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
386
387 /**
388 * Windows that have lost input focus and are waiting for the new
389 * focus window to be displayed before they are told about this.
390 */
391 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
392
393 /**
394 * This is set when we have run out of memory, and will either be an empty
395 * list or contain windows that need to be force removed.
396 */
397 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700398
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800399 /**
Dianne Hackborn38e29a62011-09-18 14:43:08 -0700400 * Windows that clients are waiting to have drawn.
401 */
402 ArrayList<Pair<WindowState, IRemoteCallback>> mWaitingForDrawn
403 = new ArrayList<Pair<WindowState, IRemoteCallback>>();
404
405 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800406 * Used when rebuilding window list to keep track of windows that have
407 * been removed.
408 */
409 WindowState[] mRebuildTmp = new WindowState[20];
410
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700412
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800413 SurfaceSession mFxSession;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700414 private DimAnimator mDimAnimator = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 Surface mBlurSurface;
416 boolean mBlurShown;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700417 Watermark mWatermark;
Brad Fitzpatrick68044332010-11-22 18:19:48 -0800418 StrictModeFlash mStrictModeFlash;
Dianne Hackborna1111872010-11-23 20:55:11 -0800419 ScreenRotationAnimation mScreenRotationAnimation;
Romain Guy06882f82009-06-10 13:36:04 -0700420
Dianne Hackborn7916ac62011-05-16 20:45:48 -0700421 BlackFrame mBlackFrame;
422
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800423 int mTransactionSequence = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425 final float[] mTmpFloats = new float[9];
426
427 boolean mSafeMode;
428 boolean mDisplayEnabled = false;
429 boolean mSystemBooted = false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700430 boolean mForceDisplayEnabled = false;
Dianne Hackborn661cd522011-08-22 00:26:20 -0700431 boolean mShowingBootMessages = false;
Christopher Tateb696aee2010-04-02 19:08:30 -0700432 int mInitialDisplayWidth = 0;
433 int mInitialDisplayHeight = 0;
Dianne Hackborn7916ac62011-05-16 20:45:48 -0700434 int mBaseDisplayWidth = 0;
435 int mBaseDisplayHeight = 0;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -0700436 int mCurDisplayWidth = 0;
437 int mCurDisplayHeight = 0;
Dianne Hackborn81e56d52011-05-26 00:55:58 -0700438 int mAppDisplayWidth = 0;
439 int mAppDisplayHeight = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800440 int mRotation = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborndacea8c2011-04-21 17:26:39 -0700442 boolean mAltOrientation = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800443 ArrayList<IRotationWatcher> mRotationWatchers
444 = new ArrayList<IRotationWatcher>();
Jeff Brown01a98dd2011-09-20 15:08:29 -0700445 int mDeferredRotationPauseCount;
Romain Guy06882f82009-06-10 13:36:04 -0700446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800447 boolean mLayoutNeeded = true;
448 boolean mAnimationPending = false;
449 boolean mDisplayFrozen = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800450 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 boolean mWindowsFreezingScreen = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452 int mAppsFreezingScreen = 0;
Dianne Hackbornbc7386c2011-06-06 17:27:54 -0700453 int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800455 int mLayoutSeq = 0;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700456
457 int mLastStatusBarVisibility = 0;
458
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800459 // State while inside of layoutAndPlaceSurfacesLocked().
460 boolean mFocusMayChange;
461
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800462 Configuration mCurConfiguration = new Configuration();
463
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800464 // This is held as long as we have the screen frozen, to give us time to
465 // perform a rotation animation when turning off shows the lock screen which
466 // changes the orientation.
467 PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800469 // State management of app transitions. When we are preparing for a
470 // transition, mNextAppTransition will be the kind of transition to
471 // perform or TRANSIT_NONE if we are not waiting. If we are waiting,
472 // mOpeningApps and mClosingApps are the lists of tokens that will be
473 // made visible or hidden at the next transition.
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700474 int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700475 String mNextAppTransitionPackage;
476 int mNextAppTransitionEnter;
477 int mNextAppTransitionExit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800478 boolean mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -0700479 boolean mAppTransitionRunning = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 boolean mAppTransitionTimeout = false;
481 boolean mStartingIconInTransition = false;
482 boolean mSkipAppTransitionAnimation = false;
483 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
484 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Dianne Hackborna8f60182009-09-01 19:01:50 -0700485 final ArrayList<AppWindowToken> mToTopApps = new ArrayList<AppWindowToken>();
486 final ArrayList<AppWindowToken> mToBottomApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700487
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488 Display mDisplay;
Romain Guy06882f82009-06-10 13:36:04 -0700489
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700490 final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Jeff Brownbc68a592011-07-25 12:58:12 -0700491 final DisplayMetrics mRealDisplayMetrics = new DisplayMetrics();
Dianne Hackborn48a76512011-06-08 21:51:44 -0700492 final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics();
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700493 final DisplayMetrics mCompatDisplayMetrics = new DisplayMetrics();
494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 H mH = new H();
496
497 WindowState mCurrentFocus = null;
498 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800500 // This just indicates the window the input method is on top of, not
501 // necessarily the window its input is going to.
502 WindowState mInputMethodTarget = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800503 boolean mInputMethodTargetWaitingAnim;
504 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 WindowState mInputMethodWindow = null;
507 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
508
Jeff Brown2992ea72011-01-28 22:04:14 -0800509 boolean mHardKeyboardAvailable;
510 boolean mHardKeyboardEnabled;
511 OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
512
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700513 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800514
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700515 // If non-null, this is the currently visible window that is associated
516 // with the wallpaper.
517 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700518 // If non-null, we are in the middle of animating from one wallpaper target
519 // to another, and this is the lower one in Z-order.
520 WindowState mLowerWallpaperTarget = null;
521 // If non-null, we are in the middle of animating from one wallpaper target
522 // to another, and this is the higher one in Z-order.
523 WindowState mUpperWallpaperTarget = null;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -0800524 // Window currently running an animation that has requested it be detached
525 // from the wallpaper. This means we need to ensure the wallpaper is
526 // visible behind it in case it animates in a way that would allow it to be
527 // seen.
528 WindowState mWindowDetachedWallpaper = null;
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800529 DimSurface mWindowAnimationBackgroundSurface = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700530 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700531 float mLastWallpaperX = -1;
532 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800533 float mLastWallpaperXStep = -1;
534 float mLastWallpaperYStep = -1;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700535 // This is set when we are waiting for a wallpaper to tell us it is done
536 // changing its scroll position.
537 WindowState mWaitingOnWallpaper;
538 // The last time we had a timeout when waiting for a wallpaper.
539 long mLastWallpaperTimeoutTime;
540 // We give a wallpaper up to 150ms to finish scrolling.
541 static final long WALLPAPER_TIMEOUT = 150;
542 // Time we wait after a timeout before trying to wait again.
543 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800545 AppWindowToken mFocusedApp = null;
546
547 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700548
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 float mWindowAnimationScale = 1.0f;
550 float mTransitionAnimationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700551
Jeff Brown46b9ac02010-04-22 18:58:52 -0700552 final InputManager mInputManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800553
554 // Who is holding the screen on.
555 Session mHoldingScreenOn;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700556 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700557
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700558 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800559
Christopher Tatea53146c2010-09-07 11:57:52 -0700560 DragState mDragState = null;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800561 final InputHandler mDragInputHandler = new BaseInputHandler() {
Christopher Tatea53146c2010-09-07 11:57:52 -0700562 @Override
Jeff Brown3915bb82010-11-05 15:02:16 -0700563 public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
564 boolean handled = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700565 try {
Jeff Brown3915bb82010-11-05 15:02:16 -0700566 if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
567 && mDragState != null) {
568 boolean endDrag = false;
569 final float newX = event.getRawX();
570 final float newY = event.getRawY();
571
Christopher Tatea53146c2010-09-07 11:57:52 -0700572 switch (event.getAction()) {
573 case MotionEvent.ACTION_DOWN: {
574 if (DEBUG_DRAG) {
575 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
576 }
577 } break;
578
579 case MotionEvent.ACTION_MOVE: {
580 synchronized (mWindowMap) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700581 // move the surface and tell the involved window(s) where we are
Christopher Tatea53146c2010-09-07 11:57:52 -0700582 mDragState.notifyMoveLw(newX, newY);
583 }
584 } break;
585
586 case MotionEvent.ACTION_UP: {
587 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
588 + newX + "," + newY);
589 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700590 endDrag = mDragState.notifyDropLw(newX, newY);
Christopher Tatea53146c2010-09-07 11:57:52 -0700591 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700592 } break;
593
594 case MotionEvent.ACTION_CANCEL: {
595 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
596 endDrag = true;
597 } break;
598 }
599
600 if (endDrag) {
601 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
602 // tell all the windows that the drag has ended
Chris Tate59943592010-10-11 20:33:44 -0700603 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700604 mDragState.endDragLw();
Chris Tate59943592010-10-11 20:33:44 -0700605 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700606 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700607
608 handled = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700609 }
610 } catch (Exception e) {
611 Slog.e(TAG, "Exception caught by drag handleMotion", e);
612 } finally {
Jeff Brown3915bb82010-11-05 15:02:16 -0700613 finishedCallback.finished(handled);
Christopher Tatea53146c2010-09-07 11:57:52 -0700614 }
615 }
616 };
617
618 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800619 * Whether the UI is currently running in touch mode (not showing
620 * navigational focus because the user is directly pressing the screen).
621 */
Michael Jurkae99adc72011-08-11 18:28:01 -0700622 boolean mInTouchMode = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800623
624 private ViewServer mViewServer;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700625 private ArrayList<WindowChangeListener> mWindowChangeListeners =
626 new ArrayList<WindowChangeListener>();
627 private boolean mWindowsChanged = false;
628
629 public interface WindowChangeListener {
630 public void windowsChanged();
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -0700631 public void focusChanged();
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700632 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800633
Dianne Hackbornc485a602009-03-24 22:39:49 -0700634 final Configuration mTempConfiguration = new Configuration();
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700635
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700636 // The desired scaling factor for compatible apps.
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400637 float mCompatibleScreenScale;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700638
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800639 public static WindowManagerService main(Context context,
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700640 PowerManagerService pm, boolean haveInputMethods, boolean allowBootMsgs) {
641 WMThread thr = new WMThread(context, pm, haveInputMethods, allowBootMsgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800642 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700643
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800644 synchronized (thr) {
645 while (thr.mService == null) {
646 try {
647 thr.wait();
648 } catch (InterruptedException e) {
649 }
650 }
Jozef BABJAK06e57b52011-01-20 08:09:25 +0100651 return thr.mService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800652 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800653 }
Romain Guy06882f82009-06-10 13:36:04 -0700654
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800655 static class WMThread extends Thread {
656 WindowManagerService mService;
Romain Guy06882f82009-06-10 13:36:04 -0700657
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800658 private final Context mContext;
659 private final PowerManagerService mPM;
660 private final boolean mHaveInputMethods;
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700661 private final boolean mAllowBootMessages;
Romain Guy06882f82009-06-10 13:36:04 -0700662
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800663 public WMThread(Context context, PowerManagerService pm,
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700664 boolean haveInputMethods, boolean allowBootMsgs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665 super("WindowManager");
666 mContext = context;
667 mPM = pm;
668 mHaveInputMethods = haveInputMethods;
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700669 mAllowBootMessages = allowBootMsgs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800670 }
Romain Guy06882f82009-06-10 13:36:04 -0700671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800672 public void run() {
673 Looper.prepare();
674 WindowManagerService s = new WindowManagerService(mContext, mPM,
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700675 mHaveInputMethods, mAllowBootMessages);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800676 android.os.Process.setThreadPriority(
677 android.os.Process.THREAD_PRIORITY_DISPLAY);
Christopher Tate160edb32010-06-30 17:46:30 -0700678 android.os.Process.setCanSelfBackground(false);
Romain Guy06882f82009-06-10 13:36:04 -0700679
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800680 synchronized (this) {
681 mService = s;
682 notifyAll();
683 }
Romain Guy06882f82009-06-10 13:36:04 -0700684
Brad Fitzpatrickec062f62010-11-03 09:56:54 -0700685 // For debug builds, log event loop stalls to dropbox for analysis.
686 if (StrictMode.conditionallyEnableDebugLogging()) {
687 Slog.i(TAG, "Enabled StrictMode logging for WMThread's Looper");
688 }
689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800690 Looper.loop();
691 }
692 }
693
694 static class PolicyThread extends Thread {
695 private final WindowManagerPolicy mPolicy;
696 private final WindowManagerService mService;
697 private final Context mContext;
698 private final PowerManagerService mPM;
699 boolean mRunning = false;
Romain Guy06882f82009-06-10 13:36:04 -0700700
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800701 public PolicyThread(WindowManagerPolicy policy,
702 WindowManagerService service, Context context,
703 PowerManagerService pm) {
704 super("WindowManagerPolicy");
705 mPolicy = policy;
706 mService = service;
707 mContext = context;
708 mPM = pm;
709 }
Romain Guy06882f82009-06-10 13:36:04 -0700710
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800711 public void run() {
712 Looper.prepare();
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800713 WindowManagerPolicyThread.set(this, Looper.myLooper());
714
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800715 //Looper.myLooper().setMessageLogging(new LogPrinter(
Joe Onorato8a9b2202010-02-26 18:56:32 -0800716 // Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800717 android.os.Process.setThreadPriority(
718 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -0700719 android.os.Process.setCanSelfBackground(false);
Dianne Hackborndf89e652011-10-06 22:35:11 -0700720 mPolicy.init(mContext, mService, mService, mPM);
Romain Guy06882f82009-06-10 13:36:04 -0700721
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800722 synchronized (this) {
723 mRunning = true;
724 notifyAll();
725 }
Romain Guy06882f82009-06-10 13:36:04 -0700726
Brad Fitzpatrickec062f62010-11-03 09:56:54 -0700727 // For debug builds, log event loop stalls to dropbox for analysis.
728 if (StrictMode.conditionallyEnableDebugLogging()) {
729 Slog.i(TAG, "Enabled StrictMode for PolicyThread's Looper");
730 }
731
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800732 Looper.loop();
733 }
734 }
735
736 private WindowManagerService(Context context, PowerManagerService pm,
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700737 boolean haveInputMethods, boolean showBootMsgs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800738 mContext = context;
739 mHaveInputMethods = haveInputMethods;
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700740 mAllowBootMessages = showBootMsgs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800741 mLimitedAlphaCompositing = context.getResources().getBoolean(
742 com.android.internal.R.bool.config_sf_limitedAlpha);
Romain Guy06882f82009-06-10 13:36:04 -0700743
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800744 mPowerManager = pm;
745 mPowerManager.setPolicy(mPolicy);
746 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
747 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
748 "SCREEN_FROZEN");
749 mScreenFrozenLock.setReferenceCounted(false);
750
751 mActivityManager = ActivityManagerNative.getDefault();
752 mBatteryStats = BatteryStatsService.getService();
753
754 // Get persisted window scale setting
755 mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
756 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
757 mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
758 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Romain Guy06882f82009-06-10 13:36:04 -0700759
Jim Miller284b62e2010-06-08 14:27:42 -0700760 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
761 IntentFilter filter = new IntentFilter();
762 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
763 mContext.registerReceiver(mBroadcastReceiver, filter);
764
Jeff Brown46b9ac02010-04-22 18:58:52 -0700765 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
766 "KEEP_SCREEN_ON_FLAG");
767 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800768
Jeff Browne33348b2010-07-15 23:54:05 -0700769 mInputManager = new InputManager(context, this);
Romain Guy06882f82009-06-10 13:36:04 -0700770
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800771 PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
772 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700773
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800774 synchronized (thr) {
775 while (!thr.mRunning) {
776 try {
777 thr.wait();
778 } catch (InterruptedException e) {
779 }
780 }
781 }
Romain Guy06882f82009-06-10 13:36:04 -0700782
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700783 mInputManager.start();
Romain Guy06882f82009-06-10 13:36:04 -0700784
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800785 // Add ourself to the Watchdog monitors.
786 Watchdog.getInstance().addMonitor(this);
787 }
788
789 @Override
790 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
791 throws RemoteException {
792 try {
793 return super.onTransact(code, data, reply, flags);
794 } catch (RuntimeException e) {
795 // The window manager only throws security exceptions, so let's
796 // log all others.
797 if (!(e instanceof SecurityException)) {
Dianne Hackborn89620282011-09-11 12:47:45 -0700798 Log.wtf(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800799 }
800 throw e;
801 }
802 }
803
Jeff Browne33348b2010-07-15 23:54:05 -0700804 private void placeWindowAfter(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800805 final int i = mWindows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800806 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800807 TAG, "Adding window " + window + " at "
808 + (i+1) + " of " + mWindows.size() + " (after " + pos + ")");
809 mWindows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700810 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800811 }
812
Jeff Browne33348b2010-07-15 23:54:05 -0700813 private void placeWindowBefore(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800814 final int i = mWindows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800815 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800816 TAG, "Adding window " + window + " at "
817 + i + " of " + mWindows.size() + " (before " + pos + ")");
818 mWindows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700819 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800820 }
821
822 //This method finds out the index of a window that has the same app token as
823 //win. used for z ordering the windows in mWindows
824 private int findIdxBasedOnAppTokens(WindowState win) {
825 //use a local variable to cache mWindows
Jeff Browne33348b2010-07-15 23:54:05 -0700826 ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800827 int jmax = localmWindows.size();
828 if(jmax == 0) {
829 return -1;
830 }
831 for(int j = (jmax-1); j >= 0; j--) {
Jeff Browne33348b2010-07-15 23:54:05 -0700832 WindowState wentry = localmWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800833 if(wentry.mAppToken == win.mAppToken) {
834 return j;
835 }
836 }
837 return -1;
838 }
Romain Guy06882f82009-06-10 13:36:04 -0700839
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800840 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
841 final IWindow client = win.mClient;
842 final WindowToken token = win.mToken;
Jeff Browne33348b2010-07-15 23:54:05 -0700843 final ArrayList<WindowState> localmWindows = mWindows;
Romain Guy06882f82009-06-10 13:36:04 -0700844
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800845 final int N = localmWindows.size();
846 final WindowState attached = win.mAttachedWindow;
847 int i;
848 if (attached == null) {
849 int tokenWindowsPos = token.windows.size();
850 if (token.appWindowToken != null) {
851 int index = tokenWindowsPos-1;
852 if (index >= 0) {
853 // If this application has existing windows, we
854 // simply place the new window on top of them... but
855 // keep the starting window on top.
856 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
857 // Base windows go behind everything else.
858 placeWindowBefore(token.windows.get(0), win);
859 tokenWindowsPos = 0;
860 } else {
861 AppWindowToken atoken = win.mAppToken;
862 if (atoken != null &&
863 token.windows.get(index) == atoken.startingWindow) {
864 placeWindowBefore(token.windows.get(index), win);
865 tokenWindowsPos--;
866 } else {
867 int newIdx = findIdxBasedOnAppTokens(win);
868 if(newIdx != -1) {
Romain Guy06882f82009-06-10 13:36:04 -0700869 //there is a window above this one associated with the same
870 //apptoken note that the window could be a floating window
871 //that was created later or a window at the top of the list of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800872 //windows associated with this token.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800873 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
874 Slog.v(TAG, "Adding window " + win + " at "
875 + (newIdx+1) + " of " + N);
876 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800877 localmWindows.add(newIdx+1, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700878 mWindowsChanged = true;
Romain Guy06882f82009-06-10 13:36:04 -0700879 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800880 }
881 }
882 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800883 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800884 TAG, "Figuring out where to add app window "
885 + client.asBinder() + " (token=" + token + ")");
886 // Figure out where the window should go, based on the
887 // order of applications.
888 final int NA = mAppTokens.size();
Jeff Browne33348b2010-07-15 23:54:05 -0700889 WindowState pos = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800890 for (i=NA-1; i>=0; i--) {
891 AppWindowToken t = mAppTokens.get(i);
892 if (t == token) {
893 i--;
894 break;
895 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800896
Dianne Hackborna8f60182009-09-01 19:01:50 -0700897 // We haven't reached the token yet; if this token
898 // is not going to the bottom and has windows, we can
899 // use it as an anchor for when we do reach the token.
900 if (!t.sendingToBottom && t.windows.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800901 pos = t.windows.get(0);
902 }
903 }
904 // We now know the index into the apps. If we found
905 // an app window above, that gives us the position; else
906 // we need to look some more.
907 if (pos != null) {
908 // Move behind any windows attached to this one.
Jeff Browne33348b2010-07-15 23:54:05 -0700909 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800910 if (atoken != null) {
911 final int NC = atoken.windows.size();
912 if (NC > 0) {
913 WindowState bottom = atoken.windows.get(0);
914 if (bottom.mSubLayer < 0) {
915 pos = bottom;
916 }
917 }
918 }
919 placeWindowBefore(pos, win);
920 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -0700921 // Continue looking down until we find the first
922 // token that has windows.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800923 while (i >= 0) {
924 AppWindowToken t = mAppTokens.get(i);
925 final int NW = t.windows.size();
926 if (NW > 0) {
927 pos = t.windows.get(NW-1);
928 break;
929 }
930 i--;
931 }
932 if (pos != null) {
933 // Move in front of any windows attached to this
934 // one.
Jeff Browne33348b2010-07-15 23:54:05 -0700935 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800936 if (atoken != null) {
937 final int NC = atoken.windows.size();
938 if (NC > 0) {
939 WindowState top = atoken.windows.get(NC-1);
940 if (top.mSubLayer >= 0) {
941 pos = top;
942 }
943 }
944 }
945 placeWindowAfter(pos, win);
946 } else {
947 // Just search for the start of this layer.
948 final int myLayer = win.mBaseLayer;
949 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -0700950 WindowState w = localmWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800951 if (w.mBaseLayer > myLayer) {
952 break;
953 }
954 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800955 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
956 Slog.v(TAG, "Adding window " + win + " at "
957 + i + " of " + N);
958 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700960 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800961 }
962 }
963 }
964 } else {
965 // Figure out where window should go, based on layer.
966 final int myLayer = win.mBaseLayer;
967 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -0700968 if (localmWindows.get(i).mBaseLayer <= myLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969 i++;
970 break;
971 }
972 }
973 if (i < 0) i = 0;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800974 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700975 TAG, "Adding window " + win + " at "
976 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800977 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700978 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800979 }
980 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800981 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800982 token.windows.add(tokenWindowsPos, win);
983 }
984
985 } else {
986 // Figure out this window's ordering relative to the window
987 // it is attached to.
988 final int NA = token.windows.size();
989 final int sublayer = win.mSubLayer;
990 int largestSublayer = Integer.MIN_VALUE;
991 WindowState windowWithLargestSublayer = null;
992 for (i=0; i<NA; i++) {
993 WindowState w = token.windows.get(i);
994 final int wSublayer = w.mSubLayer;
995 if (wSublayer >= largestSublayer) {
996 largestSublayer = wSublayer;
997 windowWithLargestSublayer = w;
998 }
999 if (sublayer < 0) {
1000 // For negative sublayers, we go below all windows
1001 // in the same sublayer.
1002 if (wSublayer >= sublayer) {
1003 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001004 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001005 token.windows.add(i, win);
1006 }
1007 placeWindowBefore(
1008 wSublayer >= 0 ? attached : w, win);
1009 break;
1010 }
1011 } else {
1012 // For positive sublayers, we go above all windows
1013 // in the same sublayer.
1014 if (wSublayer > sublayer) {
1015 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001016 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001017 token.windows.add(i, win);
1018 }
1019 placeWindowBefore(w, win);
1020 break;
1021 }
1022 }
1023 }
1024 if (i >= NA) {
1025 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001026 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001027 token.windows.add(win);
1028 }
1029 if (sublayer < 0) {
1030 placeWindowBefore(attached, win);
1031 } else {
1032 placeWindowAfter(largestSublayer >= 0
1033 ? windowWithLargestSublayer
1034 : attached,
1035 win);
1036 }
1037 }
1038 }
Romain Guy06882f82009-06-10 13:36:04 -07001039
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001040 if (win.mAppToken != null && addToToken) {
1041 win.mAppToken.allAppWindows.add(win);
1042 }
1043 }
Romain Guy06882f82009-06-10 13:36:04 -07001044
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001045 static boolean canBeImeTarget(WindowState w) {
1046 final int fl = w.mAttrs.flags
1047 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
Dianne Hackborne75d8722011-01-27 19:37:40 -08001048 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)
1049 || w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
1050 if (DEBUG_INPUT_METHOD) {
1051 Slog.i(TAG, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
1052 if (!w.isVisibleOrAdding()) {
1053 Slog.i(TAG, " mSurface=" + w.mSurface + " reportDestroy=" + w.mReportDestroySurface
1054 + " relayoutCalled=" + w.mRelayoutCalled + " viewVis=" + w.mViewVisibility
1055 + " policyVis=" + w.mPolicyVisibility + " attachHid=" + w.mAttachedHidden
1056 + " exiting=" + w.mExiting + " destroying=" + w.mDestroying);
1057 if (w.mAppToken != null) {
1058 Slog.i(TAG, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
1059 }
1060 }
1061 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001062 return w.isVisibleOrAdding();
1063 }
1064 return false;
1065 }
Romain Guy06882f82009-06-10 13:36:04 -07001066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001067 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
Jeff Browne33348b2010-07-15 23:54:05 -07001068 final ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001069 final int N = localmWindows.size();
1070 WindowState w = null;
1071 int i = N;
1072 while (i > 0) {
1073 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001074 w = localmWindows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -07001075
Dianne Hackborne75d8722011-01-27 19:37:40 -08001076 if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG, "Checking window @" + i
1077 + " " + w + " fl=0x" + Integer.toHexString(w.mAttrs.flags));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001078 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001079 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -07001080
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001081 // Yet more tricksyness! If this window is a "starting"
1082 // window, we do actually want to be on top of it, but
1083 // it is not -really- where input will go. So if the caller
1084 // is not actually looking to move the IME, look down below
1085 // for a real window to target...
1086 if (!willMove
1087 && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
1088 && i > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001089 WindowState wb = localmWindows.get(i-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001090 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1091 i--;
1092 w = wb;
1093 }
1094 }
1095 break;
1096 }
1097 }
Romain Guy06882f82009-06-10 13:36:04 -07001098
Dianne Hackborne75d8722011-01-27 19:37:40 -08001099 if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG, "Proposed new IME target: " + w);
1100
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001101 // Now, a special case -- if the last target's window is in the
1102 // process of exiting, and is above the new target, keep on the
1103 // last target to avoid flicker. Consider for example a Dialog with
1104 // the IME shown: when the Dialog is dismissed, we want to keep
1105 // the IME above it until it is completely gone so it doesn't drop
1106 // behind the dialog or its full-screen scrim.
1107 if (mInputMethodTarget != null && w != null
1108 && mInputMethodTarget.isDisplayedLw()
1109 && mInputMethodTarget.mExiting) {
1110 if (mInputMethodTarget.mAnimLayer > w.mAnimLayer) {
1111 w = mInputMethodTarget;
1112 i = localmWindows.indexOf(w);
Dianne Hackborne75d8722011-01-27 19:37:40 -08001113 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Current target higher, switching to: " + w);
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001114 }
1115 }
Romain Guy06882f82009-06-10 13:36:04 -07001116
Joe Onorato8a9b2202010-02-26 18:56:32 -08001117 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001118 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -07001119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001120 if (willMove && w != null) {
1121 final WindowState curTarget = mInputMethodTarget;
1122 if (curTarget != null && curTarget.mAppToken != null) {
Romain Guy06882f82009-06-10 13:36:04 -07001123
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001124 // Now some fun for dealing with window animations that
1125 // modify the Z order. We need to look at all windows below
1126 // the current target that are in this app, finding the highest
1127 // visible one in layering.
1128 AppWindowToken token = curTarget.mAppToken;
1129 WindowState highestTarget = null;
1130 int highestPos = 0;
1131 if (token.animating || token.animation != null) {
1132 int pos = 0;
1133 pos = localmWindows.indexOf(curTarget);
1134 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001135 WindowState win = localmWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001136 if (win.mAppToken != token) {
1137 break;
1138 }
1139 if (!win.mRemoved) {
1140 if (highestTarget == null || win.mAnimLayer >
1141 highestTarget.mAnimLayer) {
1142 highestTarget = win;
1143 highestPos = pos;
1144 }
1145 }
1146 pos--;
1147 }
1148 }
Romain Guy06882f82009-06-10 13:36:04 -07001149
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001150 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001151 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001152 + mNextAppTransition + " " + highestTarget
1153 + " animating=" + highestTarget.isAnimating()
1154 + " layer=" + highestTarget.mAnimLayer
1155 + " new layer=" + w.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001156
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001157 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001158 // If we are currently setting up for an animation,
1159 // hold everything until we can find out what will happen.
1160 mInputMethodTargetWaitingAnim = true;
1161 mInputMethodTarget = highestTarget;
1162 return highestPos + 1;
1163 } else if (highestTarget.isAnimating() &&
1164 highestTarget.mAnimLayer > w.mAnimLayer) {
1165 // If the window we are currently targeting is involved
1166 // with an animation, and it is on top of the next target
1167 // we will be over, then hold off on moving until
1168 // that is done.
Dianne Hackborne75d8722011-01-27 19:37:40 -08001169 mInputMethodTargetWaitingAnim = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001170 mInputMethodTarget = highestTarget;
1171 return highestPos + 1;
1172 }
1173 }
1174 }
1175 }
Romain Guy06882f82009-06-10 13:36:04 -07001176
Joe Onorato8a9b2202010-02-26 18:56:32 -08001177 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001178 if (w != null) {
1179 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001180 if (DEBUG_INPUT_METHOD) {
1181 RuntimeException e = null;
1182 if (!HIDE_STACK_CRAWLS) {
1183 e = new RuntimeException();
1184 e.fillInStackTrace();
1185 }
1186 Slog.w(TAG, "Moving IM target from "
1187 + mInputMethodTarget + " to " + w, e);
1188 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001189 mInputMethodTarget = w;
Dianne Hackborne75d8722011-01-27 19:37:40 -08001190 mInputMethodTargetWaitingAnim = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001191 if (w.mAppToken != null) {
1192 setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment);
1193 } else {
1194 setInputMethodAnimLayerAdjustment(0);
1195 }
1196 }
1197 return i+1;
1198 }
1199 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001200 if (DEBUG_INPUT_METHOD) {
1201 RuntimeException e = null;
1202 if (!HIDE_STACK_CRAWLS) {
1203 e = new RuntimeException();
1204 e.fillInStackTrace();
1205 }
1206 Slog.w(TAG, "Moving IM target from "
1207 + mInputMethodTarget + " to null", e);
1208 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001209 mInputMethodTarget = null;
1210 setInputMethodAnimLayerAdjustment(0);
1211 }
1212 return -1;
1213 }
Romain Guy06882f82009-06-10 13:36:04 -07001214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001215 void addInputMethodWindowToListLocked(WindowState win) {
1216 int pos = findDesiredInputMethodWindowIndexLocked(true);
1217 if (pos >= 0) {
1218 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001219 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001220 TAG, "Adding input method window " + win + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001221 mWindows.add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001222 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001223 moveInputMethodDialogsLocked(pos+1);
1224 return;
1225 }
1226 win.mTargetAppToken = null;
1227 addWindowToListInOrderLocked(win, true);
1228 moveInputMethodDialogsLocked(pos);
1229 }
Romain Guy06882f82009-06-10 13:36:04 -07001230
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001231 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001232 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001233 mInputMethodAnimLayerAdjustment = adj;
1234 WindowState imw = mInputMethodWindow;
1235 if (imw != null) {
1236 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001237 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001238 + " anim layer: " + imw.mAnimLayer);
1239 int wi = imw.mChildWindows.size();
1240 while (wi > 0) {
1241 wi--;
Jeff Browne33348b2010-07-15 23:54:05 -07001242 WindowState cw = imw.mChildWindows.get(wi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001243 cw.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001244 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001245 + " anim layer: " + cw.mAnimLayer);
1246 }
1247 }
1248 int di = mInputMethodDialogs.size();
1249 while (di > 0) {
1250 di --;
1251 imw = mInputMethodDialogs.get(di);
1252 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001253 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001254 + " anim layer: " + imw.mAnimLayer);
1255 }
1256 }
Romain Guy06882f82009-06-10 13:36:04 -07001257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001258 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
1259 int wpos = mWindows.indexOf(win);
1260 if (wpos >= 0) {
1261 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001262 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001263 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001264 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001265 int NC = win.mChildWindows.size();
1266 while (NC > 0) {
1267 NC--;
Jeff Browne33348b2010-07-15 23:54:05 -07001268 WindowState cw = win.mChildWindows.get(NC);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001269 int cpos = mWindows.indexOf(cw);
1270 if (cpos >= 0) {
1271 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001272 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001273 + cpos + ": " + cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001274 mWindows.remove(cpos);
1275 }
1276 }
1277 }
1278 return interestingPos;
1279 }
Romain Guy06882f82009-06-10 13:36:04 -07001280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001281 private void reAddWindowToListInOrderLocked(WindowState win) {
1282 addWindowToListInOrderLocked(win, false);
1283 // This is a hack to get all of the child windows added as well
1284 // at the right position. Child windows should be rare and
1285 // this case should be rare, so it shouldn't be that big a deal.
1286 int wpos = mWindows.indexOf(win);
1287 if (wpos >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001288 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001289 + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001290 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001291 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001292 reAddWindowLocked(wpos, win);
1293 }
1294 }
Romain Guy06882f82009-06-10 13:36:04 -07001295
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001296 void logWindowList(String prefix) {
1297 int N = mWindows.size();
1298 while (N > 0) {
1299 N--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001300 Slog.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001301 }
1302 }
Romain Guy06882f82009-06-10 13:36:04 -07001303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001304 void moveInputMethodDialogsLocked(int pos) {
1305 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001307 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001308 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001309 for (int i=0; i<N; i++) {
1310 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1311 }
1312 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001313 Slog.v(TAG, "Window list w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314 logWindowList(" ");
1315 }
Romain Guy06882f82009-06-10 13:36:04 -07001316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001317 if (pos >= 0) {
1318 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
1319 if (pos < mWindows.size()) {
Jeff Browne33348b2010-07-15 23:54:05 -07001320 WindowState wp = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001321 if (wp == mInputMethodWindow) {
1322 pos++;
1323 }
1324 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001325 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001326 for (int i=0; i<N; i++) {
1327 WindowState win = dialogs.get(i);
1328 win.mTargetAppToken = targetAppToken;
1329 pos = reAddWindowLocked(pos, win);
1330 }
1331 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001332 Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001333 logWindowList(" ");
1334 }
1335 return;
1336 }
1337 for (int i=0; i<N; i++) {
1338 WindowState win = dialogs.get(i);
1339 win.mTargetAppToken = null;
1340 reAddWindowToListInOrderLocked(win);
1341 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001342 Slog.v(TAG, "No IM target, final list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001343 logWindowList(" ");
1344 }
1345 }
1346 }
Romain Guy06882f82009-06-10 13:36:04 -07001347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001348 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1349 final WindowState imWin = mInputMethodWindow;
1350 final int DN = mInputMethodDialogs.size();
1351 if (imWin == null && DN == 0) {
1352 return false;
1353 }
Romain Guy06882f82009-06-10 13:36:04 -07001354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001355 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1356 if (imPos >= 0) {
1357 // In this case, the input method windows are to be placed
1358 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001359
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001360 // First check to see if the input method windows are already
1361 // located here, and contiguous.
1362 final int N = mWindows.size();
1363 WindowState firstImWin = imPos < N
Jeff Browne33348b2010-07-15 23:54:05 -07001364 ? mWindows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001365
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001366 // Figure out the actual input method window that should be
1367 // at the bottom of their stack.
1368 WindowState baseImWin = imWin != null
1369 ? imWin : mInputMethodDialogs.get(0);
1370 if (baseImWin.mChildWindows.size() > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001371 WindowState cw = baseImWin.mChildWindows.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001372 if (cw.mSubLayer < 0) baseImWin = cw;
1373 }
Romain Guy06882f82009-06-10 13:36:04 -07001374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001375 if (firstImWin == baseImWin) {
1376 // The windows haven't moved... but are they still contiguous?
1377 // First find the top IM window.
1378 int pos = imPos+1;
1379 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001380 if (!(mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001381 break;
1382 }
1383 pos++;
1384 }
1385 pos++;
1386 // Now there should be no more input method windows above.
1387 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001388 if ((mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001389 break;
1390 }
1391 pos++;
1392 }
1393 if (pos >= N) {
1394 // All is good!
1395 return false;
1396 }
1397 }
Romain Guy06882f82009-06-10 13:36:04 -07001398
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001399 if (imWin != null) {
1400 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001401 Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001402 logWindowList(" ");
1403 }
1404 imPos = tmpRemoveWindowLocked(imPos, imWin);
1405 if (DEBUG_INPUT_METHOD) {
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001406 Slog.v(TAG, "List after removing with new pos " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001407 logWindowList(" ");
1408 }
1409 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1410 reAddWindowLocked(imPos, imWin);
1411 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001412 Slog.v(TAG, "List after moving IM to " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001413 logWindowList(" ");
1414 }
1415 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1416 } else {
1417 moveInputMethodDialogsLocked(imPos);
1418 }
Romain Guy06882f82009-06-10 13:36:04 -07001419
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001420 } else {
1421 // In this case, the input method windows go in a fixed layer,
1422 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001423
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001424 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001425 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001426 tmpRemoveWindowLocked(0, imWin);
1427 imWin.mTargetAppToken = null;
1428 reAddWindowToListInOrderLocked(imWin);
1429 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001430 Slog.v(TAG, "List with no IM target:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001431 logWindowList(" ");
1432 }
1433 if (DN > 0) moveInputMethodDialogsLocked(-1);;
1434 } else {
1435 moveInputMethodDialogsLocked(-1);;
1436 }
Romain Guy06882f82009-06-10 13:36:04 -07001437
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001438 }
Romain Guy06882f82009-06-10 13:36:04 -07001439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001440 if (needAssignLayers) {
1441 assignLayersLocked();
1442 }
Romain Guy06882f82009-06-10 13:36:04 -07001443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001444 return true;
1445 }
Romain Guy06882f82009-06-10 13:36:04 -07001446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001447 void adjustInputMethodDialogsLocked() {
1448 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1449 }
Romain Guy06882f82009-06-10 13:36:04 -07001450
Dianne Hackborn25994b42009-09-04 14:21:19 -07001451 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001452 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001453 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1454 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
1455 ? wallpaperTarget.mAppToken.animation : null)
1456 + " upper=" + mUpperWallpaperTarget
1457 + " lower=" + mLowerWallpaperTarget);
1458 return (wallpaperTarget != null
1459 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
1460 && wallpaperTarget.mAppToken.animation != null)))
1461 || mUpperWallpaperTarget != null
1462 || mLowerWallpaperTarget != null;
1463 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001464
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001465 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1466 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001467
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001468 int adjustWallpaperWindowsLocked() {
1469 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001470
Dianne Hackborn81e56d52011-05-26 00:55:58 -07001471 final int dw = mAppDisplayWidth;
1472 final int dh = mAppDisplayHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001473
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001474 // First find top-most window that has asked to be on top of the
1475 // wallpaper; all wallpapers go behind it.
Jeff Browne33348b2010-07-15 23:54:05 -07001476 final ArrayList<WindowState> localmWindows = mWindows;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001477 int N = localmWindows.size();
1478 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001479 WindowState foundW = null;
1480 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001481 WindowState topCurW = null;
1482 int topCurI = 0;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001483 int windowDetachedI = -1;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001484 int i = N;
1485 while (i > 0) {
1486 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001487 w = localmWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001488 if ((w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER)) {
1489 if (topCurW == null) {
1490 topCurW = w;
1491 topCurI = i;
1492 }
1493 continue;
1494 }
1495 topCurW = null;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001496 if (w != mWindowDetachedWallpaper && w.mAppToken != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001497 // If this window's app token is hidden and not animating,
1498 // it is of no interest to us.
1499 if (w.mAppToken.hidden && w.mAppToken.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001500 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001501 "Skipping not hidden or animating token: " + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001502 continue;
1503 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001504 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001505 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": readyfordisplay="
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001506 + w.isReadyForDisplay() + " drawpending=" + w.mDrawPending
1507 + " commitdrawpending=" + w.mCommitDrawPending);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001508 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07001509 && (mWallpaperTarget == w
1510 || (!w.mDrawPending && !w.mCommitDrawPending))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001511 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001512 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001513 foundW = w;
1514 foundI = i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001515 if (w == mWallpaperTarget && ((w.mAppToken != null
1516 && w.mAppToken.animation != null)
1517 || w.mAnimation != null)) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001518 // The current wallpaper target is animating, so we'll
1519 // look behind it for another possible target and figure
1520 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001521 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001522 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001523 continue;
1524 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001525 break;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001526 } else if (w == mWindowDetachedWallpaper) {
1527 windowDetachedI = i;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001528 }
1529 }
1530
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001531 if (foundW == null && windowDetachedI >= 0) {
1532 if (DEBUG_WALLPAPER) Slog.v(TAG,
1533 "Found animating detached wallpaper activity: #" + i + "=" + w);
1534 foundW = w;
1535 foundI = windowDetachedI;
1536 }
1537
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001538 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001539 // If we are currently waiting for an app transition, and either
1540 // the current target or the next target are involved with it,
1541 // then hold off on doing anything with the wallpaper.
1542 // Note that we are checking here for just whether the target
1543 // is part of an app token... which is potentially overly aggressive
1544 // (the app token may not be involved in the transition), but good
1545 // enough (we'll just wait until whatever transition is pending
1546 // executes).
1547 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001548 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001549 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001550 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001551 }
1552 if (foundW != null && foundW.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001553 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001554 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001555 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001556 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001557 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001558
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001559 if (mWallpaperTarget != foundW) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001560 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001561 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001562 + " oldTarget: " + mWallpaperTarget);
1563 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001564
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001565 mLowerWallpaperTarget = null;
1566 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001567
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001568 WindowState oldW = mWallpaperTarget;
1569 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001570
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001571 // Now what is happening... if the current and new targets are
1572 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001573 if (foundW != null && oldW != null) {
1574 boolean oldAnim = oldW.mAnimation != null
1575 || (oldW.mAppToken != null && oldW.mAppToken.animation != null);
1576 boolean foundAnim = foundW.mAnimation != null
1577 || (foundW.mAppToken != null && foundW.mAppToken.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001578 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001579 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001580 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001581 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001582 if (foundAnim && oldAnim) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001583 int oldI = localmWindows.indexOf(oldW);
1584 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001585 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001586 }
1587 if (oldI >= 0) {
1588 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001589 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001590 + "=" + oldW + "; new#" + foundI
1591 + "=" + foundW);
1592 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001593
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001594 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001595 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001596 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001597 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001598 }
1599 mWallpaperTarget = oldW;
1600 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001601
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001602 // Now set the upper and lower wallpaper targets
1603 // correctly, and make sure that we are positioning
1604 // the wallpaper below the lower.
1605 if (foundI > oldI) {
1606 // The new target is on top of the old one.
1607 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001608 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001609 }
1610 mUpperWallpaperTarget = foundW;
1611 mLowerWallpaperTarget = oldW;
1612 foundW = oldW;
1613 foundI = oldI;
1614 } else {
1615 // The new target is below the old one.
1616 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001617 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001618 }
1619 mUpperWallpaperTarget = oldW;
1620 mLowerWallpaperTarget = foundW;
1621 }
1622 }
1623 }
1624 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001625
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001626 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001627 // Is it time to stop animating?
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001628 boolean lowerAnimating = mLowerWallpaperTarget.mAnimation != null
1629 || (mLowerWallpaperTarget.mAppToken != null
1630 && mLowerWallpaperTarget.mAppToken.animation != null);
1631 boolean upperAnimating = mUpperWallpaperTarget.mAnimation != null
1632 || (mUpperWallpaperTarget.mAppToken != null
1633 && mUpperWallpaperTarget.mAppToken.animation != null);
1634 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001635 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001636 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001637 }
1638 mLowerWallpaperTarget = null;
1639 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001640 }
1641 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001642
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001643 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001644 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001645 // The window is visible to the compositor... but is it visible
1646 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001647 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001648 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001649
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001650 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001651 // its layer adjustment. Only do this if we are not transfering
1652 // between two wallpaper targets.
1653 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001654 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001655 ? foundW.mAppToken.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001656
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001657 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1658 * TYPE_LAYER_MULTIPLIER
1659 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001660
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001661 // Now w is the window we are supposed to be behind... but we
1662 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001663 // AND any starting window associated with it, AND below the
1664 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001665 while (foundI > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001666 WindowState wb = localmWindows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001667 if (wb.mBaseLayer < maxLayer &&
1668 wb.mAttachedWindow != foundW &&
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001669 (foundW.mAttachedWindow == null ||
1670 wb.mAttachedWindow != foundW.mAttachedWindow) &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001671 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001672 foundW.mToken == null || wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001673 // This window is not related to the previous one in any
1674 // interesting way, so stop here.
1675 break;
1676 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001677 foundW = wb;
1678 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001679 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001680 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001681 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001682 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001683
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001684 if (foundW == null && topCurW != null) {
1685 // There is no wallpaper target, so it goes at the bottom.
1686 // We will assume it is the same place as last time, if known.
1687 foundW = topCurW;
1688 foundI = topCurI+1;
1689 } else {
1690 // Okay i is the position immediately above the wallpaper. Look at
1691 // what is below it for later.
Jeff Browne33348b2010-07-15 23:54:05 -07001692 foundW = foundI > 0 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001693 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001694
Dianne Hackborn284ac932009-08-28 10:34:25 -07001695 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001696 if (mWallpaperTarget.mWallpaperX >= 0) {
1697 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001698 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001699 }
1700 if (mWallpaperTarget.mWallpaperY >= 0) {
1701 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001702 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001703 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001704 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001705
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001706 // Start stepping backwards from here, ensuring that our wallpaper windows
1707 // are correctly placed.
1708 int curTokenIndex = mWallpaperTokens.size();
1709 while (curTokenIndex > 0) {
1710 curTokenIndex--;
1711 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001712 if (token.hidden == visible) {
1713 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1714 token.hidden = !visible;
1715 // Need to do a layout to ensure the wallpaper now has the
1716 // correct size.
1717 mLayoutNeeded = true;
1718 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001719
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001720 int curWallpaperIndex = token.windows.size();
1721 while (curWallpaperIndex > 0) {
1722 curWallpaperIndex--;
1723 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001724
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001725 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001726 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001727 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001728
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001729 // First, make sure the client has the current visibility
1730 // state.
1731 if (wallpaper.mWallpaperVisible != visible) {
1732 wallpaper.mWallpaperVisible = visible;
1733 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001734 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001735 "Setting visibility of wallpaper " + wallpaper
1736 + ": " + visible);
1737 wallpaper.mClient.dispatchAppVisibility(visible);
1738 } catch (RemoteException e) {
1739 }
1740 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001741
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001742 wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001743 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001744 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001745
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001746 // First, if this window is at the current index, then all
1747 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001748 if (wallpaper == foundW) {
1749 foundI--;
1750 foundW = foundI > 0
Jeff Browne33348b2010-07-15 23:54:05 -07001751 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001752 continue;
1753 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001754
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001755 // The window didn't match... the current wallpaper window,
1756 // wherever it is, is in the wrong place, so make sure it is
1757 // not in the list.
1758 int oldIndex = localmWindows.indexOf(wallpaper);
1759 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001760 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001761 + oldIndex + ": " + wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001762 localmWindows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001763 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001764 if (oldIndex < foundI) {
1765 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001766 }
1767 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001768
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001769 // Now stick it in.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001770 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
1771 Slog.v(TAG, "Moving wallpaper " + wallpaper
1772 + " from " + oldIndex + " to " + foundI);
1773 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001774
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001775 localmWindows.add(foundI, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001776 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001777 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001778 }
1779 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001780
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001781 return changed;
1782 }
1783
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001784 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001785 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001786 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001787 mWallpaperAnimLayerAdjustment = adj;
1788 int curTokenIndex = mWallpaperTokens.size();
1789 while (curTokenIndex > 0) {
1790 curTokenIndex--;
1791 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1792 int curWallpaperIndex = token.windows.size();
1793 while (curWallpaperIndex > 0) {
1794 curWallpaperIndex--;
1795 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1796 wallpaper.mAnimLayer = wallpaper.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001797 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001798 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001799 }
1800 }
1801 }
1802
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001803 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
1804 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001805 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001806 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001807 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001808 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackbornffb3d932011-05-17 17:44:51 -07001809 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001810 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
1811 changed = wallpaperWin.mXOffset != offset;
1812 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001813 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001814 + wallpaperWin + " x: " + offset);
1815 wallpaperWin.mXOffset = offset;
1816 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001817 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001818 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001819 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001820 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001821 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001822
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001823 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001824 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001825 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1826 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1827 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001828 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001829 + wallpaperWin + " y: " + offset);
1830 changed = true;
1831 wallpaperWin.mYOffset = offset;
1832 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001833 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001834 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001835 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001836 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001837 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001838
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001839 if (rawChanged) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001840 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001841 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001842 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
1843 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001844 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001845 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001846 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001847 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001848 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
1849 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001850 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001851 if (mWaitingOnWallpaper != null) {
1852 long start = SystemClock.uptimeMillis();
1853 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
1854 < start) {
1855 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001856 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07001857 "Waiting for offset complete...");
1858 mWindowMap.wait(WALLPAPER_TIMEOUT);
1859 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001860 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001861 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07001862 if ((start+WALLPAPER_TIMEOUT)
1863 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001864 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07001865 + wallpaperWin);
1866 mLastWallpaperTimeoutTime = start;
1867 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001868 }
Dianne Hackborn75804932009-10-20 20:15:20 -07001869 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001870 }
1871 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001872 } catch (RemoteException e) {
1873 }
1874 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001875
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001876 return changed;
1877 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001878
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001879 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001880 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001881 if (mWaitingOnWallpaper != null &&
1882 mWaitingOnWallpaper.mClient.asBinder() == window) {
1883 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07001884 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001885 }
1886 }
1887 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001888
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001889 boolean updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Dianne Hackborn81e56d52011-05-26 00:55:58 -07001890 final int dw = mAppDisplayWidth;
1891 final int dh = mAppDisplayHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001892
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001893 boolean changed = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001894
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001895 WindowState target = mWallpaperTarget;
1896 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001897 if (target.mWallpaperX >= 0) {
1898 mLastWallpaperX = target.mWallpaperX;
1899 } else if (changingTarget.mWallpaperX >= 0) {
1900 mLastWallpaperX = changingTarget.mWallpaperX;
1901 }
1902 if (target.mWallpaperY >= 0) {
1903 mLastWallpaperY = target.mWallpaperY;
1904 } else if (changingTarget.mWallpaperY >= 0) {
1905 mLastWallpaperY = changingTarget.mWallpaperY;
1906 }
1907 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001908
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001909 int curTokenIndex = mWallpaperTokens.size();
1910 while (curTokenIndex > 0) {
1911 curTokenIndex--;
1912 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1913 int curWallpaperIndex = token.windows.size();
1914 while (curWallpaperIndex > 0) {
1915 curWallpaperIndex--;
1916 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1917 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
1918 wallpaper.computeShownFrameLocked();
1919 changed = true;
1920 // We only want to be synchronous with one wallpaper.
1921 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001922 }
1923 }
1924 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001925
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001926 return changed;
1927 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001928
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001929 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07001930 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Dianne Hackborn81e56d52011-05-26 00:55:58 -07001931 final int dw = mAppDisplayWidth;
1932 final int dh = mAppDisplayHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001933
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001934 int curTokenIndex = mWallpaperTokens.size();
1935 while (curTokenIndex > 0) {
1936 curTokenIndex--;
1937 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001938 if (token.hidden == visible) {
1939 token.hidden = !visible;
1940 // Need to do a layout to ensure the wallpaper now has the
1941 // correct size.
1942 mLayoutNeeded = true;
1943 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001944
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001945 int curWallpaperIndex = token.windows.size();
1946 while (curWallpaperIndex > 0) {
1947 curWallpaperIndex--;
1948 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1949 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001950 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001951 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001952
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001953 if (wallpaper.mWallpaperVisible != visible) {
1954 wallpaper.mWallpaperVisible = visible;
1955 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001956 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07001957 "Updating visibility of wallpaper " + wallpaper
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001958 + ": " + visible);
1959 wallpaper.mClient.dispatchAppVisibility(visible);
1960 } catch (RemoteException e) {
1961 }
1962 }
1963 }
1964 }
1965 }
Dianne Hackborn90d2db32010-02-11 22:19:06 -08001966
Dianne Hackborn9a230e02011-10-06 11:51:27 -07001967 public int addWindow(Session session, IWindow client, int seq,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001968 WindowManager.LayoutParams attrs, int viewVisibility,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001969 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001970 int res = mPolicy.checkAddPermission(attrs);
1971 if (res != WindowManagerImpl.ADD_OKAY) {
1972 return res;
1973 }
Romain Guy06882f82009-06-10 13:36:04 -07001974
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001975 boolean reportNewConfig = false;
1976 WindowState attachedWindow = null;
1977 WindowState win = null;
Dianne Hackborn5132b372010-07-29 12:51:35 -07001978 long origId;
Romain Guy06882f82009-06-10 13:36:04 -07001979
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001980 synchronized(mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001981 if (mDisplay == null) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07001982 throw new IllegalStateException("Display has not been initialialized");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001983 }
Romain Guy06882f82009-06-10 13:36:04 -07001984
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001985 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001986 Slog.w(TAG, "Window " + client + " is already added");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001987 return WindowManagerImpl.ADD_DUPLICATE_ADD;
1988 }
1989
1990 if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001991 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001992 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001993 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001994 + attrs.token + ". Aborting.");
1995 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
1996 }
1997 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
1998 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001999 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002000 + attrs.token + ". Aborting.");
2001 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2002 }
2003 }
2004
2005 boolean addToken = false;
2006 WindowToken token = mTokenMap.get(attrs.token);
2007 if (token == null) {
2008 if (attrs.type >= FIRST_APPLICATION_WINDOW
2009 && attrs.type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002010 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002011 + attrs.token + ". Aborting.");
2012 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2013 }
2014 if (attrs.type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002015 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002016 + attrs.token + ". Aborting.");
2017 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2018 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002019 if (attrs.type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002020 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002021 + attrs.token + ". Aborting.");
2022 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2023 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002024 token = new WindowToken(this, attrs.token, -1, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002025 addToken = true;
2026 } else if (attrs.type >= FIRST_APPLICATION_WINDOW
2027 && attrs.type <= LAST_APPLICATION_WINDOW) {
2028 AppWindowToken atoken = token.appWindowToken;
2029 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002030 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002031 + token + ". Aborting.");
2032 return WindowManagerImpl.ADD_NOT_APP_TOKEN;
2033 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002034 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002035 + token + ". Aborting.");
2036 return WindowManagerImpl.ADD_APP_EXITING;
2037 }
2038 if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
2039 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002040 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002041 TAG, "**** NO NEED TO START: " + attrs.getTitle());
2042 return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
2043 }
2044 } else if (attrs.type == TYPE_INPUT_METHOD) {
2045 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002046 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002047 + attrs.token + ". Aborting.");
2048 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2049 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002050 } else if (attrs.type == TYPE_WALLPAPER) {
2051 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002052 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002053 + attrs.token + ". Aborting.");
2054 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2055 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002056 }
2057
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002058 win = new WindowState(this, session, client, token,
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002059 attachedWindow, seq, attrs, viewVisibility);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002060 if (win.mDeathRecipient == null) {
2061 // Client has apparently died, so there is no reason to
2062 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002063 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002064 + " that is dead, aborting.");
2065 return WindowManagerImpl.ADD_APP_EXITING;
2066 }
2067
2068 mPolicy.adjustWindowParamsLw(win.mAttrs);
Romain Guy06882f82009-06-10 13:36:04 -07002069
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002070 res = mPolicy.prepareAddWindowLw(win, attrs);
2071 if (res != WindowManagerImpl.ADD_OKAY) {
2072 return res;
2073 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002074
Jeff Browncc4f7db2011-08-30 20:34:48 -07002075 if (outInputChannel != null && (attrs.inputFeatures
2076 & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002077 String name = win.makeInputChannelName();
2078 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
Jeff Browncc4f7db2011-08-30 20:34:48 -07002079 win.setInputChannel(inputChannels[0]);
Jeff Brown0a0ab122011-08-12 18:08:08 -07002080 inputChannels[1].transferTo(outInputChannel);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002081
Jeff Brown928e0542011-01-10 11:17:36 -08002082 mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002083 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002084
2085 // From now on, no exceptions or errors allowed!
2086
2087 res = WindowManagerImpl.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002088
Dianne Hackborn5132b372010-07-29 12:51:35 -07002089 origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002091 if (addToken) {
2092 mTokenMap.put(attrs.token, token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002093 }
2094 win.attach();
2095 mWindowMap.put(client.asBinder(), win);
2096
2097 if (attrs.type == TYPE_APPLICATION_STARTING &&
2098 token.appWindowToken != null) {
2099 token.appWindowToken.startingWindow = win;
2100 }
2101
2102 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002103
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002104 if (attrs.type == TYPE_INPUT_METHOD) {
2105 mInputMethodWindow = win;
2106 addInputMethodWindowToListLocked(win);
2107 imMayMove = false;
2108 } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
2109 mInputMethodDialogs.add(win);
2110 addWindowToListInOrderLocked(win, true);
2111 adjustInputMethodDialogsLocked();
2112 imMayMove = false;
2113 } else {
2114 addWindowToListInOrderLocked(win, true);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002115 if (attrs.type == TYPE_WALLPAPER) {
2116 mLastWallpaperTimeoutTime = 0;
2117 adjustWallpaperWindowsLocked();
2118 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002119 adjustWallpaperWindowsLocked();
2120 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002121 }
Romain Guy06882f82009-06-10 13:36:04 -07002122
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002123 win.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002125 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
Romain Guy06882f82009-06-10 13:36:04 -07002126
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002127 if (mInTouchMode) {
2128 res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
2129 }
2130 if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
2131 res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
2132 }
Romain Guy06882f82009-06-10 13:36:04 -07002133
Jeff Brown2e44b072011-01-24 15:21:56 -08002134 mInputMonitor.setUpdateInputWindowsNeededLw();
2135
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002136 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002137 if (win.canReceiveKeys()) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002138 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
2139 false /*updateInputWindows*/);
Jeff Brown349703e2010-06-22 01:27:15 -07002140 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002141 imMayMove = false;
2142 }
2143 }
Romain Guy06882f82009-06-10 13:36:04 -07002144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002145 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002146 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002147 }
Romain Guy06882f82009-06-10 13:36:04 -07002148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002149 assignLayersLocked();
2150 // Don't do layout here, the window must call
2151 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002152
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002153 //dump();
2154
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002155 if (focusChanged) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002156 finishUpdateFocusedWindowAfterAssignLayersLocked(false /*updateInputWindows*/);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002157 }
Jeff Brown2e44b072011-01-24 15:21:56 -08002158 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08002159
Joe Onorato8a9b2202010-02-26 18:56:32 -08002160 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002161 TAG, "New client " + client.asBinder()
2162 + ": window=" + win);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002163
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002164 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002165 reportNewConfig = true;
2166 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002167 }
2168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002169 if (reportNewConfig) {
2170 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002171 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07002172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002173 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002175 return res;
2176 }
Romain Guy06882f82009-06-10 13:36:04 -07002177
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002178 public void removeWindow(Session session, IWindow client) {
2179 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002180 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002181 if (win == null) {
2182 return;
2183 }
2184 removeWindowLocked(session, win);
2185 }
2186 }
Romain Guy06882f82009-06-10 13:36:04 -07002187
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002188 public void removeWindowLocked(Session session, WindowState win) {
2189
Joe Onorato8a9b2202010-02-26 18:56:32 -08002190 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002191 TAG, "Remove " + win + " client="
2192 + Integer.toHexString(System.identityHashCode(
2193 win.mClient.asBinder()))
2194 + ", surface=" + win.mSurface);
2195
2196 final long origId = Binder.clearCallingIdentity();
Jeff Brownc5ed5912010-07-14 18:48:53 -07002197
2198 win.disposeInputChannel();
Romain Guy06882f82009-06-10 13:36:04 -07002199
Joe Onorato8a9b2202010-02-26 18:56:32 -08002200 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002201 TAG, "Remove " + win + ": mSurface=" + win.mSurface
2202 + " mExiting=" + win.mExiting
2203 + " isAnimating=" + win.isAnimating()
2204 + " app-animation="
2205 + (win.mAppToken != null ? win.mAppToken.animation : null)
2206 + " inPendingTransaction="
2207 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2208 + " mDisplayFrozen=" + mDisplayFrozen);
2209 // Visibility of the removed window. Will be used later to update orientation later on.
2210 boolean wasVisible = false;
2211 // First, see if we need to run an animation. If we do, we have
2212 // to hold off on removing the window until the animation is done.
2213 // If the display is frozen, just remove immediately, since the
2214 // animation wouldn't be seen.
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07002215 if (win.mSurface != null && !mDisplayFrozen && mDisplayEnabled
2216 && mPolicy.isScreenOnFully()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002217 // If we are not currently running the exit animation, we
2218 // need to see about starting one.
2219 if (wasVisible=win.isWinVisibleLw()) {
Romain Guy06882f82009-06-10 13:36:04 -07002220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002221 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2222 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2223 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2224 }
2225 // Try starting an animation.
2226 if (applyAnimationLocked(win, transit, false)) {
2227 win.mExiting = true;
2228 }
2229 }
2230 if (win.mExiting || win.isAnimating()) {
2231 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002232 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002233 win.mExiting = true;
2234 win.mRemoveOnExit = true;
2235 mLayoutNeeded = true;
Jeff Brown3a22cd92011-01-21 13:59:04 -08002236 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2237 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002238 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08002239 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002240 if (win.mAppToken != null) {
2241 win.mAppToken.updateReportedVisibilityLocked();
2242 }
2243 //dump();
2244 Binder.restoreCallingIdentity(origId);
2245 return;
2246 }
2247 }
2248
2249 removeWindowInnerLocked(session, win);
2250 // Removing a visible window will effect the computed orientation
2251 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002252 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002253 != mForcedAppOrientation
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002254 && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002255 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002256 }
Jeff Brown3a22cd92011-01-21 13:59:04 -08002257 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002258 Binder.restoreCallingIdentity(origId);
2259 }
Romain Guy06882f82009-06-10 13:36:04 -07002260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002261 private void removeWindowInnerLocked(Session session, WindowState win) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002262 if (win.mRemoved) {
2263 // Nothing to do.
2264 return;
2265 }
2266
2267 for (int i=win.mChildWindows.size()-1; i>=0; i--) {
2268 WindowState cwin = win.mChildWindows.get(i);
2269 Slog.w(TAG, "Force-removing child win " + cwin + " from container "
2270 + win);
2271 removeWindowInnerLocked(cwin.mSession, cwin);
2272 }
2273
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002274 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002276 if (mInputMethodTarget == win) {
2277 moveInputMethodWindowsIfNeededLocked(false);
2278 }
Romain Guy06882f82009-06-10 13:36:04 -07002279
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002280 if (false) {
2281 RuntimeException e = new RuntimeException("here");
2282 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002283 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002284 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002286 mPolicy.removeWindowLw(win);
2287 win.removeLocked();
2288
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002289 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002290 mWindowMap.remove(win.mClient.asBinder());
2291 mWindows.remove(win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002292 mPendingRemove.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002293 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002294 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002295
2296 if (mInputMethodWindow == win) {
2297 mInputMethodWindow = null;
2298 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2299 mInputMethodDialogs.remove(win);
2300 }
Romain Guy06882f82009-06-10 13:36:04 -07002301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002302 final WindowToken token = win.mToken;
2303 final AppWindowToken atoken = win.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002304 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + win + " from " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002305 token.windows.remove(win);
2306 if (atoken != null) {
2307 atoken.allAppWindows.remove(win);
2308 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002309 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002310 TAG, "**** Removing window " + win + ": count="
2311 + token.windows.size());
2312 if (token.windows.size() == 0) {
2313 if (!token.explicit) {
2314 mTokenMap.remove(token.token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002315 } else if (atoken != null) {
2316 atoken.firstWindowDrawn = false;
2317 }
2318 }
2319
2320 if (atoken != null) {
2321 if (atoken.startingWindow == win) {
2322 atoken.startingWindow = null;
2323 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2324 // If this is the last window and we had requested a starting
2325 // transition window, well there is no point now.
2326 atoken.startingData = null;
2327 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2328 // If this is the last window except for a starting transition
2329 // window, we need to get rid of the starting transition.
2330 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002331 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002332 + ": no more real windows");
2333 }
2334 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2335 mH.sendMessage(m);
2336 }
2337 }
Romain Guy06882f82009-06-10 13:36:04 -07002338
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002339 if (win.mAttrs.type == TYPE_WALLPAPER) {
2340 mLastWallpaperTimeoutTime = 0;
2341 adjustWallpaperWindowsLocked();
2342 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002343 adjustWallpaperWindowsLocked();
2344 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002345
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002346 if (!mInLayout) {
2347 assignLayersLocked();
2348 mLayoutNeeded = true;
2349 performLayoutAndPlaceSurfacesLocked();
2350 if (win.mAppToken != null) {
2351 win.mAppToken.updateReportedVisibilityLocked();
2352 }
2353 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07002354
Jeff Brown2e44b072011-01-24 15:21:56 -08002355 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002356 }
2357
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002358 static void logSurface(WindowState w, String msg, RuntimeException where) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002359 String str = " SURFACE " + Integer.toHexString(w.hashCode())
2360 + ": " + msg + " / " + w.mAttrs.getTitle();
2361 if (where != null) {
2362 Slog.i(TAG, str, where);
2363 } else {
2364 Slog.i(TAG, str);
2365 }
2366 }
2367
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002368 void setTransparentRegionWindow(Session session, IWindow client, Region region) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002369 long origId = Binder.clearCallingIdentity();
2370 try {
2371 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002372 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002373 if ((w != null) && (w.mSurface != null)) {
Dianne Hackborn36991742011-10-11 21:35:26 -07002374 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002375 ">>> OPEN TRANSACTION setTransparentRegion");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002376 Surface.openTransaction();
2377 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002378 if (SHOW_TRANSACTIONS) logSurface(w,
2379 "transparentRegionHint=" + region, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002380 w.mSurface.setTransparentRegionHint(region);
2381 } finally {
2382 Surface.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -07002383 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002384 "<<< CLOSE TRANSACTION setTransparentRegion");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002385 }
2386 }
2387 }
2388 } finally {
2389 Binder.restoreCallingIdentity(origId);
2390 }
2391 }
2392
2393 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002394 int touchableInsets, Rect contentInsets,
Jeff Brownfbf09772011-01-16 14:06:57 -08002395 Rect visibleInsets, Region touchableRegion) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002396 long origId = Binder.clearCallingIdentity();
2397 try {
2398 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002399 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002400 if (w != null) {
2401 w.mGivenInsetsPending = false;
2402 w.mGivenContentInsets.set(contentInsets);
2403 w.mGivenVisibleInsets.set(visibleInsets);
Jeff Brownfbf09772011-01-16 14:06:57 -08002404 w.mGivenTouchableRegion.set(touchableRegion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002405 w.mTouchableInsets = touchableInsets;
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002406 if (w.mGlobalScale != 1) {
2407 w.mGivenContentInsets.scale(w.mGlobalScale);
2408 w.mGivenVisibleInsets.scale(w.mGlobalScale);
2409 w.mGivenTouchableRegion.scale(w.mGlobalScale);
2410 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002411 mLayoutNeeded = true;
2412 performLayoutAndPlaceSurfacesLocked();
2413 }
2414 }
2415 } finally {
2416 Binder.restoreCallingIdentity(origId);
2417 }
2418 }
Romain Guy06882f82009-06-10 13:36:04 -07002419
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002420 public void getWindowDisplayFrame(Session session, IWindow client,
2421 Rect outDisplayFrame) {
2422 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002423 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002424 if (win == null) {
2425 outDisplayFrame.setEmpty();
2426 return;
2427 }
2428 outDisplayFrame.set(win.mDisplayFrame);
2429 }
2430 }
2431
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002432 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2433 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002434 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2435 window.mWallpaperX = x;
2436 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002437 window.mWallpaperXStep = xStep;
2438 window.mWallpaperYStep = yStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002439 if (updateWallpaperOffsetLocked(window, true)) {
2440 performLayoutAndPlaceSurfacesLocked();
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002441 }
2442 }
2443 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002444
Dianne Hackborn75804932009-10-20 20:15:20 -07002445 void wallpaperCommandComplete(IBinder window, Bundle result) {
2446 synchronized (mWindowMap) {
2447 if (mWaitingOnWallpaper != null &&
2448 mWaitingOnWallpaper.mClient.asBinder() == window) {
2449 mWaitingOnWallpaper = null;
2450 mWindowMap.notifyAll();
2451 }
2452 }
2453 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002454
Dianne Hackborn75804932009-10-20 20:15:20 -07002455 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2456 String action, int x, int y, int z, Bundle extras, boolean sync) {
2457 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2458 || window == mUpperWallpaperTarget) {
2459 boolean doWait = sync;
2460 int curTokenIndex = mWallpaperTokens.size();
2461 while (curTokenIndex > 0) {
2462 curTokenIndex--;
2463 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2464 int curWallpaperIndex = token.windows.size();
2465 while (curWallpaperIndex > 0) {
2466 curWallpaperIndex--;
2467 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2468 try {
2469 wallpaper.mClient.dispatchWallpaperCommand(action,
2470 x, y, z, extras, sync);
2471 // We only want to be synchronous with one wallpaper.
2472 sync = false;
2473 } catch (RemoteException e) {
2474 }
2475 }
2476 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002477
Dianne Hackborn75804932009-10-20 20:15:20 -07002478 if (doWait) {
2479 // XXX Need to wait for result.
2480 }
2481 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002482
Dianne Hackborn75804932009-10-20 20:15:20 -07002483 return null;
2484 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002485
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002486 public int relayoutWindow(Session session, IWindow client, int seq,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002487 WindowManager.LayoutParams attrs, int requestedWidth,
2488 int requestedHeight, int viewVisibility, boolean insetsPending,
2489 Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002490 Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002491 boolean displayed = false;
2492 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002493 boolean configChanged;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002494
2495 // if they don't have this permission, mask out the status bar bits
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002496 int systemUiVisibility = 0;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002497 if (attrs != null) {
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002498 systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
2499 if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -07002500 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
2501 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002502 systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
Dianne Hackborna44abeb2011-08-08 19:24:01 -07002503 }
Joe Onoratoac0ee892011-01-30 15:38:30 -08002504 }
2505 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002506 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002507
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002508 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002509 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002510 if (win == null) {
2511 return 0;
2512 }
2513 win.mRequestedWidth = requestedWidth;
2514 win.mRequestedHeight = requestedHeight;
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002515 if (attrs != null && seq == win.mSeq) {
2516 win.mSystemUiVisibility = systemUiVisibility;
2517 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002518
2519 if (attrs != null) {
2520 mPolicy.adjustWindowParamsLw(attrs);
2521 }
Romain Guy06882f82009-06-10 13:36:04 -07002522
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002523 int attrChanges = 0;
2524 int flagChanges = 0;
2525 if (attrs != null) {
Dianne Hackborn0e60db22011-09-01 11:17:57 -07002526 if (win.mAttrs.type != attrs.type) {
2527 throw new IllegalArgumentException(
2528 "Window type can not be changed after the window is added.");
2529 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002530 flagChanges = win.mAttrs.flags ^= attrs.flags;
2531 attrChanges = win.mAttrs.copyFrom(attrs);
2532 }
2533
Joe Onorato8a9b2202010-02-26 18:56:32 -08002534 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002535
Dianne Hackborn5fd21692011-06-07 14:09:47 -07002536 win.mEnforceSizeCompat = (win.mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0;
2537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002538 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
2539 win.mAlpha = attrs.alpha;
2540 }
2541
2542 final boolean scaledWindow =
2543 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2544
2545 if (scaledWindow) {
2546 // requested{Width|Height} Surface's physical size
2547 // attrs.{width|height} Size on screen
2548 win.mHScale = (attrs.width != requestedWidth) ?
2549 (attrs.width / (float)requestedWidth) : 1.0f;
2550 win.mVScale = (attrs.height != requestedHeight) ?
2551 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002552 } else {
2553 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002554 }
2555
2556 boolean imMayMove = (flagChanges&(
2557 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
2558 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002559
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002560 boolean focusMayChange = win.mViewVisibility != viewVisibility
2561 || ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
2562 || (!win.mRelayoutCalled);
Romain Guy06882f82009-06-10 13:36:04 -07002563
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002564 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2565 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07002566 wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002568 win.mRelayoutCalled = true;
2569 final int oldVisibility = win.mViewVisibility;
2570 win.mViewVisibility = viewVisibility;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07002571 if (DEBUG_SCREEN_ON) {
2572 RuntimeException stack = new RuntimeException();
2573 stack.fillInStackTrace();
2574 Slog.i(TAG, "Relayout " + win + ": oldVis=" + oldVisibility
2575 + " newVis=" + viewVisibility, stack);
2576 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002577 if (viewVisibility == View.VISIBLE &&
2578 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
2579 displayed = !win.isVisibleLw();
2580 if (win.mExiting) {
2581 win.mExiting = false;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07002582 if (win.mAnimation != null) {
2583 win.mAnimation.cancel();
2584 win.mAnimation = null;
2585 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002586 }
2587 if (win.mDestroying) {
2588 win.mDestroying = false;
2589 mDestroySurface.remove(win);
2590 }
2591 if (oldVisibility == View.GONE) {
2592 win.mEnterAnimationPending = true;
2593 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002594 if (displayed) {
2595 if (win.mSurface != null && !win.mDrawPending
2596 && !win.mCommitDrawPending && !mDisplayFrozen
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07002597 && mDisplayEnabled && mPolicy.isScreenOnFully()) {
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002598 applyEnterAnimationLocked(win);
2599 }
2600 if ((win.mAttrs.flags
2601 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2602 if (DEBUG_VISIBILITY) Slog.v(TAG,
2603 "Relayout window turning screen on: " + win);
2604 win.mTurnOnScreen = true;
2605 }
2606 int diff = 0;
2607 if (win.mConfiguration != mCurConfiguration
2608 && (win.mConfiguration == null
2609 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2610 win.mConfiguration = mCurConfiguration;
2611 if (DEBUG_CONFIGURATION) {
2612 Slog.i(TAG, "Window " + win + " visible with new config: "
2613 + win.mConfiguration + " / 0x"
2614 + Integer.toHexString(diff));
2615 }
2616 outConfig.setTo(mCurConfiguration);
2617 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002618 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002619 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2620 // To change the format, we need to re-build the surface.
2621 win.destroySurfaceLocked();
2622 displayed = true;
2623 }
2624 try {
2625 Surface surface = win.createSurfaceLocked();
2626 if (surface != null) {
2627 outSurface.copyFrom(surface);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002628 win.mReportDestroySurface = false;
2629 win.mSurfacePendingDestroy = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002630 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002631 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002632 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002633 // For some reason there isn't a surface. Clear the
2634 // caller's object so they see the same state.
2635 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002636 }
2637 } catch (Exception e) {
Jeff Brown2e44b072011-01-24 15:21:56 -08002638 mInputMonitor.updateInputWindowsLw(true /*force*/);
Jeff Browne33348b2010-07-15 23:54:05 -07002639
Joe Onorato8a9b2202010-02-26 18:56:32 -08002640 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002641 + client + " (" + win.mAttrs.getTitle() + ")",
2642 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002643 Binder.restoreCallingIdentity(origId);
2644 return 0;
2645 }
2646 if (displayed) {
2647 focusMayChange = true;
2648 }
2649 if (win.mAttrs.type == TYPE_INPUT_METHOD
2650 && mInputMethodWindow == null) {
2651 mInputMethodWindow = win;
2652 imMayMove = true;
2653 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002654 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2655 && win.mAppToken != null
2656 && win.mAppToken.startingWindow != null) {
2657 // Special handling of starting window over the base
2658 // window of the app: propagate lock screen flags to it,
2659 // to provide the correct semantics while starting.
2660 final int mask =
2661 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002662 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2663 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002664 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2665 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2666 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002667 } else {
2668 win.mEnterAnimationPending = false;
2669 if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002670 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002671 + ": mExiting=" + win.mExiting
2672 + " mSurfacePendingDestroy=" + win.mSurfacePendingDestroy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002673 // If we are not currently running the exit animation, we
2674 // need to see about starting one.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002675 if (!win.mExiting || win.mSurfacePendingDestroy) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002676 // Try starting an animation; if there isn't one, we
2677 // can destroy the surface right away.
2678 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2679 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2680 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2681 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002682 if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002683 applyAnimationLocked(win, transit, false)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002684 focusMayChange = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002685 win.mExiting = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002686 } else if (win.isAnimating()) {
2687 // Currently in a hide animation... turn this into
2688 // an exit.
2689 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002690 } else if (win == mWallpaperTarget) {
2691 // If the wallpaper is currently behind this
2692 // window, we need to change both of them inside
2693 // of a transaction to avoid artifacts.
2694 win.mExiting = true;
2695 win.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002696 } else {
2697 if (mInputMethodWindow == win) {
2698 mInputMethodWindow = null;
2699 }
2700 win.destroySurfaceLocked();
2701 }
2702 }
2703 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002704
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002705 if (win.mSurface == null || (win.getAttrs().flags
2706 & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
2707 || win.mSurfacePendingDestroy) {
2708 // We are being called from a local process, which
2709 // means outSurface holds its current surface. Ensure the
2710 // surface object is cleared, but we don't want it actually
2711 // destroyed at this point.
2712 win.mSurfacePendingDestroy = false;
2713 outSurface.release();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002714 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002715 } else if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002716 if (DEBUG_VISIBILITY) Slog.i(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002717 "Keeping surface, will report destroy: " + win);
2718 win.mReportDestroySurface = true;
2719 outSurface.copyFrom(win.mSurface);
2720 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002721 }
2722
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002723 if (focusMayChange) {
2724 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
Jeff Brown3a22cd92011-01-21 13:59:04 -08002725 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2726 false /*updateInputWindows*/)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002727 imMayMove = false;
2728 }
2729 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2730 }
Romain Guy06882f82009-06-10 13:36:04 -07002731
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002732 // updateFocusedWindowLocked() already assigned layers so we only need to
2733 // reassign them at this point if the IM window state gets shuffled
2734 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002735
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002736 if (imMayMove) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002737 if (moveInputMethodWindowsIfNeededLocked(false) || displayed) {
2738 // Little hack here -- we -should- be able to rely on the
2739 // function to return true if the IME has moved and needs
2740 // its layer recomputed. However, if the IME was hidden
2741 // and isn't actually moved in the list, its layer may be
2742 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002743 assignLayers = true;
2744 }
2745 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002746 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002747 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002748 assignLayers = true;
2749 }
2750 }
Romain Guy06882f82009-06-10 13:36:04 -07002751
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002752 mLayoutNeeded = true;
2753 win.mGivenInsetsPending = insetsPending;
2754 if (assignLayers) {
2755 assignLayersLocked();
2756 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002757 configChanged = updateOrientationFromAppTokensLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002758 performLayoutAndPlaceSurfacesLocked();
Dianne Hackborn284ac932009-08-28 10:34:25 -07002759 if (displayed && win.mIsWallpaper) {
Dianne Hackborn81e56d52011-05-26 00:55:58 -07002760 updateWallpaperOffsetLocked(win, mAppDisplayWidth, mAppDisplayHeight, false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002761 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002762 if (win.mAppToken != null) {
2763 win.mAppToken.updateReportedVisibilityLocked();
2764 }
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002765 outFrame.set(win.mCompatFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002766 outContentInsets.set(win.mContentInsets);
2767 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002768 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002769 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002770 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002771 + ", requestedHeight=" + requestedHeight
2772 + ", viewVisibility=" + viewVisibility
2773 + "\nRelayout returning frame=" + outFrame
2774 + ", surface=" + outSurface);
2775
Joe Onorato8a9b2202010-02-26 18:56:32 -08002776 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002777 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
2778
2779 inTouchMode = mInTouchMode;
Jeff Browne33348b2010-07-15 23:54:05 -07002780
Jeff Brown2e44b072011-01-24 15:21:56 -08002781 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002782 }
2783
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002784 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002785 sendNewConfiguration();
2786 }
Romain Guy06882f82009-06-10 13:36:04 -07002787
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002788 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002789
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002790 return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
2791 | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
2792 }
2793
Dianne Hackborn64825172011-03-02 21:32:58 -08002794 public boolean outOfMemoryWindow(Session session, IWindow client) {
2795 long origId = Binder.clearCallingIdentity();
2796
2797 try {
2798 synchronized(mWindowMap) {
2799 WindowState win = windowForClientLocked(session, client, false);
2800 if (win == null) {
2801 return false;
2802 }
2803 return reclaimSomeSurfaceMemoryLocked(win, "from-client", false);
2804 }
2805 } finally {
2806 Binder.restoreCallingIdentity(origId);
2807 }
2808 }
2809
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002810 public void finishDrawingWindow(Session session, IWindow client) {
2811 final long origId = Binder.clearCallingIdentity();
2812 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002813 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002814 if (win != null && win.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002815 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
2816 adjustWallpaperWindowsLocked();
2817 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002818 mLayoutNeeded = true;
2819 performLayoutAndPlaceSurfacesLocked();
2820 }
2821 }
2822 Binder.restoreCallingIdentity(origId);
2823 }
2824
Svetoslav Ganov7961be72011-06-21 12:31:56 -07002825 public float getWindowCompatibilityScale(IBinder windowToken) {
2826 synchronized (mWindowMap) {
2827 WindowState windowState = mWindowMap.get(windowToken);
2828 return (windowState != null) ? windowState.mGlobalScale : 1.0f;
2829 }
2830 }
2831
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002832 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Dianne Hackborn08121bc2011-01-17 17:54:31 -08002833 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: layout params pkg="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002834 + (lp != null ? lp.packageName : null)
2835 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
2836 if (lp != null && lp.windowAnimations != 0) {
2837 // If this is a system resource, don't try to load it from the
2838 // application resources. It is nice to avoid loading application
2839 // resources if we can.
2840 String packageName = lp.packageName != null ? lp.packageName : "android";
2841 int resId = lp.windowAnimations;
2842 if ((resId&0xFF000000) == 0x01000000) {
2843 packageName = "android";
2844 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002845 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002846 + packageName);
2847 return AttributeCache.instance().get(packageName, resId,
2848 com.android.internal.R.styleable.WindowAnimation);
2849 }
2850 return null;
2851 }
Romain Guy06882f82009-06-10 13:36:04 -07002852
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002853 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Dianne Hackborn08121bc2011-01-17 17:54:31 -08002854 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002855 + packageName + " resId=0x" + Integer.toHexString(resId));
2856 if (packageName != null) {
2857 if ((resId&0xFF000000) == 0x01000000) {
2858 packageName = "android";
2859 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002860 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002861 + packageName);
2862 return AttributeCache.instance().get(packageName, resId,
2863 com.android.internal.R.styleable.WindowAnimation);
2864 }
2865 return null;
2866 }
2867
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002868 void applyEnterAnimationLocked(WindowState win) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002869 int transit = WindowManagerPolicy.TRANSIT_SHOW;
2870 if (win.mEnterAnimationPending) {
2871 win.mEnterAnimationPending = false;
2872 transit = WindowManagerPolicy.TRANSIT_ENTER;
2873 }
2874
2875 applyAnimationLocked(win, transit, true);
2876 }
2877
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002878 boolean applyAnimationLocked(WindowState win,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002879 int transit, boolean isEntrance) {
2880 if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
2881 // If we are trying to apply an animation, but already running
2882 // an animation of the same type, then just leave that one alone.
2883 return true;
2884 }
Romain Guy06882f82009-06-10 13:36:04 -07002885
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002886 // Only apply an animation if the display isn't frozen. If it is
2887 // frozen, there is no reason to animate and it can cause strange
2888 // artifacts when we unfreeze the display if some different animation
2889 // is running.
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07002890 if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002891 int anim = mPolicy.selectAnimationLw(win, transit);
2892 int attr = -1;
2893 Animation a = null;
2894 if (anim != 0) {
2895 a = AnimationUtils.loadAnimation(mContext, anim);
2896 } else {
2897 switch (transit) {
2898 case WindowManagerPolicy.TRANSIT_ENTER:
2899 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
2900 break;
2901 case WindowManagerPolicy.TRANSIT_EXIT:
2902 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
2903 break;
2904 case WindowManagerPolicy.TRANSIT_SHOW:
2905 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
2906 break;
2907 case WindowManagerPolicy.TRANSIT_HIDE:
2908 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
2909 break;
2910 }
2911 if (attr >= 0) {
2912 a = loadAnimation(win.mAttrs, attr);
2913 }
2914 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002915 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: win=" + win
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002916 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
2917 + " mAnimation=" + win.mAnimation
2918 + " isEntrance=" + isEntrance);
2919 if (a != null) {
2920 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002921 RuntimeException e = null;
2922 if (!HIDE_STACK_CRAWLS) {
2923 e = new RuntimeException();
2924 e.fillInStackTrace();
2925 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002926 Slog.v(TAG, "Loaded animation " + a + " for " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002927 }
2928 win.setAnimation(a);
2929 win.mAnimationIsEntrance = isEntrance;
2930 }
2931 } else {
2932 win.clearAnimation();
2933 }
2934
2935 return win.mAnimation != null;
2936 }
2937
2938 private Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
2939 int anim = 0;
2940 Context context = mContext;
2941 if (animAttr >= 0) {
2942 AttributeCache.Entry ent = getCachedAnimations(lp);
2943 if (ent != null) {
2944 context = ent.context;
2945 anim = ent.array.getResourceId(animAttr, 0);
2946 }
2947 }
2948 if (anim != 0) {
2949 return AnimationUtils.loadAnimation(context, anim);
2950 }
2951 return null;
2952 }
Romain Guy06882f82009-06-10 13:36:04 -07002953
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002954 private Animation loadAnimation(String packageName, int resId) {
2955 int anim = 0;
2956 Context context = mContext;
2957 if (resId >= 0) {
2958 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
2959 if (ent != null) {
2960 context = ent.context;
2961 anim = resId;
2962 }
2963 }
2964 if (anim != 0) {
2965 return AnimationUtils.loadAnimation(context, anim);
2966 }
2967 return null;
2968 }
2969
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002970 private boolean applyAnimationLocked(AppWindowToken wtoken,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002971 WindowManager.LayoutParams lp, int transit, boolean enter) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002972 // Only apply an animation if the display isn't frozen. If it is
2973 // frozen, there is no reason to animate and it can cause strange
2974 // artifacts when we unfreeze the display if some different animation
2975 // is running.
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07002976 if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002977 Animation a;
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002978 if (mNextAppTransitionPackage != null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002979 a = loadAnimation(mNextAppTransitionPackage, enter ?
2980 mNextAppTransitionEnter : mNextAppTransitionExit);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002981 } else {
2982 int animAttr = 0;
2983 switch (transit) {
2984 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
2985 animAttr = enter
2986 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
2987 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
2988 break;
2989 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
2990 animAttr = enter
2991 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
2992 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
2993 break;
2994 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
2995 animAttr = enter
2996 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
2997 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
2998 break;
2999 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
3000 animAttr = enter
3001 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
3002 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
3003 break;
3004 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
3005 animAttr = enter
3006 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
3007 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
3008 break;
3009 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
3010 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07003011 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003012 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
3013 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003014 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003015 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003016 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
3017 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003018 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003019 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003020 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003021 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
3022 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
3023 break;
3024 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
3025 animAttr = enter
3026 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
3027 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
3028 break;
3029 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
3030 animAttr = enter
3031 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
3032 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003033 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003034 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003035 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003036 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003037 + " anim=" + a
3038 + " animAttr=0x" + Integer.toHexString(animAttr)
3039 + " transit=" + transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003040 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003041 if (a != null) {
3042 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003043 RuntimeException e = null;
3044 if (!HIDE_STACK_CRAWLS) {
3045 e = new RuntimeException();
3046 e.fillInStackTrace();
3047 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003048 Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003049 }
3050 wtoken.setAnimation(a);
3051 }
3052 } else {
3053 wtoken.clearAnimation();
3054 }
3055
3056 return wtoken.animation != null;
3057 }
3058
3059 // -------------------------------------------------------------
3060 // Application Window Tokens
3061 // -------------------------------------------------------------
3062
3063 public void validateAppTokens(List tokens) {
3064 int v = tokens.size()-1;
3065 int m = mAppTokens.size()-1;
3066 while (v >= 0 && m >= 0) {
3067 AppWindowToken wtoken = mAppTokens.get(m);
3068 if (wtoken.removed) {
3069 m--;
3070 continue;
3071 }
3072 if (tokens.get(v) != wtoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003073 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003074 + " @ " + v + ", internal is " + wtoken.token + " @ " + m);
3075 }
3076 v--;
3077 m--;
3078 }
3079 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003080 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003081 v--;
3082 }
3083 while (m >= 0) {
3084 AppWindowToken wtoken = mAppTokens.get(m);
3085 if (!wtoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003086 Slog.w(TAG, "Invalid internal token: " + wtoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003087 }
3088 m--;
3089 }
3090 }
3091
3092 boolean checkCallingPermission(String permission, String func) {
3093 // Quick check: if the calling permission is me, it's all okay.
3094 if (Binder.getCallingPid() == Process.myPid()) {
3095 return true;
3096 }
Romain Guy06882f82009-06-10 13:36:04 -07003097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003098 if (mContext.checkCallingPermission(permission)
3099 == PackageManager.PERMISSION_GRANTED) {
3100 return true;
3101 }
3102 String msg = "Permission Denial: " + func + " from pid="
3103 + Binder.getCallingPid()
3104 + ", uid=" + Binder.getCallingUid()
3105 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003106 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003107 return false;
3108 }
Romain Guy06882f82009-06-10 13:36:04 -07003109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003110 AppWindowToken findAppWindowToken(IBinder token) {
3111 WindowToken wtoken = mTokenMap.get(token);
3112 if (wtoken == null) {
3113 return null;
3114 }
3115 return wtoken.appWindowToken;
3116 }
Romain Guy06882f82009-06-10 13:36:04 -07003117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003118 public void addWindowToken(IBinder token, int type) {
3119 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3120 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003121 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003122 }
Romain Guy06882f82009-06-10 13:36:04 -07003123
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003124 synchronized(mWindowMap) {
3125 WindowToken wtoken = mTokenMap.get(token);
3126 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003127 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003128 return;
3129 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003130 wtoken = new WindowToken(this, token, type, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003131 mTokenMap.put(token, wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003132 if (type == TYPE_WALLPAPER) {
3133 mWallpaperTokens.add(wtoken);
3134 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003135 }
3136 }
Romain Guy06882f82009-06-10 13:36:04 -07003137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003138 public void removeWindowToken(IBinder token) {
3139 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3140 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003141 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003142 }
3143
3144 final long origId = Binder.clearCallingIdentity();
3145 synchronized(mWindowMap) {
3146 WindowToken wtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003147 if (wtoken != null) {
3148 boolean delayed = false;
3149 if (!wtoken.hidden) {
3150 wtoken.hidden = true;
Romain Guy06882f82009-06-10 13:36:04 -07003151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003152 final int N = wtoken.windows.size();
3153 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003155 for (int i=0; i<N; i++) {
3156 WindowState win = wtoken.windows.get(i);
3157
3158 if (win.isAnimating()) {
3159 delayed = true;
3160 }
Romain Guy06882f82009-06-10 13:36:04 -07003161
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003162 if (win.isVisibleNow()) {
3163 applyAnimationLocked(win,
3164 WindowManagerPolicy.TRANSIT_EXIT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003165 changed = true;
3166 }
3167 }
3168
3169 if (changed) {
3170 mLayoutNeeded = true;
3171 performLayoutAndPlaceSurfacesLocked();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003172 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
3173 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003174 }
Romain Guy06882f82009-06-10 13:36:04 -07003175
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003176 if (delayed) {
3177 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003178 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3179 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003180 }
3181 }
Romain Guy06882f82009-06-10 13:36:04 -07003182
Jeff Brown2e44b072011-01-24 15:21:56 -08003183 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003184 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003185 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003186 }
3187 }
3188 Binder.restoreCallingIdentity(origId);
3189 }
3190
3191 public void addAppToken(int addPos, IApplicationToken token,
3192 int groupId, int requestedOrientation, boolean fullscreen) {
3193 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3194 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003195 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003196 }
Jeff Brown349703e2010-06-22 01:27:15 -07003197
3198 // Get the dispatching timeout here while we are not holding any locks so that it
3199 // can be cached by the AppWindowToken. The timeout value is used later by the
3200 // input dispatcher in code that does hold locks. If we did not cache the value
3201 // here we would run the chance of introducing a deadlock between the window manager
3202 // (which holds locks while updating the input dispatcher state) and the activity manager
3203 // (which holds locks while querying the application token).
3204 long inputDispatchingTimeoutNanos;
3205 try {
3206 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3207 } catch (RemoteException ex) {
3208 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3209 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3210 }
Romain Guy06882f82009-06-10 13:36:04 -07003211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003212 synchronized(mWindowMap) {
3213 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3214 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003215 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003216 return;
3217 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003218 wtoken = new AppWindowToken(this, token);
Jeff Brown349703e2010-06-22 01:27:15 -07003219 wtoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003220 wtoken.groupId = groupId;
3221 wtoken.appFullscreen = fullscreen;
3222 wtoken.requestedOrientation = requestedOrientation;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003223 if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003224 mAppTokens.add(addPos, wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003225 mTokenMap.put(token.asBinder(), wtoken);
Romain Guy06882f82009-06-10 13:36:04 -07003226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003227 // Application tokens start out hidden.
3228 wtoken.hidden = true;
3229 wtoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003230
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003231 //dump();
3232 }
3233 }
Romain Guy06882f82009-06-10 13:36:04 -07003234
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003235 public void setAppGroupId(IBinder token, int groupId) {
3236 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3237 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003238 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003239 }
3240
3241 synchronized(mWindowMap) {
3242 AppWindowToken wtoken = findAppWindowToken(token);
3243 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003244 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003245 return;
3246 }
3247 wtoken.groupId = groupId;
3248 }
3249 }
Romain Guy06882f82009-06-10 13:36:04 -07003250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003251 public int getOrientationFromWindowsLocked() {
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003252 if (mDisplayFrozen || mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
3253 // If the display is frozen, some activities may be in the middle
3254 // of restarting, and thus have removed their old window. If the
3255 // window has the flag to hide the lock screen, then the lock screen
3256 // can re-appear and inflict its own orientation on us. Keep the
3257 // orientation stable until this all settles down.
3258 return mLastWindowForcedOrientation;
3259 }
3260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003261 int pos = mWindows.size() - 1;
3262 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07003263 WindowState wtoken = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003264 pos--;
3265 if (wtoken.mAppToken != null) {
3266 // We hit an application window. so the orientation will be determined by the
3267 // app window. No point in continuing further.
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003268 return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003269 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003270 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003271 continue;
3272 }
3273 int req = wtoken.mAttrs.screenOrientation;
3274 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3275 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3276 continue;
3277 } else {
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003278 return (mLastWindowForcedOrientation=req);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003279 }
3280 }
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003281 return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003282 }
Romain Guy06882f82009-06-10 13:36:04 -07003283
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003284 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003285 int pos = mAppTokens.size() - 1;
3286 int curGroup = 0;
3287 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3288 boolean findingBehind = false;
3289 boolean haveGroup = false;
3290 boolean lastFullscreen = false;
3291 while (pos >= 0) {
3292 AppWindowToken wtoken = mAppTokens.get(pos);
3293 pos--;
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003294
3295 if (DEBUG_APP_ORIENTATION) Slog.v(TAG, "Checking app orientation: " + wtoken);
3296
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003297 // if we're about to tear down this window and not seek for
3298 // the behind activity, don't use it for orientation
3299 if (!findingBehind
3300 && (!wtoken.hidden && wtoken.hiddenRequested)) {
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003301 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + wtoken
3302 + " -- going to hide");
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003303 continue;
3304 }
3305
3306 if (!haveGroup) {
3307 // We ignore any hidden applications on the top.
3308 if (wtoken.hiddenRequested || wtoken.willBeHidden) {
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003309 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + wtoken
3310 + " -- hidden on top");
The Android Open Source Project10592532009-03-18 17:39:46 -07003311 continue;
3312 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003313 haveGroup = true;
3314 curGroup = wtoken.groupId;
3315 lastOrientation = wtoken.requestedOrientation;
3316 } else if (curGroup != wtoken.groupId) {
3317 // If we have hit a new application group, and the bottom
3318 // of the previous group didn't explicitly say to use
3319 // the orientation behind it, and the last app was
3320 // full screen, then we'll stick with the
3321 // user's orientation.
3322 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3323 && lastFullscreen) {
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003324 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + wtoken
3325 + " -- end of group, return " + lastOrientation);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003326 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003327 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003328 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003329 int or = wtoken.requestedOrientation;
3330 // If this application is fullscreen, and didn't explicitly say
3331 // to use the orientation behind it, then just take whatever
3332 // orientation it has and ignores whatever is under it.
3333 lastFullscreen = wtoken.appFullscreen;
3334 if (lastFullscreen
3335 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003336 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + wtoken
3337 + " -- full screen, return " + or);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003338 return or;
3339 }
3340 // If this application has requested an explicit orientation,
3341 // then use it.
Dianne Hackborne5439f22010-10-02 16:53:50 -07003342 if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
3343 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003344 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + wtoken
3345 + " -- explicitly set, return " + or);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003346 return or;
3347 }
3348 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3349 }
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003350 if (DEBUG_ORIENTATION) Slog.v(TAG, "No app is requesting an orientation");
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003351 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003352 }
Romain Guy06882f82009-06-10 13:36:04 -07003353
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003354 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003355 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003356 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3357 "updateOrientationFromAppTokens()")) {
3358 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3359 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003360
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003361 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003362 long ident = Binder.clearCallingIdentity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003363
3364 synchronized(mWindowMap) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003365 config = updateOrientationFromAppTokensLocked(currentConfig,
3366 freezeThisOneIfNeeded);
3367 }
3368
3369 Binder.restoreCallingIdentity(ident);
3370 return config;
3371 }
3372
3373 private Configuration updateOrientationFromAppTokensLocked(
3374 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
3375 Configuration config = null;
3376
3377 if (updateOrientationFromAppTokensLocked(false)) {
3378 if (freezeThisOneIfNeeded != null) {
3379 AppWindowToken wtoken = findAppWindowToken(
3380 freezeThisOneIfNeeded);
3381 if (wtoken != null) {
3382 startAppFreezingScreenLocked(wtoken,
3383 ActivityInfo.CONFIG_ORIENTATION);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003384 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003385 }
3386 config = computeNewConfigurationLocked();
3387
3388 } else if (currentConfig != null) {
3389 // No obvious action we need to take, but if our current
3390 // state mismatches the activity manager's, update it,
3391 // disregarding font scale, which should remain set to
3392 // the value of the previous configuration.
3393 mTempConfiguration.setToDefaults();
3394 mTempConfiguration.fontScale = currentConfig.fontScale;
3395 if (computeNewConfigurationLocked(mTempConfiguration)) {
3396 if (currentConfig.diff(mTempConfiguration) != 0) {
3397 mWaitingForConfig = true;
3398 mLayoutNeeded = true;
3399 startFreezingDisplayLocked(false);
3400 config = new Configuration(mTempConfiguration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003401 }
3402 }
3403 }
3404
Dianne Hackborncfaef692009-06-15 14:24:44 -07003405 return config;
3406 }
3407
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003408 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003409 * Determine the new desired orientation of the display, returning
3410 * a non-null new Configuration if it has changed from the current
3411 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3412 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3413 * SCREEN. This will typically be done for you if you call
3414 * sendNewConfiguration().
3415 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003416 * The orientation is computed from non-application windows first. If none of
3417 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003418 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003419 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3420 * android.os.IBinder)
3421 */
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003422 boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003423 boolean changed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003424 long ident = Binder.clearCallingIdentity();
3425 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003426 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003427
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003428 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003429 mForcedAppOrientation = req;
3430 //send a message to Policy indicating orientation change to take
3431 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003432 mPolicy.setCurrentOrientationLw(req);
Jeff Brown01a98dd2011-09-20 15:08:29 -07003433 if (updateRotationUncheckedLocked(inTransaction)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003434 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003435 }
3436 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003437
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003438 return changed;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003439 } finally {
3440 Binder.restoreCallingIdentity(ident);
3441 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003442 }
Romain Guy06882f82009-06-10 13:36:04 -07003443
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003444 int computeForcedAppOrientationLocked() {
3445 int req = getOrientationFromWindowsLocked();
3446 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3447 req = getOrientationFromAppTokensLocked();
3448 }
3449 return req;
3450 }
Romain Guy06882f82009-06-10 13:36:04 -07003451
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003452 public void setNewConfiguration(Configuration config) {
3453 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3454 "setNewConfiguration()")) {
3455 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3456 }
3457
3458 synchronized(mWindowMap) {
3459 mCurConfiguration = new Configuration(config);
3460 mWaitingForConfig = false;
3461 performLayoutAndPlaceSurfacesLocked();
3462 }
3463 }
3464
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003465 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3466 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3467 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003468 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003469 }
Romain Guy06882f82009-06-10 13:36:04 -07003470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003471 synchronized(mWindowMap) {
3472 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3473 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003474 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003475 return;
3476 }
Romain Guy06882f82009-06-10 13:36:04 -07003477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003478 wtoken.requestedOrientation = requestedOrientation;
3479 }
3480 }
Romain Guy06882f82009-06-10 13:36:04 -07003481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003482 public int getAppOrientation(IApplicationToken token) {
3483 synchronized(mWindowMap) {
3484 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3485 if (wtoken == null) {
3486 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3487 }
Romain Guy06882f82009-06-10 13:36:04 -07003488
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003489 return wtoken.requestedOrientation;
3490 }
3491 }
Romain Guy06882f82009-06-10 13:36:04 -07003492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003493 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3494 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3495 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003496 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003497 }
3498
3499 synchronized(mWindowMap) {
3500 boolean changed = false;
3501 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003502 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003503 changed = mFocusedApp != null;
3504 mFocusedApp = null;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003505 if (changed) {
3506 mInputMonitor.setFocusedAppLw(null);
Jeff Brown349703e2010-06-22 01:27:15 -07003507 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003508 } else {
3509 AppWindowToken newFocus = findAppWindowToken(token);
3510 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003511 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003512 return;
3513 }
3514 changed = mFocusedApp != newFocus;
3515 mFocusedApp = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003516 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003517 if (changed) {
3518 mInputMonitor.setFocusedAppLw(newFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07003519 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003520 }
3521
3522 if (moveFocusNow && changed) {
3523 final long origId = Binder.clearCallingIdentity();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003524 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003525 Binder.restoreCallingIdentity(origId);
3526 }
3527 }
3528 }
3529
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003530 public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003531 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3532 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003533 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003534 }
Romain Guy06882f82009-06-10 13:36:04 -07003535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003536 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003537 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003538 TAG, "Prepare app transition: transit=" + transit
3539 + " mNextAppTransition=" + mNextAppTransition);
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07003540 if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003541 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
3542 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003543 mNextAppTransition = transit;
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003544 } else if (!alwaysKeepCurrent) {
3545 if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
3546 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
3547 // Opening a new task always supersedes a close for the anim.
3548 mNextAppTransition = transit;
3549 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
3550 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
3551 // Opening a new activity always supersedes a close for the anim.
3552 mNextAppTransition = transit;
3553 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003554 }
3555 mAppTransitionReady = false;
3556 mAppTransitionTimeout = false;
3557 mStartingIconInTransition = false;
3558 mSkipAppTransitionAnimation = false;
3559 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
3560 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
3561 5000);
3562 }
3563 }
3564 }
3565
3566 public int getPendingAppTransition() {
3567 return mNextAppTransition;
3568 }
Romain Guy06882f82009-06-10 13:36:04 -07003569
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003570 public void overridePendingAppTransition(String packageName,
3571 int enterAnim, int exitAnim) {
Dianne Hackborn8b571a82009-09-25 16:09:43 -07003572 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003573 mNextAppTransitionPackage = packageName;
3574 mNextAppTransitionEnter = enterAnim;
3575 mNextAppTransitionExit = exitAnim;
3576 }
3577 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003579 public void executeAppTransition() {
3580 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3581 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003582 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003583 }
Romain Guy06882f82009-06-10 13:36:04 -07003584
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003585 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003586 if (DEBUG_APP_TRANSITIONS) {
3587 RuntimeException e = new RuntimeException("here");
3588 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003589 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003590 + mNextAppTransition, e);
3591 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003592 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003593 mAppTransitionReady = true;
3594 final long origId = Binder.clearCallingIdentity();
3595 performLayoutAndPlaceSurfacesLocked();
3596 Binder.restoreCallingIdentity(origId);
3597 }
3598 }
3599 }
3600
3601 public void setAppStartingWindow(IBinder token, String pkg,
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07003602 int theme, CompatibilityInfo compatInfo,
3603 CharSequence nonLocalizedLabel, int labelRes, int icon,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003604 int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003605 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3606 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003607 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003608 }
3609
3610 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003611 if (DEBUG_STARTING_WINDOW) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003612 TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
3613 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003615 AppWindowToken wtoken = findAppWindowToken(token);
3616 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003617 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003618 return;
3619 }
3620
3621 // If the display is frozen, we won't do anything until the
3622 // actual window is displayed so there is no reason to put in
3623 // the starting window.
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07003624 if (mDisplayFrozen || !mDisplayEnabled || !mPolicy.isScreenOnFully()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003625 return;
3626 }
Romain Guy06882f82009-06-10 13:36:04 -07003627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003628 if (wtoken.startingData != null) {
3629 return;
3630 }
Romain Guy06882f82009-06-10 13:36:04 -07003631
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003632 if (transferFrom != null) {
3633 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3634 if (ttoken != null) {
3635 WindowState startingWindow = ttoken.startingWindow;
3636 if (startingWindow != null) {
3637 if (mStartingIconInTransition) {
3638 // In this case, the starting icon has already
3639 // been displayed, so start letting windows get
3640 // shown immediately without any more transitions.
3641 mSkipAppTransitionAnimation = true;
3642 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003643 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003644 "Moving existing starting from " + ttoken
3645 + " to " + wtoken);
3646 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003647
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003648 // Transfer the starting window over to the new
3649 // token.
3650 wtoken.startingData = ttoken.startingData;
3651 wtoken.startingView = ttoken.startingView;
3652 wtoken.startingWindow = startingWindow;
3653 ttoken.startingData = null;
3654 ttoken.startingView = null;
3655 ttoken.startingWindow = null;
3656 ttoken.startingMoved = true;
3657 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003658 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003659 startingWindow.mAppToken = wtoken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003660 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003661 "Removing starting window: " + startingWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003662 mWindows.remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07003663 mWindowsChanged = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003664 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing starting " + startingWindow
3665 + " from " + ttoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003666 ttoken.windows.remove(startingWindow);
3667 ttoken.allAppWindows.remove(startingWindow);
3668 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003670 // Propagate other interesting state between the
3671 // tokens. If the old token is displayed, we should
3672 // immediately force the new one to be displayed. If
3673 // it is animating, we need to move that animation to
3674 // the new one.
3675 if (ttoken.allDrawn) {
3676 wtoken.allDrawn = true;
3677 }
3678 if (ttoken.firstWindowDrawn) {
3679 wtoken.firstWindowDrawn = true;
3680 }
3681 if (!ttoken.hidden) {
3682 wtoken.hidden = false;
3683 wtoken.hiddenRequested = false;
3684 wtoken.willBeHidden = false;
3685 }
3686 if (wtoken.clientHidden != ttoken.clientHidden) {
3687 wtoken.clientHidden = ttoken.clientHidden;
3688 wtoken.sendAppVisibilityToClients();
3689 }
3690 if (ttoken.animation != null) {
3691 wtoken.animation = ttoken.animation;
3692 wtoken.animating = ttoken.animating;
3693 wtoken.animLayerAdjustment = ttoken.animLayerAdjustment;
3694 ttoken.animation = null;
3695 ttoken.animLayerAdjustment = 0;
3696 wtoken.updateLayers();
3697 ttoken.updateLayers();
3698 }
Romain Guy06882f82009-06-10 13:36:04 -07003699
Jeff Brown3a22cd92011-01-21 13:59:04 -08003700 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
3701 true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003702 mLayoutNeeded = true;
3703 performLayoutAndPlaceSurfacesLocked();
3704 Binder.restoreCallingIdentity(origId);
3705 return;
3706 } else if (ttoken.startingData != null) {
3707 // The previous app was getting ready to show a
3708 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08003709 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003710 "Moving pending starting from " + ttoken
3711 + " to " + wtoken);
3712 wtoken.startingData = ttoken.startingData;
3713 ttoken.startingData = null;
3714 ttoken.startingMoved = true;
3715 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3716 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3717 // want to process the message ASAP, before any other queued
3718 // messages.
3719 mH.sendMessageAtFrontOfQueue(m);
3720 return;
3721 }
3722 }
3723 }
3724
3725 // There is no existing starting window, and the caller doesn't
3726 // want us to create one, so that's it!
3727 if (!createIfNeeded) {
3728 return;
3729 }
Romain Guy06882f82009-06-10 13:36:04 -07003730
Dianne Hackborn284ac932009-08-28 10:34:25 -07003731 // If this is a translucent or wallpaper window, then don't
3732 // show a starting window -- the current effect (a full-screen
3733 // opaque starting window that fades away to the real contents
3734 // when it is ready) does not work for this.
3735 if (theme != 0) {
3736 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
3737 com.android.internal.R.styleable.Window);
3738 if (ent.array.getBoolean(
3739 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
3740 return;
3741 }
3742 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07003743 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
3744 return;
3745 }
3746 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07003747 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
3748 return;
3749 }
3750 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003751
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003752 mStartingIconInTransition = true;
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07003753 wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003754 labelRes, icon, windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003755 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3756 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3757 // want to process the message ASAP, before any other queued
3758 // messages.
3759 mH.sendMessageAtFrontOfQueue(m);
3760 }
3761 }
3762
3763 public void setAppWillBeHidden(IBinder token) {
3764 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3765 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003766 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003767 }
3768
3769 AppWindowToken wtoken;
3770
3771 synchronized(mWindowMap) {
3772 wtoken = findAppWindowToken(token);
3773 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003774 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 -08003775 return;
3776 }
3777 wtoken.willBeHidden = true;
3778 }
3779 }
Romain Guy06882f82009-06-10 13:36:04 -07003780
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003781 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07003782 boolean visible, int transit, boolean performLayout) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003783 boolean delayed = false;
3784
3785 if (wtoken.clientHidden == visible) {
3786 wtoken.clientHidden = !visible;
3787 wtoken.sendAppVisibilityToClients();
3788 }
Romain Guy06882f82009-06-10 13:36:04 -07003789
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003790 wtoken.willBeHidden = false;
3791 if (wtoken.hidden == visible) {
3792 final int N = wtoken.allAppWindows.size();
3793 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003794 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003795 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
3796 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07003797
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003798 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07003799
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003800 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003801 if (wtoken.animation == sDummyAnimation) {
3802 wtoken.animation = null;
3803 }
Dianne Hackbornffb3d932011-05-17 17:44:51 -07003804 applyAnimationLocked(wtoken, lp, transit, visible);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003805 changed = true;
3806 if (wtoken.animation != null) {
3807 delayed = runningAppAnimation = true;
3808 }
3809 }
Romain Guy06882f82009-06-10 13:36:04 -07003810
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003811 for (int i=0; i<N; i++) {
3812 WindowState win = wtoken.allAppWindows.get(i);
3813 if (win == wtoken.startingWindow) {
3814 continue;
3815 }
3816
3817 if (win.isAnimating()) {
3818 delayed = true;
3819 }
Romain Guy06882f82009-06-10 13:36:04 -07003820
Joe Onorato8a9b2202010-02-26 18:56:32 -08003821 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003822 //win.dump(" ");
3823 if (visible) {
3824 if (!win.isVisibleNow()) {
3825 if (!runningAppAnimation) {
3826 applyAnimationLocked(win,
3827 WindowManagerPolicy.TRANSIT_ENTER, true);
3828 }
3829 changed = true;
3830 }
3831 } else if (win.isVisibleNow()) {
3832 if (!runningAppAnimation) {
3833 applyAnimationLocked(win,
3834 WindowManagerPolicy.TRANSIT_EXIT, false);
3835 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003836 changed = true;
3837 }
3838 }
3839
3840 wtoken.hidden = wtoken.hiddenRequested = !visible;
3841 if (!visible) {
3842 unsetAppFreezingScreenLocked(wtoken, true, true);
3843 } else {
3844 // If we are being set visible, and the starting window is
3845 // not yet displayed, then make sure it doesn't get displayed.
3846 WindowState swin = wtoken.startingWindow;
3847 if (swin != null && (swin.mDrawPending
3848 || swin.mCommitDrawPending)) {
3849 swin.mPolicyVisibility = false;
3850 swin.mPolicyVisibilityAfterAnim = false;
3851 }
3852 }
Romain Guy06882f82009-06-10 13:36:04 -07003853
Joe Onorato8a9b2202010-02-26 18:56:32 -08003854 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003855 + ": hidden=" + wtoken.hidden + " hiddenRequested="
3856 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07003857
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003858 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003859 mLayoutNeeded = true;
Jeff Brown3a22cd92011-01-21 13:59:04 -08003860 mInputMonitor.setUpdateInputWindowsNeededLw();
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003861 if (performLayout) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08003862 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
3863 false /*updateInputWindows*/);
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003864 performLayoutAndPlaceSurfacesLocked();
3865 }
Jeff Brown2e44b072011-01-24 15:21:56 -08003866 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003867 }
3868 }
3869
3870 if (wtoken.animation != null) {
3871 delayed = true;
3872 }
Romain Guy06882f82009-06-10 13:36:04 -07003873
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003874 return delayed;
3875 }
3876
3877 public void setAppVisibility(IBinder token, boolean visible) {
3878 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3879 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003880 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003881 }
3882
3883 AppWindowToken wtoken;
3884
3885 synchronized(mWindowMap) {
3886 wtoken = findAppWindowToken(token);
3887 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003888 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003889 return;
3890 }
3891
3892 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003893 RuntimeException e = null;
3894 if (!HIDE_STACK_CRAWLS) {
3895 e = new RuntimeException();
3896 e.fillInStackTrace();
3897 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003898 Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003899 + "): mNextAppTransition=" + mNextAppTransition
3900 + " hidden=" + wtoken.hidden
3901 + " hiddenRequested=" + wtoken.hiddenRequested, e);
3902 }
Romain Guy06882f82009-06-10 13:36:04 -07003903
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003904 // If we are preparing an app transition, then delay changing
3905 // the visibility of this token until we execute that transition.
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07003906 if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully()
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003907 && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003908 // Already in requested state, don't do anything more.
3909 if (wtoken.hiddenRequested != visible) {
3910 return;
3911 }
3912 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07003913
Joe Onorato8a9b2202010-02-26 18:56:32 -08003914 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003915 TAG, "Setting dummy animation on: " + wtoken);
3916 wtoken.setDummyAnimation();
3917 mOpeningApps.remove(wtoken);
3918 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003919 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003920 wtoken.inPendingTransaction = true;
3921 if (visible) {
3922 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003923 wtoken.startingDisplayed = false;
3924 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003925
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003926 // If the token is currently hidden (should be the
3927 // common case), then we need to set up to wait for
3928 // its windows to be ready.
3929 if (wtoken.hidden) {
3930 wtoken.allDrawn = false;
3931 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003932
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003933 if (wtoken.clientHidden) {
3934 // In the case where we are making an app visible
3935 // but holding off for a transition, we still need
3936 // to tell the client to make its windows visible so
3937 // they get drawn. Otherwise, we will wait on
3938 // performing the transition until all windows have
3939 // been drawn, they never will be, and we are sad.
3940 wtoken.clientHidden = false;
3941 wtoken.sendAppVisibilityToClients();
3942 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003943 }
3944 } else {
3945 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003946
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003947 // If the token is currently visible (should be the
3948 // common case), then set up to wait for it to be hidden.
3949 if (!wtoken.hidden) {
3950 wtoken.waitingToHide = true;
3951 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003952 }
3953 return;
3954 }
Romain Guy06882f82009-06-10 13:36:04 -07003955
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003956 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003957 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07003958 true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003959 wtoken.updateReportedVisibilityLocked();
3960 Binder.restoreCallingIdentity(origId);
3961 }
3962 }
3963
3964 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
3965 boolean unfreezeSurfaceNow, boolean force) {
3966 if (wtoken.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003967 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003968 + " force=" + force);
3969 final int N = wtoken.allAppWindows.size();
3970 boolean unfrozeWindows = false;
3971 for (int i=0; i<N; i++) {
3972 WindowState w = wtoken.allAppWindows.get(i);
3973 if (w.mAppFreezing) {
3974 w.mAppFreezing = false;
3975 if (w.mSurface != null && !w.mOrientationChanging) {
3976 w.mOrientationChanging = true;
3977 }
3978 unfrozeWindows = true;
3979 }
3980 }
3981 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003982 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003983 wtoken.freezingScreen = false;
3984 mAppsFreezingScreen--;
3985 }
3986 if (unfreezeSurfaceNow) {
3987 if (unfrozeWindows) {
3988 mLayoutNeeded = true;
3989 performLayoutAndPlaceSurfacesLocked();
3990 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003991 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003992 }
3993 }
3994 }
Romain Guy06882f82009-06-10 13:36:04 -07003995
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003996 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
3997 int configChanges) {
3998 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003999 RuntimeException e = null;
4000 if (!HIDE_STACK_CRAWLS) {
4001 e = new RuntimeException();
4002 e.fillInStackTrace();
4003 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004004 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004005 + ": hidden=" + wtoken.hidden + " freezing="
4006 + wtoken.freezingScreen, e);
4007 }
4008 if (!wtoken.hiddenRequested) {
4009 if (!wtoken.freezingScreen) {
4010 wtoken.freezingScreen = true;
4011 mAppsFreezingScreen++;
4012 if (mAppsFreezingScreen == 1) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08004013 startFreezingDisplayLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004014 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
4015 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
4016 5000);
4017 }
4018 }
4019 final int N = wtoken.allAppWindows.size();
4020 for (int i=0; i<N; i++) {
4021 WindowState w = wtoken.allAppWindows.get(i);
4022 w.mAppFreezing = true;
4023 }
4024 }
4025 }
Romain Guy06882f82009-06-10 13:36:04 -07004026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004027 public void startAppFreezingScreen(IBinder token, int configChanges) {
4028 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4029 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004030 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004031 }
4032
4033 synchronized(mWindowMap) {
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07004034 if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOnFully()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004035 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004036 return;
4037 }
Romain Guy06882f82009-06-10 13:36:04 -07004038
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004039 AppWindowToken wtoken = findAppWindowToken(token);
4040 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004041 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004042 return;
4043 }
4044 final long origId = Binder.clearCallingIdentity();
4045 startAppFreezingScreenLocked(wtoken, configChanges);
4046 Binder.restoreCallingIdentity(origId);
4047 }
4048 }
Romain Guy06882f82009-06-10 13:36:04 -07004049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004050 public void stopAppFreezingScreen(IBinder token, boolean force) {
4051 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4052 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004053 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004054 }
4055
4056 synchronized(mWindowMap) {
4057 AppWindowToken wtoken = findAppWindowToken(token);
4058 if (wtoken == null || wtoken.appToken == null) {
4059 return;
4060 }
4061 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004062 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004063 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.freezingScreen);
4064 unsetAppFreezingScreenLocked(wtoken, true, force);
4065 Binder.restoreCallingIdentity(origId);
4066 }
4067 }
Romain Guy06882f82009-06-10 13:36:04 -07004068
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004069 public void removeAppToken(IBinder token) {
4070 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4071 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004072 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004073 }
4074
4075 AppWindowToken wtoken = null;
4076 AppWindowToken startingToken = null;
4077 boolean delayed = false;
4078
4079 final long origId = Binder.clearCallingIdentity();
4080 synchronized(mWindowMap) {
4081 WindowToken basewtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004082 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004083 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004084 delayed = setTokenVisibilityLocked(wtoken, null, false,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004085 WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004086 wtoken.inPendingTransaction = false;
4087 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004088 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004089 if (mClosingApps.contains(wtoken)) {
4090 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004091 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004092 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004093 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004094 delayed = true;
4095 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004096 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004097 TAG, "Removing app " + wtoken + " delayed=" + delayed
4098 + " animation=" + wtoken.animation
4099 + " animating=" + wtoken.animating);
4100 if (delayed) {
4101 // set the token aside because it has an active animation to be finished
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004102 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4103 "removeAppToken make exiting: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004104 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004105 } else {
4106 // Make sure there is no animation running on this token,
4107 // so any windows associated with it will be removed as
4108 // soon as their animations are complete
4109 wtoken.animation = null;
4110 wtoken.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004111 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004112 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4113 "removeAppToken: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004114 mAppTokens.remove(wtoken);
4115 wtoken.removed = true;
4116 if (wtoken.startingData != null) {
4117 startingToken = wtoken;
4118 }
4119 unsetAppFreezingScreenLocked(wtoken, true, true);
4120 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004121 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004122 mFocusedApp = null;
Jeff Brown3a22cd92011-01-21 13:59:04 -08004123 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004124 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004125 }
4126 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004127 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004128 }
Romain Guy06882f82009-06-10 13:36:04 -07004129
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004130 if (!delayed && wtoken != null) {
4131 wtoken.updateReportedVisibilityLocked();
4132 }
4133 }
4134 Binder.restoreCallingIdentity(origId);
4135
4136 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004137 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004138 + startingToken + ": app token removed");
4139 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
4140 mH.sendMessage(m);
4141 }
4142 }
4143
4144 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
4145 final int NW = token.windows.size();
4146 for (int i=0; i<NW; i++) {
4147 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004148 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004149 mWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004150 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004151 int j = win.mChildWindows.size();
4152 while (j > 0) {
4153 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004154 WindowState cwin = win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004155 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004156 "Tmp removing child window " + cwin);
4157 mWindows.remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004158 }
4159 }
4160 return NW > 0;
4161 }
4162
4163 void dumpAppTokensLocked() {
4164 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004165 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004166 }
4167 }
Romain Guy06882f82009-06-10 13:36:04 -07004168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004169 void dumpWindowsLocked() {
4170 for (int i=mWindows.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004171 Slog.v(TAG, " #" + i + ": " + mWindows.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004172 }
4173 }
Romain Guy06882f82009-06-10 13:36:04 -07004174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004175 private int findWindowOffsetLocked(int tokenPos) {
4176 final int NW = mWindows.size();
4177
4178 if (tokenPos >= mAppTokens.size()) {
4179 int i = NW;
4180 while (i > 0) {
4181 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07004182 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004183 if (win.getAppToken() != null) {
4184 return i+1;
4185 }
4186 }
4187 }
4188
4189 while (tokenPos > 0) {
4190 // Find the first app token below the new position that has
4191 // a window displayed.
4192 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004193 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004194 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004195 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004196 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07004197 "Skipping token -- currently sending to bottom");
4198 tokenPos--;
4199 continue;
4200 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004201 int i = wtoken.windows.size();
4202 while (i > 0) {
4203 i--;
4204 WindowState win = wtoken.windows.get(i);
4205 int j = win.mChildWindows.size();
4206 while (j > 0) {
4207 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004208 WindowState cwin = win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004209 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004210 for (int pos=NW-1; pos>=0; pos--) {
4211 if (mWindows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004212 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004213 "Found child win @" + (pos+1));
4214 return pos+1;
4215 }
4216 }
4217 }
4218 }
4219 for (int pos=NW-1; pos>=0; pos--) {
4220 if (mWindows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004221 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004222 return pos+1;
4223 }
4224 }
4225 }
4226 tokenPos--;
4227 }
4228
4229 return 0;
4230 }
4231
4232 private final int reAddWindowLocked(int index, WindowState win) {
4233 final int NCW = win.mChildWindows.size();
4234 boolean added = false;
4235 for (int j=0; j<NCW; j++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004236 WindowState cwin = win.mChildWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004237 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004238 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004239 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004240 win.mRebuilding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004241 mWindows.add(index, win);
4242 index++;
4243 added = true;
4244 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004245 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004246 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004247 cwin.mRebuilding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004248 mWindows.add(index, cwin);
4249 index++;
4250 }
4251 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004252 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004253 + index + ": " + win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004254 win.mRebuilding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004255 mWindows.add(index, win);
4256 index++;
4257 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004258 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004259 return index;
4260 }
Romain Guy06882f82009-06-10 13:36:04 -07004261
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004262 private final int reAddAppWindowsLocked(int index, WindowToken token) {
4263 final int NW = token.windows.size();
4264 for (int i=0; i<NW; i++) {
4265 index = reAddWindowLocked(index, token.windows.get(i));
4266 }
4267 return index;
4268 }
4269
4270 public void moveAppToken(int index, IBinder token) {
4271 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4272 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004273 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004274 }
4275
4276 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004277 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004278 if (DEBUG_REORDER) dumpAppTokensLocked();
4279 final AppWindowToken wtoken = findAppWindowToken(token);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004280 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
4281 "Start moving token " + wtoken + " initially at "
4282 + mAppTokens.indexOf(wtoken));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004283 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004284 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004285 + token + " (" + wtoken + ")");
4286 return;
4287 }
4288 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004289 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004290 else if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "Moved " + token + " to " + index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004291 if (DEBUG_REORDER) dumpAppTokensLocked();
Romain Guy06882f82009-06-10 13:36:04 -07004292
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004293 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004294 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004295 if (DEBUG_REORDER) dumpWindowsLocked();
4296 if (tmpRemoveAppWindowsLocked(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004297 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004298 if (DEBUG_REORDER) dumpWindowsLocked();
4299 reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004300 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004301 if (DEBUG_REORDER) dumpWindowsLocked();
Jeff Brown3a22cd92011-01-21 13:59:04 -08004302 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4303 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004304 mLayoutNeeded = true;
Jeff Brown2e44b072011-01-24 15:21:56 -08004305 mInputMonitor.setUpdateInputWindowsNeededLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004306 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08004307 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004308 }
4309 Binder.restoreCallingIdentity(origId);
4310 }
4311 }
4312
4313 private void removeAppTokensLocked(List<IBinder> tokens) {
4314 // XXX This should be done more efficiently!
4315 // (take advantage of the fact that both lists should be
4316 // ordered in the same way.)
4317 int N = tokens.size();
4318 for (int i=0; i<N; i++) {
4319 IBinder token = tokens.get(i);
4320 final AppWindowToken wtoken = findAppWindowToken(token);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004321 if (DEBUG_REORDER || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4322 "Temporarily removing " + wtoken + " from " + mAppTokens.indexOf(wtoken));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004323 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004324 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004325 + token + " (" + wtoken + ")");
4326 i--;
4327 N--;
4328 }
4329 }
4330 }
4331
Dianne Hackborna8f60182009-09-01 19:01:50 -07004332 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
4333 boolean updateFocusAndLayout) {
4334 // First remove all of the windows from the list.
4335 tmpRemoveAppWindowsLocked(wtoken);
4336
4337 // Where to start adding?
4338 int pos = findWindowOffsetLocked(tokenPos);
4339
4340 // And now add them back at the correct place.
4341 pos = reAddAppWindowsLocked(pos, wtoken);
4342
4343 if (updateFocusAndLayout) {
Jeff Brown2e44b072011-01-24 15:21:56 -08004344 mInputMonitor.setUpdateInputWindowsNeededLw();
Jeff Brown3a22cd92011-01-21 13:59:04 -08004345 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4346 false /*updateInputWindows*/)) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004347 assignLayersLocked();
4348 }
4349 mLayoutNeeded = true;
4350 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08004351 mInputMonitor.updateInputWindowsLw(false /*force*/);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004352 }
4353 }
4354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004355 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
4356 // First remove all of the windows from the list.
4357 final int N = tokens.size();
4358 int i;
4359 for (i=0; i<N; i++) {
4360 WindowToken token = mTokenMap.get(tokens.get(i));
4361 if (token != null) {
4362 tmpRemoveAppWindowsLocked(token);
4363 }
4364 }
4365
4366 // Where to start adding?
4367 int pos = findWindowOffsetLocked(tokenPos);
4368
4369 // And now add them back at the correct place.
4370 for (i=0; i<N; i++) {
4371 WindowToken token = mTokenMap.get(tokens.get(i));
4372 if (token != null) {
4373 pos = reAddAppWindowsLocked(pos, token);
4374 }
4375 }
4376
Jeff Brown2e44b072011-01-24 15:21:56 -08004377 mInputMonitor.setUpdateInputWindowsNeededLw();
Jeff Brown3a22cd92011-01-21 13:59:04 -08004378 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4379 false /*updateInputWindows*/)) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004380 assignLayersLocked();
4381 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004382 mLayoutNeeded = true;
4383 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08004384 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004385
4386 //dump();
4387 }
4388
4389 public void moveAppTokensToTop(List<IBinder> tokens) {
4390 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4391 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004392 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004393 }
4394
4395 final long origId = Binder.clearCallingIdentity();
4396 synchronized(mWindowMap) {
4397 removeAppTokensLocked(tokens);
4398 final int N = tokens.size();
4399 for (int i=0; i<N; i++) {
4400 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4401 if (wt != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004402 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
4403 "Adding next to top: " + wt);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004404 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004405 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004406 mToTopApps.remove(wt);
4407 mToBottomApps.remove(wt);
4408 mToTopApps.add(wt);
4409 wt.sendingToBottom = false;
4410 wt.sendingToTop = true;
4411 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004412 }
4413 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004414
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004415 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004416 moveAppWindowsLocked(tokens, mAppTokens.size());
4417 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004418 }
4419 Binder.restoreCallingIdentity(origId);
4420 }
4421
4422 public void moveAppTokensToBottom(List<IBinder> tokens) {
4423 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4424 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004425 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004426 }
4427
4428 final long origId = Binder.clearCallingIdentity();
4429 synchronized(mWindowMap) {
4430 removeAppTokensLocked(tokens);
4431 final int N = tokens.size();
4432 int pos = 0;
4433 for (int i=0; i<N; i++) {
4434 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4435 if (wt != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004436 if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4437 "Adding next to bottom: " + wt + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004438 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004439 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004440 mToTopApps.remove(wt);
4441 mToBottomApps.remove(wt);
4442 mToBottomApps.add(i, wt);
4443 wt.sendingToTop = false;
4444 wt.sendingToBottom = true;
4445 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004446 pos++;
4447 }
4448 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004449
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004450 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004451 moveAppWindowsLocked(tokens, 0);
4452 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004453 }
4454 Binder.restoreCallingIdentity(origId);
4455 }
4456
4457 // -------------------------------------------------------------
4458 // Misc IWindowSession methods
4459 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004460
Jim Miller284b62e2010-06-08 14:27:42 -07004461 private boolean shouldAllowDisableKeyguard()
Jim Millerd6b57052010-06-07 17:52:42 -07004462 {
Jim Miller284b62e2010-06-08 14:27:42 -07004463 // We fail safe and prevent disabling keyguard in the unlikely event this gets
4464 // called before DevicePolicyManagerService has started.
4465 if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
4466 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
4467 Context.DEVICE_POLICY_SERVICE);
4468 if (dpm != null) {
4469 mAllowDisableKeyguard = dpm.getPasswordQuality(null)
4470 == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
4471 ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
4472 }
Jim Millerd6b57052010-06-07 17:52:42 -07004473 }
Jim Miller284b62e2010-06-08 14:27:42 -07004474 return mAllowDisableKeyguard == ALLOW_DISABLE_YES;
Jim Millerd6b57052010-06-07 17:52:42 -07004475 }
4476
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004477 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004478 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004479 != PackageManager.PERMISSION_GRANTED) {
4480 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4481 }
Jim Millerd6b57052010-06-07 17:52:42 -07004482
Jim Miller284b62e2010-06-08 14:27:42 -07004483 synchronized (mKeyguardTokenWatcher) {
4484 mKeyguardTokenWatcher.acquire(token, tag);
Mike Lockwooddd884682009-10-11 16:57:08 -04004485 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004486 }
4487
4488 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004489 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004490 != PackageManager.PERMISSION_GRANTED) {
4491 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4492 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004493
Jim Miller284b62e2010-06-08 14:27:42 -07004494 synchronized (mKeyguardTokenWatcher) {
4495 mKeyguardTokenWatcher.release(token);
Jim Millerd6b57052010-06-07 17:52:42 -07004496
Jim Miller284b62e2010-06-08 14:27:42 -07004497 if (!mKeyguardTokenWatcher.isAcquired()) {
4498 // If we are the last one to reenable the keyguard wait until
4499 // we have actually finished reenabling until returning.
4500 // It is possible that reenableKeyguard() can be called before
4501 // the previous disableKeyguard() is handled, in which case
4502 // neither mKeyguardTokenWatcher.acquired() or released() would
4503 // be called. In that case mKeyguardDisabled will be false here
4504 // and we have nothing to wait for.
4505 while (mKeyguardDisabled) {
4506 try {
4507 mKeyguardTokenWatcher.wait();
4508 } catch (InterruptedException e) {
4509 Thread.currentThread().interrupt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004510 }
4511 }
4512 }
4513 }
4514 }
4515
4516 /**
4517 * @see android.app.KeyguardManager#exitKeyguardSecurely
4518 */
4519 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004520 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004521 != PackageManager.PERMISSION_GRANTED) {
4522 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4523 }
4524 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
4525 public void onKeyguardExitResult(boolean success) {
4526 try {
4527 callback.onKeyguardExitResult(success);
4528 } catch (RemoteException e) {
4529 // Client has died, we don't care.
4530 }
4531 }
4532 });
4533 }
4534
4535 public boolean inKeyguardRestrictedInputMode() {
4536 return mPolicy.inKeyguardRestrictedKeyInputMode();
4537 }
Romain Guy06882f82009-06-10 13:36:04 -07004538
Mike Lockwood520d8bc2011-02-18 13:23:13 -05004539 public boolean isKeyguardLocked() {
4540 return mPolicy.isKeyguardLocked();
4541 }
4542
4543 public boolean isKeyguardSecure() {
4544 return mPolicy.isKeyguardSecure();
4545 }
4546
Dianne Hackborn90c52de2011-09-23 12:57:44 -07004547 public void dismissKeyguard() {
4548 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
4549 != PackageManager.PERMISSION_GRANTED) {
4550 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4551 }
4552 synchronized(mWindowMap) {
4553 mPolicy.dismissKeyguardLw();
4554 }
4555 }
4556
Dianne Hackbornffa42482009-09-23 22:20:11 -07004557 public void closeSystemDialogs(String reason) {
4558 synchronized(mWindowMap) {
4559 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07004560 WindowState w = mWindows.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07004561 if (w.mSurface != null) {
4562 try {
4563 w.mClient.closeSystemDialogs(reason);
4564 } catch (RemoteException e) {
4565 }
4566 }
4567 }
4568 }
4569 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004570
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004571 static float fixScale(float scale) {
4572 if (scale < 0) scale = 0;
4573 else if (scale > 20) scale = 20;
4574 return Math.abs(scale);
4575 }
Romain Guy06882f82009-06-10 13:36:04 -07004576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004577 public void setAnimationScale(int which, float scale) {
4578 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4579 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004580 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004581 }
4582
4583 if (scale < 0) scale = 0;
4584 else if (scale > 20) scale = 20;
4585 scale = Math.abs(scale);
4586 switch (which) {
4587 case 0: mWindowAnimationScale = fixScale(scale); break;
4588 case 1: mTransitionAnimationScale = fixScale(scale); break;
4589 }
Romain Guy06882f82009-06-10 13:36:04 -07004590
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004591 // Persist setting
4592 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4593 }
Romain Guy06882f82009-06-10 13:36:04 -07004594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004595 public void setAnimationScales(float[] scales) {
4596 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4597 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004598 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004599 }
4600
4601 if (scales != null) {
4602 if (scales.length >= 1) {
4603 mWindowAnimationScale = fixScale(scales[0]);
4604 }
4605 if (scales.length >= 2) {
4606 mTransitionAnimationScale = fixScale(scales[1]);
4607 }
4608 }
Romain Guy06882f82009-06-10 13:36:04 -07004609
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004610 // Persist setting
4611 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4612 }
Romain Guy06882f82009-06-10 13:36:04 -07004613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004614 public float getAnimationScale(int which) {
4615 switch (which) {
4616 case 0: return mWindowAnimationScale;
4617 case 1: return mTransitionAnimationScale;
4618 }
4619 return 0;
4620 }
Romain Guy06882f82009-06-10 13:36:04 -07004621
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004622 public float[] getAnimationScales() {
4623 return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
4624 }
Romain Guy06882f82009-06-10 13:36:04 -07004625
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004626 public int getSwitchState(int sw) {
4627 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4628 "getSwitchState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004629 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004630 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004631 return mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004632 }
Romain Guy06882f82009-06-10 13:36:04 -07004633
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004634 public int getSwitchStateForDevice(int devid, int sw) {
4635 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4636 "getSwitchStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004637 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004638 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004639 return mInputManager.getSwitchState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004640 }
Romain Guy06882f82009-06-10 13:36:04 -07004641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004642 public int getScancodeState(int sw) {
4643 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4644 "getScancodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004645 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004646 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004647 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004648 }
Romain Guy06882f82009-06-10 13:36:04 -07004649
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004650 public int getScancodeStateForDevice(int devid, int sw) {
4651 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4652 "getScancodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004653 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004654 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004655 return mInputManager.getScanCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004656 }
Romain Guy06882f82009-06-10 13:36:04 -07004657
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004658 public int getTrackballScancodeState(int sw) {
4659 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4660 "getTrackballScancodeState()")) {
4661 throw new SecurityException("Requires READ_INPUT_STATE permission");
4662 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004663 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004664 }
4665
4666 public int getDPadScancodeState(int sw) {
4667 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4668 "getDPadScancodeState()")) {
4669 throw new SecurityException("Requires READ_INPUT_STATE permission");
4670 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004671 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004672 }
4673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004674 public int getKeycodeState(int sw) {
4675 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4676 "getKeycodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004677 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004678 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004679 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004680 }
Romain Guy06882f82009-06-10 13:36:04 -07004681
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004682 public int getKeycodeStateForDevice(int devid, int sw) {
4683 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4684 "getKeycodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004685 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004686 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004687 return mInputManager.getKeyCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004688 }
Romain Guy06882f82009-06-10 13:36:04 -07004689
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004690 public int getTrackballKeycodeState(int sw) {
4691 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4692 "getTrackballKeycodeState()")) {
4693 throw new SecurityException("Requires READ_INPUT_STATE permission");
4694 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004695 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004696 }
4697
4698 public int getDPadKeycodeState(int sw) {
4699 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4700 "getDPadKeycodeState()")) {
4701 throw new SecurityException("Requires READ_INPUT_STATE permission");
4702 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004703 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004704 }
Jeff Browna41ca772010-08-11 14:46:32 -07004705
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004706 public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
Jeff Brown6d0fec22010-07-23 21:28:06 -07004707 return mInputManager.hasKeys(-1, InputDevice.SOURCE_ANY, keycodes, keyExists);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004708 }
Romain Guy06882f82009-06-10 13:36:04 -07004709
Jeff Browna41ca772010-08-11 14:46:32 -07004710 public InputChannel monitorInput(String inputChannelName) {
4711 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4712 "monitorInput()")) {
4713 throw new SecurityException("Requires READ_INPUT_STATE permission");
4714 }
4715 return mInputManager.monitorInput(inputChannelName);
4716 }
4717
Jeff Brown0029c662011-03-30 02:25:18 -07004718 public void setInputFilter(InputFilter filter) {
4719 mInputManager.setInputFilter(filter);
4720 }
4721
Jeff Brown8d608662010-08-30 03:02:23 -07004722 public InputDevice getInputDevice(int deviceId) {
4723 return mInputManager.getInputDevice(deviceId);
4724 }
4725
4726 public int[] getInputDeviceIds() {
4727 return mInputManager.getInputDeviceIds();
4728 }
4729
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004730 public void enableScreenAfterBoot() {
4731 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07004732 if (DEBUG_BOOT) {
4733 RuntimeException here = new RuntimeException("here");
4734 here.fillInStackTrace();
4735 Slog.i(TAG, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled
4736 + " mForceDisplayEnabled=" + mForceDisplayEnabled
4737 + " mShowingBootMessages=" + mShowingBootMessages
4738 + " mSystemBooted=" + mSystemBooted, here);
4739 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004740 if (mSystemBooted) {
4741 return;
4742 }
4743 mSystemBooted = true;
Dianne Hackborn661cd522011-08-22 00:26:20 -07004744 hideBootMessagesLocked();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07004745 // If the screen still doesn't come up after 30 seconds, give
4746 // up and turn it on.
4747 Message msg = mH.obtainMessage(H.BOOT_TIMEOUT);
4748 mH.sendMessageDelayed(msg, 30*1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004749 }
Romain Guy06882f82009-06-10 13:36:04 -07004750
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07004751 mPolicy.systemBooted();
4752
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004753 performEnableScreen();
4754 }
Romain Guy06882f82009-06-10 13:36:04 -07004755
Dianne Hackborn661cd522011-08-22 00:26:20 -07004756 void enableScreenIfNeededLocked() {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07004757 if (DEBUG_BOOT) {
4758 RuntimeException here = new RuntimeException("here");
4759 here.fillInStackTrace();
4760 Slog.i(TAG, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled
4761 + " mForceDisplayEnabled=" + mForceDisplayEnabled
4762 + " mShowingBootMessages=" + mShowingBootMessages
4763 + " mSystemBooted=" + mSystemBooted, here);
4764 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004765 if (mDisplayEnabled) {
4766 return;
4767 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07004768 if (!mSystemBooted && !mShowingBootMessages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004769 return;
4770 }
4771 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
4772 }
Romain Guy06882f82009-06-10 13:36:04 -07004773
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07004774 public void performBootTimeout() {
4775 synchronized(mWindowMap) {
4776 if (mDisplayEnabled) {
4777 return;
4778 }
4779 Slog.w(TAG, "***** BOOT TIMEOUT: forcing display enabled");
4780 mForceDisplayEnabled = true;
4781 }
4782 performEnableScreen();
4783 }
4784
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004785 public void performEnableScreen() {
4786 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07004787 if (DEBUG_BOOT) {
4788 RuntimeException here = new RuntimeException("here");
4789 here.fillInStackTrace();
4790 Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
4791 + " mForceDisplayEnabled=" + mForceDisplayEnabled
4792 + " mShowingBootMessages=" + mShowingBootMessages
4793 + " mSystemBooted=" + mSystemBooted, here);
4794 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004795 if (mDisplayEnabled) {
4796 return;
4797 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07004798 if (!mSystemBooted && !mShowingBootMessages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004799 return;
4800 }
Romain Guy06882f82009-06-10 13:36:04 -07004801
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07004802 if (!mForceDisplayEnabled) {
4803 // Don't enable the screen until all existing windows
4804 // have been drawn.
4805 boolean haveBootMsg = false;
4806 boolean haveApp = false;
4807 boolean haveWallpaper = false;
Dianne Hackborn38cc8962011-10-13 11:33:55 -07004808 boolean haveKeyguard = true;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07004809 final int N = mWindows.size();
4810 for (int i=0; i<N; i++) {
4811 WindowState w = mWindows.get(i);
Dianne Hackborn38cc8962011-10-13 11:33:55 -07004812 if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD) {
4813 // Only if there is a keyguard attached to the window manager
4814 // will we consider ourselves as having a keyguard. If it
4815 // isn't attached, we don't know if it wants to be shown or
4816 // hidden. If it is attached, we will say we have a keyguard
4817 // if the window doesn't want to be visible, because in that
4818 // case it explicitly doesn't want to be shown so we should
4819 // not delay turning the screen on for it.
4820 boolean vis = w.mViewVisibility == View.VISIBLE
4821 && w.mPolicyVisibility;
4822 haveKeyguard = !vis;
4823 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07004824 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
4825 return;
4826 }
4827 if (w.isDrawnLw()) {
4828 if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_BOOT_PROGRESS) {
4829 haveBootMsg = true;
4830 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION) {
4831 haveApp = true;
4832 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER) {
4833 haveWallpaper = true;
4834 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD) {
4835 haveKeyguard = true;
4836 }
4837 }
4838 }
4839
Dianne Hackborn38cc8962011-10-13 11:33:55 -07004840 if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07004841 Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
4842 + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
4843 + " haveWall=" + haveWallpaper + " haveKeyguard=" + haveKeyguard);
4844 }
4845
4846 // If we are turning on the screen to show the boot message,
4847 // don't do it until the boot message is actually displayed.
4848 if (!mSystemBooted && !haveBootMsg) {
4849 return;
4850 }
4851
4852 // If we are turning on the screen after the boot is completed
4853 // normally, don't do so until we have the application and
4854 // wallpaper.
4855 if (mSystemBooted && ((!haveApp && !haveKeyguard) || !haveWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004856 return;
4857 }
4858 }
Romain Guy06882f82009-06-10 13:36:04 -07004859
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004860 mDisplayEnabled = true;
Dianne Hackborn38cc8962011-10-13 11:33:55 -07004861 if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004862 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004863 StringWriter sw = new StringWriter();
4864 PrintWriter pw = new PrintWriter(sw);
4865 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004866 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004867 }
4868 try {
4869 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
4870 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004871 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004872 Parcel data = Parcel.obtain();
4873 data.writeInterfaceToken("android.ui.ISurfaceComposer");
4874 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
4875 data, null, 0);
4876 data.recycle();
4877 }
4878 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004879 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004880 }
4881 }
Romain Guy06882f82009-06-10 13:36:04 -07004882
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004883 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07004884
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004885 // Make sure the last requested orientation has been applied.
Jeff Brown01a98dd2011-09-20 15:08:29 -07004886 updateRotationUnchecked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004887 }
Romain Guy06882f82009-06-10 13:36:04 -07004888
Dianne Hackborn661cd522011-08-22 00:26:20 -07004889 public void showBootMessage(final CharSequence msg, final boolean always) {
4890 boolean first = false;
4891 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07004892 if (DEBUG_BOOT) {
4893 RuntimeException here = new RuntimeException("here");
4894 here.fillInStackTrace();
4895 Slog.i(TAG, "showBootMessage: msg=" + msg + " always=" + always
4896 + " mAllowBootMessages=" + mAllowBootMessages
4897 + " mShowingBootMessages=" + mShowingBootMessages
4898 + " mSystemBooted=" + mSystemBooted, here);
4899 }
Dianne Hackborn58f42a52011-10-10 13:46:34 -07004900 if (!mAllowBootMessages) {
4901 return;
4902 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07004903 if (!mShowingBootMessages) {
4904 if (!always) {
4905 return;
4906 }
4907 first = true;
4908 }
4909 if (mSystemBooted) {
4910 return;
4911 }
4912 mShowingBootMessages = true;
4913 mPolicy.showBootMessage(msg, always);
4914 }
4915 if (first) {
4916 performEnableScreen();
4917 }
4918 }
4919
4920 public void hideBootMessagesLocked() {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07004921 if (DEBUG_BOOT) {
4922 RuntimeException here = new RuntimeException("here");
4923 here.fillInStackTrace();
4924 Slog.i(TAG, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled
4925 + " mForceDisplayEnabled=" + mForceDisplayEnabled
4926 + " mShowingBootMessages=" + mShowingBootMessages
4927 + " mSystemBooted=" + mSystemBooted, here);
4928 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07004929 if (mShowingBootMessages) {
4930 mShowingBootMessages = false;
4931 mPolicy.hideBootMessages();
4932 }
4933 }
4934
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004935 public void setInTouchMode(boolean mode) {
4936 synchronized(mWindowMap) {
4937 mInTouchMode = mode;
4938 }
4939 }
4940
Brad Fitzpatrick68044332010-11-22 18:19:48 -08004941 // TODO: more accounting of which pid(s) turned it on, keep count,
4942 // only allow disables from pids which have count on, etc.
4943 public void showStrictModeViolation(boolean on) {
4944 int pid = Binder.getCallingPid();
4945 synchronized(mWindowMap) {
4946 // Ignoring requests to enable the red border from clients
4947 // which aren't on screen. (e.g. Broadcast Receivers in
4948 // the background..)
4949 if (on) {
4950 boolean isVisible = false;
4951 for (WindowState ws : mWindows) {
4952 if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
4953 isVisible = true;
4954 break;
4955 }
4956 }
4957 if (!isVisible) {
4958 return;
4959 }
4960 }
4961
Dianne Hackborn36991742011-10-11 21:35:26 -07004962 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
4963 ">>> OPEN TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08004964 Surface.openTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08004965 try {
4966 if (mStrictModeFlash == null) {
4967 mStrictModeFlash = new StrictModeFlash(mDisplay, mFxSession);
4968 }
4969 mStrictModeFlash.setVisibility(on);
4970 } finally {
4971 Surface.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -07004972 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
4973 "<<< CLOSE TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08004974 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08004975 }
4976 }
4977
Brad Fitzpatrickc1a968a2010-11-24 08:56:40 -08004978 public void setStrictModeVisualIndicatorPreference(String value) {
4979 SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
4980 }
4981
Jim Millere70d5062011-03-08 21:38:39 -08004982 /**
4983 * Takes a snapshot of the screen. In landscape mode this grabs the whole screen.
4984 * In portrait mode, it grabs the upper region of the screen based on the vertical dimension
4985 * of the target image.
4986 *
4987 * @param width the width of the target bitmap
4988 * @param height the height of the target bitmap
4989 */
4990 public Bitmap screenshotApplications(IBinder appToken, int width, int height) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004991 if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
4992 "screenshotApplications()")) {
4993 throw new SecurityException("Requires READ_FRAME_BUFFER permission");
4994 }
4995
4996 Bitmap rawss;
4997
Dianne Hackbornd2835932010-12-13 16:28:46 -08004998 int maxLayer = 0;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004999 final Rect frame = new Rect();
5000
5001 float scale;
Jim Millere70d5062011-03-08 21:38:39 -08005002 int dw, dh;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005003 int rot;
5004
5005 synchronized(mWindowMap) {
5006 long ident = Binder.clearCallingIdentity();
5007
Dianne Hackborn81e56d52011-05-26 00:55:58 -07005008 dw = mAppDisplayWidth;
5009 dh = mAppDisplayHeight;
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005010
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005011 int aboveAppLayer = mPolicy.windowTypeToLayerLw(
5012 WindowManager.LayoutParams.TYPE_APPLICATION) * TYPE_LAYER_MULTIPLIER
5013 + TYPE_LAYER_OFFSET;
5014 aboveAppLayer += TYPE_LAYER_MULTIPLIER;
5015
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005016 boolean isImeTarget = mInputMethodTarget != null
5017 && mInputMethodTarget.mAppToken != null
5018 && mInputMethodTarget.mAppToken.appToken != null
5019 && mInputMethodTarget.mAppToken.appToken.asBinder() == appToken;
5020
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005021 // Figure out the part of the screen that is actually the app.
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005022 boolean including = false;
5023 for (int i=mWindows.size()-1; i>=0; i--) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005024 WindowState ws = mWindows.get(i);
5025 if (ws.mSurface == null) {
5026 continue;
5027 }
5028 if (ws.mLayer >= aboveAppLayer) {
Dianne Hackbornd2835932010-12-13 16:28:46 -08005029 continue;
5030 }
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005031 // When we will skip windows: when we are not including
5032 // ones behind a window we didn't skip, and we are actually
5033 // taking a screenshot of a specific app.
5034 if (!including && appToken != null) {
5035 // Also, we can possibly skip this window if it is not
5036 // an IME target or the application for the screenshot
5037 // is not the current IME target.
5038 if (!ws.mIsImWindow || !isImeTarget) {
5039 // And finally, this window is of no interest if it
5040 // is not associated with the screenshot app.
5041 if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
5042 continue;
5043 }
5044 }
5045 }
5046
5047 // We keep on including windows until we go past a full-screen
5048 // window.
5049 including = !ws.mIsImWindow && !ws.isFullscreen(dw, dh);
5050
Dianne Hackbornd2835932010-12-13 16:28:46 -08005051 if (maxLayer < ws.mAnimLayer) {
5052 maxLayer = ws.mAnimLayer;
5053 }
Jim Miller2aded182011-03-08 15:32:42 -08005054
5055 // Don't include wallpaper in bounds calculation
5056 if (!ws.mIsWallpaper) {
Dianne Hackbornffb3d932011-05-17 17:44:51 -07005057 final Rect wf = ws.mFrame;
Jim Miller2aded182011-03-08 15:32:42 -08005058 final Rect cr = ws.mContentInsets;
5059 int left = wf.left + cr.left;
5060 int top = wf.top + cr.top;
5061 int right = wf.right - cr.right;
5062 int bottom = wf.bottom - cr.bottom;
5063 frame.union(left, top, right, bottom);
5064 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005065 }
5066 Binder.restoreCallingIdentity(ident);
5067
Dianne Hackborndd962ee2011-02-02 11:11:50 -08005068 // Constrain frame to the screen size.
5069 frame.intersect(0, 0, dw, dh);
Jim Millere70d5062011-03-08 21:38:39 -08005070
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005071 if (frame.isEmpty() || maxLayer == 0) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005072 return null;
5073 }
5074
5075 // The screenshot API does not apply the current screen rotation.
5076 rot = mDisplay.getRotation();
5077 int fw = frame.width();
5078 int fh = frame.height();
5079
Jim Miller28637ba2011-07-06 19:57:05 -07005080 // Constrain thumbnail to smaller of screen width or height. Assumes aspect
5081 // of thumbnail is the same as the screen (in landscape) or square.
5082 if (dw <= dh) {
5083 scale = width / (float) fw; // portrait
5084 } else {
5085 scale = height / (float) fh; // landscape
5086 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005087
5088 // The screen shot will contain the entire screen.
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005089 dw = (int)(dw*scale);
5090 dh = (int)(dh*scale);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005091 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
5092 int tmp = dw;
5093 dw = dh;
5094 dh = tmp;
5095 rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
5096 }
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -07005097 if (DEBUG_SCREENSHOT) {
5098 Slog.i(TAG, "Screenshot: " + dw + "x" + dh + " from 0 to " + maxLayer);
5099 for (int i=0; i<mWindows.size(); i++) {
5100 Slog.i(TAG, mWindows.get(i) + ": " + mWindows.get(i).mLayer
5101 + " animLayer=" + mWindows.get(i).mAnimLayer
5102 + " surfaceLayer=" + mWindows.get(i).mSurfaceLayer);
5103 }
5104 }
Dianne Hackbornd2835932010-12-13 16:28:46 -08005105 rawss = Surface.screenshot(dw, dh, 0, maxLayer);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005106 }
5107
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005108 if (rawss == null) {
Dianne Hackborn88b03bd2010-12-16 11:15:18 -08005109 Log.w(TAG, "Failure taking screenshot for (" + dw + "x" + dh
5110 + ") to layer " + maxLayer);
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005111 return null;
5112 }
Jim Millere70d5062011-03-08 21:38:39 -08005113
5114 Bitmap bm = Bitmap.createBitmap(width, height, rawss.getConfig());
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005115 Matrix matrix = new Matrix();
5116 ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
5117 matrix.postTranslate(-(int)(frame.left*scale), -(int)(frame.top*scale));
5118 Canvas canvas = new Canvas(bm);
5119 canvas.drawBitmap(rawss, matrix, null);
Dianne Hackborn6311d0a2011-08-02 16:37:58 -07005120 canvas.setBitmap(null);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005121
5122 rawss.recycle();
5123 return bm;
5124 }
5125
Jeff Brown01a98dd2011-09-20 15:08:29 -07005126 /**
5127 * Freeze rotation changes. (Enable "rotation lock".)
5128 * Persists across reboots.
Jeff Brown4dfce202011-10-05 12:00:10 -07005129 * @param rotation The desired rotation to freeze to, or -1 to use the
5130 * current rotation.
Jeff Brown01a98dd2011-09-20 15:08:29 -07005131 */
Jeff Brown4dfce202011-10-05 12:00:10 -07005132 public void freezeRotation(int rotation) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005133 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005134 "freezeRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005135 throw new SecurityException("Requires SET_ORIENTATION permission");
5136 }
Jeff Brown4dfce202011-10-05 12:00:10 -07005137 if (rotation < -1 || rotation > Surface.ROTATION_270) {
5138 throw new IllegalArgumentException("Rotation argument must be -1 or a valid "
5139 + "rotation constant.");
5140 }
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005141
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005142 if (DEBUG_ORIENTATION) Slog.v(TAG, "freezeRotation: mRotation=" + mRotation);
5143
Jeff Brown4dfce202011-10-05 12:00:10 -07005144 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED,
5145 rotation == -1 ? mRotation : rotation);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005146 updateRotationUnchecked(false);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005147 }
5148
Jeff Brown01a98dd2011-09-20 15:08:29 -07005149 /**
5150 * Thaw rotation changes. (Disable "rotation lock".)
5151 * Persists across reboots.
5152 */
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005153 public void thawRotation() {
5154 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005155 "thawRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005156 throw new SecurityException("Requires SET_ORIENTATION permission");
5157 }
5158
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005159 if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation);
5160
5161 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 777); // rot not used
Jeff Brown01a98dd2011-09-20 15:08:29 -07005162 updateRotationUnchecked(false);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005163 }
5164
Jeff Brown01a98dd2011-09-20 15:08:29 -07005165 /**
5166 * Recalculate the current rotation.
5167 *
5168 * Called by the window manager policy whenever the state of the system changes
5169 * such that the current rotation might need to be updated, such as when the
5170 * device is docked or rotated into a new posture.
5171 */
5172 public void updateRotation(boolean alwaysSendConfiguration) {
5173 updateRotationUnchecked(alwaysSendConfiguration);
5174 }
5175
5176 /**
5177 * Temporarily pauses rotation changes until resumed.
5178 *
5179 * This can be used to prevent rotation changes from occurring while the user is
5180 * performing certain operations, such as drag and drop.
5181 *
5182 * This call nests and must be matched by an equal number of calls to {@link #resumeRotation}.
5183 */
5184 void pauseRotationLocked() {
5185 mDeferredRotationPauseCount += 1;
5186 }
5187
5188 /**
5189 * Resumes normal rotation changes after being paused.
5190 */
5191 void resumeRotationLocked() {
5192 if (mDeferredRotationPauseCount > 0) {
5193 mDeferredRotationPauseCount -= 1;
5194 if (mDeferredRotationPauseCount == 0) {
5195 boolean changed = updateRotationUncheckedLocked(false);
5196 if (changed) {
5197 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
5198 }
5199 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005200 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005201 }
Romain Guy06882f82009-06-10 13:36:04 -07005202
Jeff Brown01a98dd2011-09-20 15:08:29 -07005203 public void updateRotationUnchecked(
5204 boolean alwaysSendConfiguration) {
5205 if(DEBUG_ORIENTATION) Slog.v(TAG, "updateRotationUnchecked("
5206 + "alwaysSendConfiguration=" + alwaysSendConfiguration + ")");
Romain Guy06882f82009-06-10 13:36:04 -07005207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005208 long origId = Binder.clearCallingIdentity();
5209 boolean changed;
5210 synchronized(mWindowMap) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005211 changed = updateRotationUncheckedLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005212 }
Romain Guy06882f82009-06-10 13:36:04 -07005213
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005214 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005215 sendNewConfiguration();
5216 }
Romain Guy06882f82009-06-10 13:36:04 -07005217
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005218 Binder.restoreCallingIdentity(origId);
5219 }
Romain Guy06882f82009-06-10 13:36:04 -07005220
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005221 /**
Jeff Brown01a98dd2011-09-20 15:08:29 -07005222 * Updates the current rotation.
5223 *
5224 * Returns true if the rotation has been changed. In this case YOU
5225 * MUST CALL sendNewConfiguration() TO UNFREEZE THE SCREEN.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005226 */
Jeff Brown01a98dd2011-09-20 15:08:29 -07005227 public boolean updateRotationUncheckedLocked(boolean inTransaction) {
5228 if (mDeferredRotationPauseCount > 0) {
5229 // Rotation updates have been paused temporarily. Defer the update until
5230 // updates have been resumed.
5231 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, rotation is paused.");
Christopher Tateccd24de2011-01-12 15:02:55 -08005232 return false;
5233 }
5234
Jeff Brown01a98dd2011-09-20 15:08:29 -07005235 if (mScreenRotationAnimation != null && mScreenRotationAnimation.isAnimating()) {
5236 // Rotation updates cannot be performed while the previous rotation change
5237 // animation is still in progress. Skip this update. We will try updating
5238 // again after the animation is finished and the display is unfrozen.
5239 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, animation in progress.");
5240 return false;
5241 }
5242
5243 if (!mDisplayEnabled) {
5244 // No point choosing a rotation if the display is not enabled.
5245 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, display is not enabled.");
5246 return false;
5247 }
5248
5249 // TODO: Implement forced rotation changes.
5250 // Set mAltOrientation to indicate that the application is receiving
5251 // an orientation that has different metrics than it expected.
5252 // eg. Portrait instead of Landscape.
5253
5254 int rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, mRotation);
5255 boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
5256 mForcedAppOrientation, rotation);
5257
5258 if (DEBUG_ORIENTATION) {
5259 Slog.v(TAG, "Application requested orientation "
5260 + mForcedAppOrientation + ", got rotation " + rotation
5261 + " which has " + (altOrientation ? "incompatible" : "compatible")
5262 + " metrics");
5263 }
5264
5265 if (mRotation == rotation && mAltOrientation == altOrientation) {
5266 // No change.
5267 return false;
5268 }
5269
5270 if (DEBUG_ORIENTATION) {
5271 Slog.v(TAG,
5272 "Rotation changed to " + rotation + (altOrientation ? " (alt)" : "")
5273 + " from " + mRotation + (mAltOrientation ? " (alt)" : "")
5274 + ", forceApp=" + mForcedAppOrientation);
5275 }
5276
5277 mRotation = rotation;
5278 mAltOrientation = altOrientation;
Jeff Brownc0347aa2011-09-23 17:26:09 -07005279 mPolicy.setRotationLw(mRotation);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005280
5281 mWindowsFreezingScreen = true;
5282 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
5283 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT), 2000);
5284 mWaitingForConfig = true;
5285 mLayoutNeeded = true;
5286 startFreezingDisplayLocked(inTransaction);
5287 mInputManager.setDisplayOrientation(0, rotation);
5288
Jamie Gennise2909e12011-10-10 15:48:06 -07005289 if (!inTransaction) {
Dianne Hackborn36991742011-10-11 21:35:26 -07005290 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Jamie Gennise2909e12011-10-10 15:48:06 -07005291 ">>> OPEN TRANSACTION setRotationUnchecked");
5292 Surface.openTransaction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005293 }
Jamie Gennise2909e12011-10-10 15:48:06 -07005294 try {
5295 // NOTE: We disable the rotation in the emulator because
5296 // it doesn't support hardware OpenGL emulation yet.
5297 if (CUSTOM_SCREEN_ROTATION && mScreenRotationAnimation != null
5298 && mScreenRotationAnimation.hasScreenshot()) {
5299 mScreenRotationAnimation.setRotation(rotation);
5300 }
5301 Surface.setOrientation(0, rotation);
5302 } finally {
5303 if (!inTransaction) {
5304 Surface.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -07005305 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Jamie Gennise2909e12011-10-10 15:48:06 -07005306 "<<< CLOSE TRANSACTION setRotationUnchecked");
5307 }
5308 }
5309
Jeff Brown01a98dd2011-09-20 15:08:29 -07005310 rebuildBlackFrame(inTransaction);
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005311
Jeff Brown01a98dd2011-09-20 15:08:29 -07005312 for (int i=mWindows.size()-1; i>=0; i--) {
5313 WindowState w = mWindows.get(i);
5314 if (w.mSurface != null) {
5315 w.mOrientationChanging = true;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005316 }
5317 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07005318 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
5319 try {
5320 mRotationWatchers.get(i).onRotationChanged(rotation);
5321 } catch (RemoteException e) {
5322 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005323 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07005324 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005325 }
Romain Guy06882f82009-06-10 13:36:04 -07005326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005327 public int getRotation() {
5328 return mRotation;
5329 }
5330
5331 public int watchRotation(IRotationWatcher watcher) {
5332 final IBinder watcherBinder = watcher.asBinder();
5333 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
5334 public void binderDied() {
5335 synchronized (mWindowMap) {
5336 for (int i=0; i<mRotationWatchers.size(); i++) {
5337 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07005338 IRotationWatcher removed = mRotationWatchers.remove(i);
5339 if (removed != null) {
5340 removed.asBinder().unlinkToDeath(this, 0);
5341 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005342 i--;
5343 }
5344 }
5345 }
5346 }
5347 };
Romain Guy06882f82009-06-10 13:36:04 -07005348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005349 synchronized (mWindowMap) {
5350 try {
5351 watcher.asBinder().linkToDeath(dr, 0);
5352 mRotationWatchers.add(watcher);
5353 } catch (RemoteException e) {
5354 // Client died, no cleanup needed.
5355 }
Romain Guy06882f82009-06-10 13:36:04 -07005356
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005357 return mRotation;
5358 }
5359 }
5360
5361 /**
Adam Powelldfee59a2011-08-05 20:48:30 -07005362 * Apps that use the compact menu panel (as controlled by the panelMenuIsCompact
5363 * theme attribute) on devices that feature a physical options menu key attempt to position
5364 * their menu panel window along the edge of the screen nearest the physical menu key.
5365 * This lowers the travel distance between invoking the menu panel and selecting
5366 * a menu option.
5367 *
5368 * This method helps control where that menu is placed. Its current implementation makes
5369 * assumptions about the menu key and its relationship to the screen based on whether
5370 * the device's natural orientation is portrait (width < height) or landscape.
5371 *
5372 * The menu key is assumed to be located along the bottom edge of natural-portrait
5373 * devices and along the right edge of natural-landscape devices. If these assumptions
5374 * do not hold for the target device, this method should be changed to reflect that.
5375 *
5376 * @return A {@link Gravity} value for placing the options menu window
5377 */
5378 public int getPreferredOptionsPanelGravity() {
5379 synchronized (mWindowMap) {
5380 final int rotation = getRotation();
5381
5382 if (mInitialDisplayWidth < mInitialDisplayHeight) {
5383 // On devices with a natural orientation of portrait
5384 switch (rotation) {
5385 default:
5386 case Surface.ROTATION_0:
5387 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
5388 case Surface.ROTATION_90:
Adam Powell67ed6c72011-08-28 13:21:56 -07005389 return Gravity.RIGHT | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07005390 case Surface.ROTATION_180:
Adam Powell67ed6c72011-08-28 13:21:56 -07005391 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07005392 case Surface.ROTATION_270:
Adam Powell67ed6c72011-08-28 13:21:56 -07005393 return Gravity.LEFT | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07005394 }
5395 } else {
5396 // On devices with a natural orientation of landscape
5397 switch (rotation) {
5398 default:
5399 case Surface.ROTATION_0:
Adam Powell67ed6c72011-08-28 13:21:56 -07005400 return Gravity.RIGHT | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07005401 case Surface.ROTATION_90:
5402 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
5403 case Surface.ROTATION_180:
Adam Powell67ed6c72011-08-28 13:21:56 -07005404 return Gravity.LEFT | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07005405 case Surface.ROTATION_270:
Adam Powell67ed6c72011-08-28 13:21:56 -07005406 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07005407 }
5408 }
5409 }
5410 }
5411
5412 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005413 * Starts the view server on the specified port.
5414 *
5415 * @param port The port to listener to.
5416 *
5417 * @return True if the server was successfully started, false otherwise.
5418 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08005419 * @see com.android.server.wm.ViewServer
5420 * @see com.android.server.wm.ViewServer#VIEW_SERVER_DEFAULT_PORT
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005421 */
5422 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07005423 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005424 return false;
5425 }
5426
5427 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
5428 return false;
5429 }
5430
5431 if (port < 1024) {
5432 return false;
5433 }
5434
5435 if (mViewServer != null) {
5436 if (!mViewServer.isRunning()) {
5437 try {
5438 return mViewServer.start();
5439 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005440 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005441 }
5442 }
5443 return false;
5444 }
5445
5446 try {
5447 mViewServer = new ViewServer(this, port);
5448 return mViewServer.start();
5449 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005450 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005451 }
5452 return false;
5453 }
5454
Romain Guy06882f82009-06-10 13:36:04 -07005455 private boolean isSystemSecure() {
5456 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
5457 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5458 }
5459
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005460 /**
5461 * Stops the view server if it exists.
5462 *
5463 * @return True if the server stopped, false if it wasn't started or
5464 * couldn't be stopped.
5465 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08005466 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005467 */
5468 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07005469 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005470 return false;
5471 }
5472
5473 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
5474 return false;
5475 }
5476
5477 if (mViewServer != null) {
5478 return mViewServer.stop();
5479 }
5480 return false;
5481 }
5482
5483 /**
5484 * Indicates whether the view server is running.
5485 *
5486 * @return True if the server is running, false otherwise.
5487 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08005488 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005489 */
5490 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07005491 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005492 return false;
5493 }
5494
5495 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
5496 return false;
5497 }
5498
5499 return mViewServer != null && mViewServer.isRunning();
5500 }
5501
5502 /**
5503 * Lists all availble windows in the system. The listing is written in the
5504 * specified Socket's output stream with the following syntax:
5505 * windowHashCodeInHexadecimal windowName
5506 * Each line of the ouput represents a different window.
5507 *
5508 * @param client The remote client to send the listing to.
5509 * @return False if an error occured, true otherwise.
5510 */
5511 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07005512 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005513 return false;
5514 }
5515
5516 boolean result = true;
5517
Jeff Browne33348b2010-07-15 23:54:05 -07005518 WindowState[] windows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005519 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005520 //noinspection unchecked
Jeff Browne33348b2010-07-15 23:54:05 -07005521 windows = mWindows.toArray(new WindowState[mWindows.size()]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005522 }
5523
5524 BufferedWriter out = null;
5525
5526 // Any uncaught exception will crash the system process
5527 try {
5528 OutputStream clientStream = client.getOutputStream();
5529 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5530
5531 final int count = windows.length;
5532 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005533 final WindowState w = windows[i];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005534 out.write(Integer.toHexString(System.identityHashCode(w)));
5535 out.write(' ');
5536 out.append(w.mAttrs.getTitle());
5537 out.write('\n');
5538 }
5539
5540 out.write("DONE.\n");
5541 out.flush();
5542 } catch (Exception e) {
5543 result = false;
5544 } finally {
5545 if (out != null) {
5546 try {
5547 out.close();
5548 } catch (IOException e) {
5549 result = false;
5550 }
5551 }
5552 }
5553
5554 return result;
5555 }
5556
5557 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07005558 * Returns the focused window in the following format:
5559 * windowHashCodeInHexadecimal windowName
5560 *
5561 * @param client The remote client to send the listing to.
5562 * @return False if an error occurred, true otherwise.
5563 */
5564 boolean viewServerGetFocusedWindow(Socket client) {
5565 if (isSystemSecure()) {
5566 return false;
5567 }
5568
5569 boolean result = true;
5570
5571 WindowState focusedWindow = getFocusedWindow();
5572
5573 BufferedWriter out = null;
5574
5575 // Any uncaught exception will crash the system process
5576 try {
5577 OutputStream clientStream = client.getOutputStream();
5578 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5579
5580 if(focusedWindow != null) {
5581 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
5582 out.write(' ');
5583 out.append(focusedWindow.mAttrs.getTitle());
5584 }
5585 out.write('\n');
5586 out.flush();
5587 } catch (Exception e) {
5588 result = false;
5589 } finally {
5590 if (out != null) {
5591 try {
5592 out.close();
5593 } catch (IOException e) {
5594 result = false;
5595 }
5596 }
5597 }
5598
5599 return result;
5600 }
5601
5602 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005603 * Sends a command to a target window. The result of the command, if any, will be
5604 * written in the output stream of the specified socket.
5605 *
5606 * The parameters must follow this syntax:
5607 * windowHashcode extra
5608 *
5609 * Where XX is the length in characeters of the windowTitle.
5610 *
5611 * The first parameter is the target window. The window with the specified hashcode
5612 * will be the target. If no target can be found, nothing happens. The extra parameters
5613 * will be delivered to the target window and as parameters to the command itself.
5614 *
5615 * @param client The remote client to sent the result, if any, to.
5616 * @param command The command to execute.
5617 * @param parameters The command parameters.
5618 *
5619 * @return True if the command was successfully delivered, false otherwise. This does
5620 * not indicate whether the command itself was successful.
5621 */
5622 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07005623 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005624 return false;
5625 }
5626
5627 boolean success = true;
5628 Parcel data = null;
5629 Parcel reply = null;
5630
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005631 BufferedWriter out = null;
5632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005633 // Any uncaught exception will crash the system process
5634 try {
5635 // Find the hashcode of the window
5636 int index = parameters.indexOf(' ');
5637 if (index == -1) {
5638 index = parameters.length();
5639 }
5640 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08005641 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005642
5643 // Extract the command's parameter after the window description
5644 if (index < parameters.length()) {
5645 parameters = parameters.substring(index + 1);
5646 } else {
5647 parameters = "";
5648 }
5649
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08005650 final WindowState window = findWindow(hashCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005651 if (window == null) {
5652 return false;
5653 }
5654
5655 data = Parcel.obtain();
5656 data.writeInterfaceToken("android.view.IWindow");
5657 data.writeString(command);
5658 data.writeString(parameters);
5659 data.writeInt(1);
5660 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
5661
5662 reply = Parcel.obtain();
5663
5664 final IBinder binder = window.mClient.asBinder();
5665 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
5666 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
5667
5668 reply.readException();
5669
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005670 if (!client.isOutputShutdown()) {
5671 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
5672 out.write("DONE\n");
5673 out.flush();
5674 }
5675
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005676 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005677 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005678 success = false;
5679 } finally {
5680 if (data != null) {
5681 data.recycle();
5682 }
5683 if (reply != null) {
5684 reply.recycle();
5685 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005686 if (out != null) {
5687 try {
5688 out.close();
5689 } catch (IOException e) {
5690
5691 }
5692 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005693 }
5694
5695 return success;
5696 }
5697
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07005698 public void addWindowChangeListener(WindowChangeListener listener) {
5699 synchronized(mWindowMap) {
5700 mWindowChangeListeners.add(listener);
5701 }
5702 }
5703
5704 public void removeWindowChangeListener(WindowChangeListener listener) {
5705 synchronized(mWindowMap) {
5706 mWindowChangeListeners.remove(listener);
5707 }
5708 }
5709
5710 private void notifyWindowsChanged() {
5711 WindowChangeListener[] windowChangeListeners;
5712 synchronized(mWindowMap) {
5713 if(mWindowChangeListeners.isEmpty()) {
5714 return;
5715 }
5716 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5717 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5718 }
5719 int N = windowChangeListeners.length;
5720 for(int i = 0; i < N; i++) {
5721 windowChangeListeners[i].windowsChanged();
5722 }
5723 }
5724
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07005725 private void notifyFocusChanged() {
5726 WindowChangeListener[] windowChangeListeners;
5727 synchronized(mWindowMap) {
5728 if(mWindowChangeListeners.isEmpty()) {
5729 return;
5730 }
5731 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5732 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5733 }
5734 int N = windowChangeListeners.length;
5735 for(int i = 0; i < N; i++) {
5736 windowChangeListeners[i].focusChanged();
5737 }
5738 }
5739
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005740 private WindowState findWindow(int hashCode) {
5741 if (hashCode == -1) {
5742 return getFocusedWindow();
5743 }
5744
5745 synchronized (mWindowMap) {
Jeff Browne33348b2010-07-15 23:54:05 -07005746 final ArrayList<WindowState> windows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005747 final int count = windows.size();
5748
5749 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005750 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005751 if (System.identityHashCode(w) == hashCode) {
5752 return w;
5753 }
5754 }
5755 }
5756
5757 return null;
5758 }
5759
5760 /*
5761 * Instruct the Activity Manager to fetch the current configuration and broadcast
5762 * that to config-changed listeners if appropriate.
5763 */
5764 void sendNewConfiguration() {
5765 try {
5766 mActivityManager.updateConfiguration(null);
5767 } catch (RemoteException e) {
5768 }
5769 }
Romain Guy06882f82009-06-10 13:36:04 -07005770
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005771 public Configuration computeNewConfiguration() {
5772 synchronized (mWindowMap) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005773 Configuration config = computeNewConfigurationLocked();
5774 if (config == null && mWaitingForConfig) {
5775 // Nothing changed but we are waiting for something... stop that!
5776 mWaitingForConfig = false;
5777 performLayoutAndPlaceSurfacesLocked();
5778 }
5779 return config;
Dianne Hackbornc485a602009-03-24 22:39:49 -07005780 }
5781 }
Romain Guy06882f82009-06-10 13:36:04 -07005782
Dianne Hackbornc485a602009-03-24 22:39:49 -07005783 Configuration computeNewConfigurationLocked() {
5784 Configuration config = new Configuration();
Dianne Hackborn09e5b9d2011-10-04 16:32:01 -07005785 config.fontScale = 0;
Dianne Hackbornc485a602009-03-24 22:39:49 -07005786 if (!computeNewConfigurationLocked(config)) {
5787 return null;
5788 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07005789 return config;
5790 }
Romain Guy06882f82009-06-10 13:36:04 -07005791
Dianne Hackborn1f903c32011-09-13 19:18:06 -07005792 private int reduceConfigWidthSize(int curSize, int rotation, float density, int dw, int dh) {
5793 int size = (int)(mPolicy.getConfigDisplayWidth(dw, dh, rotation) / density);
Dianne Hackborn69cb8752011-05-19 18:13:32 -07005794 if (size < curSize) {
5795 curSize = size;
5796 }
5797 return curSize;
5798 }
5799
Dianne Hackborn5fd21692011-06-07 14:09:47 -07005800 private int computeSmallestWidth(boolean rotated, int dw, int dh, float density) {
5801 // We need to determine the smallest width that will occur under normal
5802 // operation. To this, start with the base screen size and compute the
5803 // width under the different possible rotations. We need to un-rotate
5804 // the current screen dimensions before doing this.
5805 int unrotDw, unrotDh;
5806 if (rotated) {
5807 unrotDw = dh;
5808 unrotDh = dw;
5809 } else {
5810 unrotDw = dw;
5811 unrotDh = dh;
5812 }
Dianne Hackborn1f903c32011-09-13 19:18:06 -07005813 int sw = reduceConfigWidthSize(unrotDw, Surface.ROTATION_0, density, unrotDw, unrotDh);
Dianne Hackborn09bd49a2011-09-15 19:12:01 -07005814 sw = reduceConfigWidthSize(sw, Surface.ROTATION_90, density, unrotDh, unrotDw);
Dianne Hackborn1f903c32011-09-13 19:18:06 -07005815 sw = reduceConfigWidthSize(sw, Surface.ROTATION_180, density, unrotDw, unrotDh);
Dianne Hackborn09bd49a2011-09-15 19:12:01 -07005816 sw = reduceConfigWidthSize(sw, Surface.ROTATION_270, density, unrotDh, unrotDw);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07005817 return sw;
5818 }
5819
Dianne Hackborn48a76512011-06-08 21:51:44 -07005820 private int reduceCompatConfigWidthSize(int curSize, int rotation, DisplayMetrics dm,
5821 int dw, int dh) {
Dianne Hackborn1f903c32011-09-13 19:18:06 -07005822 dm.noncompatWidthPixels = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
5823 dm.noncompatHeightPixels = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
Dianne Hackborn48a76512011-06-08 21:51:44 -07005824 float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
Dianne Hackborn2b31d532011-06-23 11:58:50 -07005825 int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
Dianne Hackborn48a76512011-06-08 21:51:44 -07005826 if (curSize == 0 || size < curSize) {
5827 curSize = size;
5828 }
5829 return curSize;
5830 }
5831
5832 private int computeCompatSmallestWidth(boolean rotated, DisplayMetrics dm, int dw, int dh) {
5833 mTmpDisplayMetrics.setTo(dm);
5834 dm = mTmpDisplayMetrics;
5835 int unrotDw, unrotDh;
5836 if (rotated) {
5837 unrotDw = dh;
5838 unrotDh = dw;
5839 } else {
5840 unrotDw = dw;
5841 unrotDh = dh;
5842 }
5843 int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, dm, unrotDw, unrotDh);
5844 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, dm, unrotDh, unrotDw);
5845 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, dm, unrotDw, unrotDh);
5846 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, dm, unrotDh, unrotDw);
5847 return sw;
5848 }
5849
Dianne Hackbornc485a602009-03-24 22:39:49 -07005850 boolean computeNewConfigurationLocked(Configuration config) {
5851 if (mDisplay == null) {
5852 return false;
5853 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005854
5855 mInputManager.getInputConfiguration(config);
Christopher Tateb696aee2010-04-02 19:08:30 -07005856
5857 // Use the effective "visual" dimensions based on current rotation
5858 final boolean rotated = (mRotation == Surface.ROTATION_90
5859 || mRotation == Surface.ROTATION_270);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07005860 final int realdw = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
5861 final int realdh = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005862
5863 if (mAltOrientation) {
5864 mCurDisplayWidth = realdw;
5865 mCurDisplayHeight = realdh;
5866 if (realdw > realdh) {
5867 // Turn landscape into portrait.
5868 int maxw = (int)(realdh/1.3f);
5869 if (maxw < realdw) {
5870 mCurDisplayWidth = maxw;
5871 }
5872 } else {
5873 // Turn portrait into landscape.
5874 int maxh = (int)(realdw/1.3f);
5875 if (maxh < realdh) {
5876 mCurDisplayHeight = maxh;
5877 }
5878 }
5879 } else {
5880 mCurDisplayWidth = realdw;
5881 mCurDisplayHeight = realdh;
5882 }
5883
5884 final int dw = mCurDisplayWidth;
5885 final int dh = mCurDisplayHeight;
Christopher Tateb696aee2010-04-02 19:08:30 -07005886
Dianne Hackbornc485a602009-03-24 22:39:49 -07005887 int orientation = Configuration.ORIENTATION_SQUARE;
5888 if (dw < dh) {
5889 orientation = Configuration.ORIENTATION_PORTRAIT;
5890 } else if (dw > dh) {
5891 orientation = Configuration.ORIENTATION_LANDSCAPE;
5892 }
5893 config.orientation = orientation;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005894
Jeff Brownbc68a592011-07-25 12:58:12 -07005895 // Update real display metrics.
5896 mDisplay.getMetricsWithSize(mRealDisplayMetrics, mCurDisplayWidth, mCurDisplayHeight);
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005897
Jeff Brownbc68a592011-07-25 12:58:12 -07005898 // Update application display metrics.
5899 final DisplayMetrics dm = mDisplayMetrics;
Dianne Hackborn1f903c32011-09-13 19:18:06 -07005900 mAppDisplayWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation);
5901 mAppDisplayHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation);
Dianne Hackborn36991742011-10-11 21:35:26 -07005902 if (false) {
5903 Slog.i(TAG, "Set app display size: " + mAppDisplayWidth
5904 + " x " + mAppDisplayHeight);
5905 }
Jeff Brownbc68a592011-07-25 12:58:12 -07005906 mDisplay.getMetricsWithSize(dm, mAppDisplayWidth, mAppDisplayHeight);
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005907
Dianne Hackborn5fd21692011-06-07 14:09:47 -07005908 mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm,
5909 mCompatDisplayMetrics);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005910
Dianne Hackborn1f903c32011-09-13 19:18:06 -07005911 config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation)
5912 / dm.density);
5913 config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation)
5914 / dm.density);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07005915 config.smallestScreenWidthDp = computeSmallestWidth(rotated, dw, dh, dm.density);
5916
5917 config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
5918 config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
Dianne Hackborn48a76512011-06-08 21:51:44 -07005919 config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dm, dw, dh);
Dianne Hackborn69cb8752011-05-19 18:13:32 -07005920
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005921 // Compute the screen layout size class.
5922 int screenLayout;
Dianne Hackborn36991742011-10-11 21:35:26 -07005923 int longSize = mAppDisplayWidth;
5924 int shortSize = mAppDisplayHeight;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005925 if (longSize < shortSize) {
5926 int tmp = longSize;
5927 longSize = shortSize;
5928 shortSize = tmp;
5929 }
5930 longSize = (int)(longSize/dm.density);
5931 shortSize = (int)(shortSize/dm.density);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005932
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005933 // These semi-magic numbers define our compatibility modes for
5934 // applications with different screens. These are guarantees to
5935 // app developers about the space they can expect for a particular
5936 // configuration. DO NOT CHANGE!
5937 if (longSize < 470) {
5938 // This is shorter than an HVGA normal density screen (which
5939 // is 480 pixels on its long side).
5940 screenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL
5941 | Configuration.SCREENLAYOUT_LONG_NO;
5942 } else {
5943 // What size is this screen screen?
5944 if (longSize >= 960 && shortSize >= 720) {
5945 // 1.5xVGA or larger screens at medium density are the point
5946 // at which we consider it to be an extra large screen.
5947 screenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE;
5948 } else if (longSize >= 640 && shortSize >= 480) {
5949 // VGA or larger screens at medium density are the point
5950 // at which we consider it to be a large screen.
5951 screenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
Dianne Hackborn723738c2009-06-25 19:48:04 -07005952 } else {
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005953 screenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL;
5954 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005955
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005956 // If this screen is wider than normal HVGA, or taller
5957 // than FWVGA, then for old apps we want to run in size
5958 // compatibility mode.
5959 if (shortSize > 321 || longSize > 570) {
5960 screenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
5961 }
5962
5963 // Is this a long screen?
5964 if (((longSize*3)/5) >= (shortSize-1)) {
5965 // Anything wider than WVGA (5:3) is considering to be long.
5966 screenLayout |= Configuration.SCREENLAYOUT_LONG_YES;
5967 } else {
5968 screenLayout |= Configuration.SCREENLAYOUT_LONG_NO;
Dianne Hackborn723738c2009-06-25 19:48:04 -07005969 }
5970 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005971 config.screenLayout = screenLayout;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005972
Jeff Brown597eec82011-01-31 17:12:25 -08005973 // Determine whether a hard keyboard is available and enabled.
Jeff Brown2992ea72011-01-28 22:04:14 -08005974 boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
5975 if (hardKeyboardAvailable != mHardKeyboardAvailable) {
5976 mHardKeyboardAvailable = hardKeyboardAvailable;
5977 mHardKeyboardEnabled = hardKeyboardAvailable;
5978
5979 mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
5980 mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
5981 }
5982 if (!mHardKeyboardEnabled) {
5983 config.keyboard = Configuration.KEYBOARD_NOKEYS;
Jeff Brown2992ea72011-01-28 22:04:14 -08005984 }
Jeff Brown597eec82011-01-31 17:12:25 -08005985
5986 // Update value of keyboardHidden, hardKeyboardHidden and navigationHidden
5987 // based on whether a hard or soft keyboard is present, whether navigation keys
5988 // are present and the lid switch state.
5989 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
5990 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
5991 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO;
5992 mPolicy.adjustConfigurationLw(config);
Dianne Hackbornc485a602009-03-24 22:39:49 -07005993 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005994 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005995
Jeff Brown2992ea72011-01-28 22:04:14 -08005996 public boolean isHardKeyboardAvailable() {
5997 synchronized (mWindowMap) {
5998 return mHardKeyboardAvailable;
5999 }
6000 }
6001
6002 public boolean isHardKeyboardEnabled() {
6003 synchronized (mWindowMap) {
6004 return mHardKeyboardEnabled;
6005 }
6006 }
6007
6008 public void setHardKeyboardEnabled(boolean enabled) {
6009 synchronized (mWindowMap) {
6010 if (mHardKeyboardEnabled != enabled) {
6011 mHardKeyboardEnabled = enabled;
6012 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
6013 }
6014 }
6015 }
6016
6017 public void setOnHardKeyboardStatusChangeListener(
6018 OnHardKeyboardStatusChangeListener listener) {
6019 synchronized (mWindowMap) {
6020 mHardKeyboardStatusChangeListener = listener;
6021 }
6022 }
6023
6024 void notifyHardKeyboardStatusChange() {
6025 final boolean available, enabled;
6026 final OnHardKeyboardStatusChangeListener listener;
6027 synchronized (mWindowMap) {
6028 listener = mHardKeyboardStatusChangeListener;
6029 available = mHardKeyboardAvailable;
6030 enabled = mHardKeyboardEnabled;
6031 }
6032 if (listener != null) {
6033 listener.onHardKeyboardStatusChange(available, enabled);
6034 }
6035 }
6036
Christopher Tatea53146c2010-09-07 11:57:52 -07006037 // -------------------------------------------------------------
6038 // Drag and drop
6039 // -------------------------------------------------------------
6040
6041 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006042 int flags, int width, int height, Surface outSurface) {
Christopher Tatea53146c2010-09-07 11:57:52 -07006043 if (DEBUG_DRAG) {
6044 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006045 + " flags=" + Integer.toHexString(flags) + " win=" + window
Christopher Tatea53146c2010-09-07 11:57:52 -07006046 + " asbinder=" + window.asBinder());
6047 }
6048
6049 final int callerPid = Binder.getCallingPid();
6050 final long origId = Binder.clearCallingIdentity();
6051 IBinder token = null;
6052
6053 try {
6054 synchronized (mWindowMap) {
6055 try {
Christopher Tatea53146c2010-09-07 11:57:52 -07006056 if (mDragState == null) {
6057 Surface surface = new Surface(session, callerPid, "drag surface", 0,
6058 width, height, PixelFormat.TRANSLUCENT, Surface.HIDDEN);
Dianne Hackbornac1471a2011-02-03 13:46:06 -08006059 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DRAG "
6060 + surface + ": CREATE");
Christopher Tatea53146c2010-09-07 11:57:52 -07006061 outSurface.copyFrom(surface);
Chris Tate7b362e42010-11-04 16:02:52 -07006062 final IBinder winBinder = window.asBinder();
Christopher Tatea53146c2010-09-07 11:57:52 -07006063 token = new Binder();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006064 mDragState = new DragState(this, token, surface, /*flags*/ 0, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07006065 mDragState.mSurface = surface;
Christopher Tatea53146c2010-09-07 11:57:52 -07006066 token = mDragState.mToken = new Binder();
6067
6068 // 5 second timeout for this window to actually begin the drag
Chris Tate7b362e42010-11-04 16:02:52 -07006069 mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
6070 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07006071 mH.sendMessageDelayed(msg, 5000);
6072 } else {
6073 Slog.w(TAG, "Drag already in progress");
6074 }
6075 } catch (Surface.OutOfResourcesException e) {
6076 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
6077 if (mDragState != null) {
6078 mDragState.reset();
6079 mDragState = null;
6080 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006081 }
6082 }
6083 } finally {
6084 Binder.restoreCallingIdentity(origId);
6085 }
6086
6087 return token;
6088 }
6089
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006090 // -------------------------------------------------------------
6091 // Input Events and Focus Management
6092 // -------------------------------------------------------------
Jeff Brown46b9ac02010-04-22 18:58:52 -07006093
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006094 final InputMonitor mInputMonitor = new InputMonitor(this);
Jeff Brown349703e2010-06-22 01:27:15 -07006095
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006096 public void pauseKeyDispatching(IBinder _token) {
6097 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6098 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006099 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006100 }
6101
6102 synchronized (mWindowMap) {
6103 WindowToken token = mTokenMap.get(_token);
6104 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006105 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006106 }
6107 }
6108 }
6109
6110 public void resumeKeyDispatching(IBinder _token) {
6111 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6112 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006113 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006114 }
6115
6116 synchronized (mWindowMap) {
6117 WindowToken token = mTokenMap.get(_token);
6118 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006119 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006120 }
6121 }
6122 }
6123
6124 public void setEventDispatching(boolean enabled) {
6125 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6126 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006127 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006128 }
6129
6130 synchronized (mWindowMap) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006131 mInputMonitor.setEventDispatchingLw(enabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006132 }
6133 }
Romain Guy06882f82009-06-10 13:36:04 -07006134
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006135 /**
6136 * Injects a keystroke event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07006137 * Even when sync is false, this method may block while waiting for current
6138 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07006139 *
6140 * @param ev A motion event describing the keystroke action. (Be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006141 * {@link SystemClock#uptimeMillis()} as the timebase.)
6142 * @param sync If true, wait for the event to be completed before returning to the caller.
6143 * @return Returns true if event was dispatched, false if it was dropped for any reason
6144 */
6145 public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
6146 long downTime = ev.getDownTime();
6147 long eventTime = ev.getEventTime();
6148
6149 int action = ev.getAction();
6150 int code = ev.getKeyCode();
6151 int repeatCount = ev.getRepeatCount();
6152 int metaState = ev.getMetaState();
6153 int deviceId = ev.getDeviceId();
6154 int scancode = ev.getScanCode();
Jeff Brownc5ed5912010-07-14 18:48:53 -07006155 int source = ev.getSource();
Mike Playlec6ded102010-11-29 16:01:03 +00006156 int flags = ev.getFlags();
Jeff Brownc5ed5912010-07-14 18:48:53 -07006157
6158 if (source == InputDevice.SOURCE_UNKNOWN) {
6159 source = InputDevice.SOURCE_KEYBOARD;
6160 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006161
6162 if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
6163 if (downTime == 0) downTime = eventTime;
6164
6165 KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
Jean-Baptiste Queru4a880132010-12-02 15:16:53 -08006166 deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006167
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006168 final int pid = Binder.getCallingPid();
6169 final int uid = Binder.getCallingUid();
6170 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac02010-04-22 18:58:52 -07006171
Jeff Brownbbda99d2010-07-28 15:48:59 -07006172 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
6173 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
6174 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
6175 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac02010-04-22 18:58:52 -07006176
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006177 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006178 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006179 }
6180
6181 /**
6182 * Inject a pointer (touch) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07006183 * Even when sync is false, this method may block while waiting for current
6184 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07006185 *
6186 * @param ev A motion event describing the pointer (touch) action. (As noted in
6187 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006188 * {@link SystemClock#uptimeMillis()} as the timebase.)
6189 * @param sync If true, wait for the event to be completed before returning to the caller.
6190 * @return Returns true if event was dispatched, false if it was dropped for any reason
6191 */
6192 public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006193 final int pid = Binder.getCallingPid();
6194 final int uid = Binder.getCallingUid();
6195 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac02010-04-22 18:58:52 -07006196
Jeff Brownc5ed5912010-07-14 18:48:53 -07006197 MotionEvent newEvent = MotionEvent.obtain(ev);
6198 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
6199 newEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
6200 }
6201
Jeff Brownbbda99d2010-07-28 15:48:59 -07006202 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
6203 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
6204 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
6205 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac02010-04-22 18:58:52 -07006206
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006207 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006208 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006209 }
Romain Guy06882f82009-06-10 13:36:04 -07006210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006211 /**
6212 * Inject a trackball (navigation device) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07006213 * Even when sync is false, this method may block while waiting for current
6214 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07006215 *
6216 * @param ev A motion event describing the trackball action. (As noted in
6217 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006218 * {@link SystemClock#uptimeMillis()} as the timebase.)
6219 * @param sync If true, wait for the event to be completed before returning to the caller.
6220 * @return Returns true if event was dispatched, false if it was dropped for any reason
6221 */
6222 public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006223 final int pid = Binder.getCallingPid();
6224 final int uid = Binder.getCallingUid();
6225 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac02010-04-22 18:58:52 -07006226
Jeff Brownc5ed5912010-07-14 18:48:53 -07006227 MotionEvent newEvent = MotionEvent.obtain(ev);
6228 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
6229 newEvent.setSource(InputDevice.SOURCE_TRACKBALL);
6230 }
6231
Jeff Brownbbda99d2010-07-28 15:48:59 -07006232 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
6233 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
6234 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
6235 INJECTION_TIMEOUT_MILLIS);
6236
6237 Binder.restoreCallingIdentity(ident);
6238 return reportInjectionResult(result);
6239 }
6240
6241 /**
6242 * Inject an input event into the UI without waiting for dispatch to commence.
6243 * This variant is useful for fire-and-forget input event injection. It does not
6244 * block any longer than it takes to enqueue the input event.
6245 *
6246 * @param ev An input event. (Be sure to set the input source correctly.)
6247 * @return Returns true if event was dispatched, false if it was dropped for any reason
6248 */
6249 public boolean injectInputEventNoWait(InputEvent ev) {
6250 final int pid = Binder.getCallingPid();
6251 final int uid = Binder.getCallingUid();
6252 final long ident = Binder.clearCallingIdentity();
6253
6254 final int result = mInputManager.injectInputEvent(ev, pid, uid,
6255 InputManager.INPUT_EVENT_INJECTION_SYNC_NONE,
6256 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac02010-04-22 18:58:52 -07006257
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006258 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006259 return reportInjectionResult(result);
6260 }
6261
6262 private boolean reportInjectionResult(int result) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006263 switch (result) {
6264 case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
6265 Slog.w(TAG, "Input event injection permission denied.");
6266 throw new SecurityException(
6267 "Injecting to another application requires INJECT_EVENTS permission");
6268 case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
Christopher Tate09e85dc2010-08-02 11:54:41 -07006269 //Slog.v(TAG, "Input event injection succeeded.");
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006270 return true;
6271 case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
6272 Slog.w(TAG, "Input event injection timed out.");
6273 return false;
6274 case InputManager.INPUT_EVENT_INJECTION_FAILED:
6275 default:
6276 Slog.w(TAG, "Input event injection failed.");
6277 return false;
Dianne Hackborncfaef692009-06-15 14:24:44 -07006278 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006279 }
Romain Guy06882f82009-06-10 13:36:04 -07006280
Jeff Brown1a84fd12011-06-02 01:26:32 -07006281 /**
6282 * Temporarily set the pointer speed. Does not save the new setting.
6283 * Used by the settings application.
6284 */
6285 public void setPointerSpeed(int speed) {
6286 if (!checkCallingPermission(android.Manifest.permission.SET_POINTER_SPEED,
6287 "setPointerSpeed()")) {
6288 throw new SecurityException("Requires SET_POINTER_SPEED permission");
6289 }
6290
6291 mInputManager.setPointerSpeed(speed);
6292 }
6293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006294 private WindowState getFocusedWindow() {
6295 synchronized (mWindowMap) {
6296 return getFocusedWindowLocked();
6297 }
6298 }
6299
6300 private WindowState getFocusedWindowLocked() {
6301 return mCurrentFocus;
6302 }
Romain Guy06882f82009-06-10 13:36:04 -07006303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006304 public boolean detectSafeMode() {
Jeff Brownb09abc12011-01-13 21:08:27 -08006305 if (!mInputMonitor.waitForInputDevicesReady(
6306 INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
6307 Slog.w(TAG, "Devices still not ready after waiting "
6308 + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
6309 + " milliseconds before attempting to detect safe mode.");
6310 }
6311
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006312 mSafeMode = mPolicy.detectSafeMode();
6313 return mSafeMode;
6314 }
Romain Guy06882f82009-06-10 13:36:04 -07006315
Dianne Hackborn661cd522011-08-22 00:26:20 -07006316 public void displayReady() {
Dianne Hackborn5132b372010-07-29 12:51:35 -07006317 synchronized(mWindowMap) {
6318 if (mDisplay != null) {
6319 throw new IllegalStateException("Display already initialized");
6320 }
6321 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
6322 mDisplay = wm.getDefaultDisplay();
Jeff Brownbc68a592011-07-25 12:58:12 -07006323 mInitialDisplayWidth = mDisplay.getRawWidth();
6324 mInitialDisplayHeight = mDisplay.getRawHeight();
Dianne Hackborn7916ac62011-05-16 20:45:48 -07006325 int rot = mDisplay.getRotation();
6326 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
6327 // If the screen is currently rotated, we need to swap the
6328 // initial width and height to get the true natural values.
6329 int tmp = mInitialDisplayWidth;
6330 mInitialDisplayWidth = mInitialDisplayHeight;
6331 mInitialDisplayHeight = tmp;
6332 }
Dianne Hackborn81e56d52011-05-26 00:55:58 -07006333 mBaseDisplayWidth = mCurDisplayWidth = mAppDisplayWidth = mInitialDisplayWidth;
6334 mBaseDisplayHeight = mCurDisplayHeight = mAppDisplayHeight = mInitialDisplayHeight;
Jeff Brownbc68a592011-07-25 12:58:12 -07006335 mInputManager.setDisplaySize(Display.DEFAULT_DISPLAY,
6336 mDisplay.getRawWidth(), mDisplay.getRawHeight(),
6337 mDisplay.getRawExternalWidth(), mDisplay.getRawExternalHeight());
Dianne Hackborn9d132642011-04-21 17:26:39 -07006338 mPolicy.setInitialDisplaySize(mInitialDisplayWidth, mInitialDisplayHeight);
Dianne Hackborn5132b372010-07-29 12:51:35 -07006339 }
6340
6341 try {
6342 mActivityManager.updateConfiguration(null);
6343 } catch (RemoteException e) {
6344 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07006345
Joe Onorato571ae902011-05-24 13:48:43 -07006346 synchronized (mWindowMap) {
6347 readForcedDisplaySizeLocked();
6348 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07006349 }
6350
Dianne Hackborn661cd522011-08-22 00:26:20 -07006351 public void systemReady() {
6352 mPolicy.systemReady();
6353 }
6354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006355 // This is an animation that does nothing: it just immediately finishes
6356 // itself every time it is called. It is used as a stub animation in cases
6357 // where we want to synchronize multiple things that may be animating.
6358 static final class DummyAnimation extends Animation {
6359 public boolean getTransformation(long currentTime, Transformation outTransformation) {
6360 return false;
6361 }
6362 }
6363 static final Animation sDummyAnimation = new DummyAnimation();
Romain Guy06882f82009-06-10 13:36:04 -07006364
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006365 // -------------------------------------------------------------
6366 // Async Handler
6367 // -------------------------------------------------------------
6368
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006369 final class H extends Handler {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006370 public static final int REPORT_FOCUS_CHANGE = 2;
6371 public static final int REPORT_LOSING_FOCUS = 3;
6372 public static final int ANIMATE = 4;
6373 public static final int ADD_STARTING = 5;
6374 public static final int REMOVE_STARTING = 6;
6375 public static final int FINISHED_STARTING = 7;
6376 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006377 public static final int WINDOW_FREEZE_TIMEOUT = 11;
6378 public static final int HOLD_SCREEN_CHANGED = 12;
6379 public static final int APP_TRANSITION_TIMEOUT = 13;
6380 public static final int PERSIST_ANIMATION_SCALE = 14;
6381 public static final int FORCE_GC = 15;
6382 public static final int ENABLE_SCREEN = 16;
6383 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006384 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07006385 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07006386 public static final int DRAG_START_TIMEOUT = 20;
Chris Tated4533f12010-10-19 15:15:08 -07006387 public static final int DRAG_END_TIMEOUT = 21;
Jeff Brown2992ea72011-01-28 22:04:14 -08006388 public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006389 public static final int BOOT_TIMEOUT = 23;
Dianne Hackborn38e29a62011-09-18 14:43:08 -07006390 public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
Romain Guy06882f82009-06-10 13:36:04 -07006391
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006392 private Session mLastReportedHold;
Romain Guy06882f82009-06-10 13:36:04 -07006393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006394 public H() {
6395 }
Romain Guy06882f82009-06-10 13:36:04 -07006396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006397 @Override
6398 public void handleMessage(Message msg) {
6399 switch (msg.what) {
6400 case REPORT_FOCUS_CHANGE: {
6401 WindowState lastFocus;
6402 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07006403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006404 synchronized(mWindowMap) {
6405 lastFocus = mLastFocus;
6406 newFocus = mCurrentFocus;
6407 if (lastFocus == newFocus) {
6408 // Focus is not changing, so nothing to do.
6409 return;
6410 }
6411 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006412 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006413 // + " to " + newFocus);
6414 if (newFocus != null && lastFocus != null
6415 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006416 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006417 mLosingFocus.add(lastFocus);
6418 lastFocus = null;
6419 }
6420 }
6421
6422 if (lastFocus != newFocus) {
6423 //System.out.println("Changing focus from " + lastFocus
6424 // + " to " + newFocus);
6425 if (newFocus != null) {
6426 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006427 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006428 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
6429 } catch (RemoteException e) {
6430 // Ignore if process has died.
6431 }
Konstantin Lopyrev5e7833a2010-08-09 17:01:11 -07006432 notifyFocusChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006433 }
6434
6435 if (lastFocus != null) {
6436 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006437 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006438 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
6439 } catch (RemoteException e) {
6440 // Ignore if process has died.
6441 }
6442 }
6443 }
6444 } break;
6445
6446 case REPORT_LOSING_FOCUS: {
6447 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07006448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006449 synchronized(mWindowMap) {
6450 losers = mLosingFocus;
6451 mLosingFocus = new ArrayList<WindowState>();
6452 }
6453
6454 final int N = losers.size();
6455 for (int i=0; i<N; i++) {
6456 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006457 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006458 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
6459 } catch (RemoteException e) {
6460 // Ignore if process has died.
6461 }
6462 }
6463 } break;
6464
6465 case ANIMATE: {
6466 synchronized(mWindowMap) {
6467 mAnimationPending = false;
6468 performLayoutAndPlaceSurfacesLocked();
6469 }
6470 } break;
6471
6472 case ADD_STARTING: {
6473 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
6474 final StartingData sd = wtoken.startingData;
6475
6476 if (sd == null) {
6477 // Animation has been canceled... do nothing.
6478 return;
6479 }
Romain Guy06882f82009-06-10 13:36:04 -07006480
Joe Onorato8a9b2202010-02-26 18:56:32 -08006481 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006482 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07006483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006484 View view = null;
6485 try {
6486 view = mPolicy.addStartingWindow(
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07006487 wtoken.token, sd.pkg, sd.theme, sd.compatInfo,
6488 sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006489 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006490 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006491 }
6492
6493 if (view != null) {
6494 boolean abort = false;
6495
6496 synchronized(mWindowMap) {
6497 if (wtoken.removed || wtoken.startingData == null) {
6498 // If the window was successfully added, then
6499 // we need to remove it.
6500 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006501 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006502 "Aborted starting " + wtoken
6503 + ": removed=" + wtoken.removed
6504 + " startingData=" + wtoken.startingData);
6505 wtoken.startingWindow = null;
6506 wtoken.startingData = null;
6507 abort = true;
6508 }
6509 } else {
6510 wtoken.startingView = view;
6511 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006512 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006513 "Added starting " + wtoken
6514 + ": startingWindow="
6515 + wtoken.startingWindow + " startingView="
6516 + wtoken.startingView);
6517 }
6518
6519 if (abort) {
6520 try {
6521 mPolicy.removeStartingWindow(wtoken.token, view);
6522 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006523 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006524 }
6525 }
6526 }
6527 } break;
6528
6529 case REMOVE_STARTING: {
6530 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
6531 IBinder token = null;
6532 View view = null;
6533 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006534 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006535 + wtoken + ": startingWindow="
6536 + wtoken.startingWindow + " startingView="
6537 + wtoken.startingView);
6538 if (wtoken.startingWindow != null) {
6539 view = wtoken.startingView;
6540 token = wtoken.token;
6541 wtoken.startingData = null;
6542 wtoken.startingView = null;
6543 wtoken.startingWindow = null;
6544 }
6545 }
6546 if (view != null) {
6547 try {
6548 mPolicy.removeStartingWindow(token, view);
6549 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006550 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006551 }
6552 }
6553 } break;
6554
6555 case FINISHED_STARTING: {
6556 IBinder token = null;
6557 View view = null;
6558 while (true) {
6559 synchronized (mWindowMap) {
6560 final int N = mFinishedStarting.size();
6561 if (N <= 0) {
6562 break;
6563 }
6564 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
6565
Joe Onorato8a9b2202010-02-26 18:56:32 -08006566 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006567 "Finished starting " + wtoken
6568 + ": startingWindow=" + wtoken.startingWindow
6569 + " startingView=" + wtoken.startingView);
6570
6571 if (wtoken.startingWindow == null) {
6572 continue;
6573 }
6574
6575 view = wtoken.startingView;
6576 token = wtoken.token;
6577 wtoken.startingData = null;
6578 wtoken.startingView = null;
6579 wtoken.startingWindow = null;
6580 }
6581
6582 try {
6583 mPolicy.removeStartingWindow(token, view);
6584 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006585 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006586 }
6587 }
6588 } break;
6589
6590 case REPORT_APPLICATION_TOKEN_WINDOWS: {
6591 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
6592
6593 boolean nowVisible = msg.arg1 != 0;
6594 boolean nowGone = msg.arg2 != 0;
6595
6596 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006597 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006598 TAG, "Reporting visible in " + wtoken
6599 + " visible=" + nowVisible
6600 + " gone=" + nowGone);
6601 if (nowVisible) {
6602 wtoken.appToken.windowsVisible();
6603 } else {
6604 wtoken.appToken.windowsGone();
6605 }
6606 } catch (RemoteException ex) {
6607 }
6608 } break;
Romain Guy06882f82009-06-10 13:36:04 -07006609
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006610 case WINDOW_FREEZE_TIMEOUT: {
6611 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006612 Slog.w(TAG, "Window freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006613 int i = mWindows.size();
6614 while (i > 0) {
6615 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07006616 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006617 if (w.mOrientationChanging) {
6618 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006619 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006620 }
6621 }
6622 performLayoutAndPlaceSurfacesLocked();
6623 }
6624 break;
6625 }
Romain Guy06882f82009-06-10 13:36:04 -07006626
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006627 case HOLD_SCREEN_CHANGED: {
6628 Session oldHold;
6629 Session newHold;
6630 synchronized (mWindowMap) {
6631 oldHold = mLastReportedHold;
6632 newHold = (Session)msg.obj;
6633 mLastReportedHold = newHold;
6634 }
Romain Guy06882f82009-06-10 13:36:04 -07006635
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006636 if (oldHold != newHold) {
6637 try {
6638 if (oldHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006639 mBatteryStats.noteStopWakelock(oldHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006640 "window",
6641 BatteryStats.WAKE_TYPE_WINDOW);
6642 }
6643 if (newHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006644 mBatteryStats.noteStartWakelock(newHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006645 "window",
6646 BatteryStats.WAKE_TYPE_WINDOW);
6647 }
6648 } catch (RemoteException e) {
6649 }
6650 }
6651 break;
6652 }
Romain Guy06882f82009-06-10 13:36:04 -07006653
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006654 case APP_TRANSITION_TIMEOUT: {
6655 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07006656 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006657 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006658 "*** APP TRANSITION TIMEOUT");
6659 mAppTransitionReady = true;
6660 mAppTransitionTimeout = true;
6661 performLayoutAndPlaceSurfacesLocked();
6662 }
6663 }
6664 break;
6665 }
Romain Guy06882f82009-06-10 13:36:04 -07006666
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006667 case PERSIST_ANIMATION_SCALE: {
6668 Settings.System.putFloat(mContext.getContentResolver(),
6669 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
6670 Settings.System.putFloat(mContext.getContentResolver(),
6671 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
6672 break;
6673 }
Romain Guy06882f82009-06-10 13:36:04 -07006674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006675 case FORCE_GC: {
6676 synchronized(mWindowMap) {
6677 if (mAnimationPending) {
6678 // If we are animating, don't do the gc now but
6679 // delay a bit so we don't interrupt the animation.
6680 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
6681 2000);
6682 return;
6683 }
6684 // If we are currently rotating the display, it will
6685 // schedule a new message when done.
6686 if (mDisplayFrozen) {
6687 return;
6688 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006689 }
6690 Runtime.getRuntime().gc();
6691 break;
6692 }
Romain Guy06882f82009-06-10 13:36:04 -07006693
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006694 case ENABLE_SCREEN: {
6695 performEnableScreen();
6696 break;
6697 }
Romain Guy06882f82009-06-10 13:36:04 -07006698
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006699 case APP_FREEZE_TIMEOUT: {
6700 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006701 Slog.w(TAG, "App freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006702 int i = mAppTokens.size();
6703 while (i > 0) {
6704 i--;
6705 AppWindowToken tok = mAppTokens.get(i);
6706 if (tok.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006707 Slog.w(TAG, "Force clearing freeze: " + tok);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006708 unsetAppFreezingScreenLocked(tok, true, true);
6709 }
6710 }
6711 }
6712 break;
6713 }
Romain Guy06882f82009-06-10 13:36:04 -07006714
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006715 case SEND_NEW_CONFIGURATION: {
6716 removeMessages(SEND_NEW_CONFIGURATION);
6717 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07006718 break;
6719 }
Romain Guy06882f82009-06-10 13:36:04 -07006720
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07006721 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07006722 if (mWindowsChanged) {
6723 synchronized (mWindowMap) {
6724 mWindowsChanged = false;
6725 }
6726 notifyWindowsChanged();
6727 }
6728 break;
6729 }
6730
Christopher Tatea53146c2010-09-07 11:57:52 -07006731 case DRAG_START_TIMEOUT: {
6732 IBinder win = (IBinder)msg.obj;
6733 if (DEBUG_DRAG) {
6734 Slog.w(TAG, "Timeout starting drag by win " + win);
6735 }
6736 synchronized (mWindowMap) {
6737 // !!! TODO: ANR the app that has failed to start the drag in time
6738 if (mDragState != null) {
Chris Tated4533f12010-10-19 15:15:08 -07006739 mDragState.unregister();
Jeff Brown2e44b072011-01-24 15:21:56 -08006740 mInputMonitor.updateInputWindowsLw(true /*force*/);
Christopher Tatea53146c2010-09-07 11:57:52 -07006741 mDragState.reset();
6742 mDragState = null;
6743 }
6744 }
Chris Tated4533f12010-10-19 15:15:08 -07006745 break;
Christopher Tatea53146c2010-09-07 11:57:52 -07006746 }
6747
Chris Tated4533f12010-10-19 15:15:08 -07006748 case DRAG_END_TIMEOUT: {
6749 IBinder win = (IBinder)msg.obj;
6750 if (DEBUG_DRAG) {
6751 Slog.w(TAG, "Timeout ending drag to win " + win);
6752 }
6753 synchronized (mWindowMap) {
6754 // !!! TODO: ANR the drag-receiving app
Christopher Tated9be36c2011-08-16 16:09:33 -07006755 if (mDragState != null) {
6756 mDragState.mDragResult = false;
6757 mDragState.endDragLw();
6758 }
Chris Tated4533f12010-10-19 15:15:08 -07006759 }
6760 break;
6761 }
Jeff Brown2992ea72011-01-28 22:04:14 -08006762
6763 case REPORT_HARD_KEYBOARD_STATUS_CHANGE: {
6764 notifyHardKeyboardStatusChange();
6765 break;
6766 }
Dianne Hackborn38e29a62011-09-18 14:43:08 -07006767
6768 case BOOT_TIMEOUT: {
6769 performBootTimeout();
6770 break;
6771 }
6772
6773 case WAITING_FOR_DRAWN_TIMEOUT: {
6774 Pair<WindowState, IRemoteCallback> pair;
6775 synchronized (mWindowMap) {
6776 pair = (Pair<WindowState, IRemoteCallback>)msg.obj;
6777 Slog.w(TAG, "Timeout waiting for drawn: " + pair.first);
6778 if (!mWaitingForDrawn.remove(pair)) {
6779 return;
6780 }
6781 }
6782 try {
6783 pair.second.sendResult(null);
6784 } catch (RemoteException e) {
6785 }
6786 break;
6787 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006788 }
6789 }
6790 }
6791
6792 // -------------------------------------------------------------
6793 // IWindowManager API
6794 // -------------------------------------------------------------
6795
6796 public IWindowSession openSession(IInputMethodClient client,
6797 IInputContext inputContext) {
6798 if (client == null) throw new IllegalArgumentException("null client");
6799 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006800 Session session = new Session(this, client, inputContext);
Jeff Brown46b9ac02010-04-22 18:58:52 -07006801 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006802 }
6803
6804 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
6805 synchronized (mWindowMap) {
6806 // The focus for the client is the window immediately below
6807 // where we would place the input method window.
6808 int idx = findDesiredInputMethodWindowIndexLocked(false);
6809 WindowState imFocus;
6810 if (idx > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07006811 imFocus = mWindows.get(idx-1);
Dianne Hackborne75d8722011-01-27 19:37:40 -08006812 //Log.i(TAG, "Desired input method target: " + imFocus);
6813 //Log.i(TAG, "Current focus: " + this.mCurrentFocus);
6814 //Log.i(TAG, "Last focus: " + this.mLastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006815 if (imFocus != null) {
Dianne Hackborne75d8722011-01-27 19:37:40 -08006816 // This may be a starting window, in which case we still want
6817 // to count it as okay.
6818 if (imFocus.mAttrs.type == LayoutParams.TYPE_APPLICATION_STARTING
6819 && imFocus.mAppToken != null) {
6820 // The client has definitely started, so it really should
6821 // have a window in this app token. Let's look for it.
6822 for (int i=0; i<imFocus.mAppToken.windows.size(); i++) {
6823 WindowState w = imFocus.mAppToken.windows.get(i);
6824 if (w != imFocus) {
6825 //Log.i(TAG, "Switching to real app window: " + w);
6826 imFocus = w;
6827 break;
6828 }
6829 }
6830 }
6831 //Log.i(TAG, "IM target client: " + imFocus.mSession.mClient);
6832 //if (imFocus.mSession.mClient != null) {
6833 // Log.i(TAG, "IM target client binder: " + imFocus.mSession.mClient.asBinder());
6834 // Log.i(TAG, "Requesting client binder: " + client.asBinder());
6835 //}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006836 if (imFocus.mSession.mClient != null &&
6837 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
6838 return true;
6839 }
Dianne Hackborne75d8722011-01-27 19:37:40 -08006840
6841 // Okay, how about this... what is the current focus?
6842 // It seems in some cases we may not have moved the IM
6843 // target window, such as when it was in a pop-up window,
6844 // so let's also look at the current focus. (An example:
6845 // go to Gmail, start searching so the keyboard goes up,
6846 // press home. Sometimes the IME won't go down.)
6847 // Would be nice to fix this more correctly, but it's
6848 // way at the end of a release, and this should be good enough.
6849 if (mCurrentFocus != null && mCurrentFocus.mSession.mClient != null &&
6850 mCurrentFocus.mSession.mClient.asBinder() == client.asBinder()) {
6851 return true;
6852 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006853 }
6854 }
6855 }
6856 return false;
6857 }
Romain Guy06882f82009-06-10 13:36:04 -07006858
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07006859 public void getDisplaySize(Point size) {
6860 synchronized(mWindowMap) {
Dianne Hackborn81e56d52011-05-26 00:55:58 -07006861 size.x = mAppDisplayWidth;
6862 size.y = mAppDisplayHeight;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07006863 }
6864 }
6865
Jeff Brownbc68a592011-07-25 12:58:12 -07006866 public void getRealDisplaySize(Point size) {
6867 synchronized(mWindowMap) {
6868 size.x = mCurDisplayWidth;
6869 size.y = mCurDisplayHeight;
6870 }
6871 }
6872
Dianne Hackborn7d608422011-08-07 16:24:18 -07006873 public void getInitialDisplaySize(Point size) {
6874 synchronized(mWindowMap) {
6875 size.x = mInitialDisplayWidth;
6876 size.y = mInitialDisplayHeight;
6877 }
6878 }
6879
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07006880 public int getMaximumSizeDimension() {
6881 synchronized(mWindowMap) {
6882 // Do this based on the raw screen size, until we are smarter.
Dianne Hackborn7916ac62011-05-16 20:45:48 -07006883 return mBaseDisplayWidth > mBaseDisplayHeight
6884 ? mBaseDisplayWidth : mBaseDisplayHeight;
6885 }
6886 }
6887
6888 public void setForcedDisplaySize(int longDimen, int shortDimen) {
6889 synchronized(mWindowMap) {
6890 int width, height;
6891 if (mInitialDisplayWidth < mInitialDisplayHeight) {
6892 width = shortDimen < mInitialDisplayWidth
6893 ? shortDimen : mInitialDisplayWidth;
6894 height = longDimen < mInitialDisplayHeight
6895 ? longDimen : mInitialDisplayHeight;
6896 } else {
6897 width = longDimen < mInitialDisplayWidth
6898 ? longDimen : mInitialDisplayWidth;
6899 height = shortDimen < mInitialDisplayHeight
6900 ? shortDimen : mInitialDisplayHeight;
6901 }
6902 setForcedDisplaySizeLocked(width, height);
Joe Onorato571ae902011-05-24 13:48:43 -07006903 Settings.Secure.putString(mContext.getContentResolver(),
6904 Settings.Secure.DISPLAY_SIZE_FORCED, width + "," + height);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07006905 }
6906 }
6907
6908 private void rebuildBlackFrame(boolean inTransaction) {
6909 if (!inTransaction) {
Dianne Hackborn36991742011-10-11 21:35:26 -07006910 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn7916ac62011-05-16 20:45:48 -07006911 ">>> OPEN TRANSACTION rebuildBlackFrame");
6912 Surface.openTransaction();
6913 }
6914 try {
6915 if (mBlackFrame != null) {
6916 mBlackFrame.kill();
6917 mBlackFrame = null;
6918 }
6919 if (mBaseDisplayWidth < mInitialDisplayWidth
6920 || mBaseDisplayHeight < mInitialDisplayHeight) {
Dianne Hackborn8f7c2712011-05-18 15:07:48 -07006921 int initW, initH, baseW, baseH;
6922 final boolean rotated = (mRotation == Surface.ROTATION_90
6923 || mRotation == Surface.ROTATION_270);
6924 if (rotated) {
6925 initW = mInitialDisplayHeight;
6926 initH = mInitialDisplayWidth;
6927 baseW = mBaseDisplayHeight;
6928 baseH = mBaseDisplayWidth;
6929 } else {
6930 initW = mInitialDisplayWidth;
6931 initH = mInitialDisplayHeight;
6932 baseW = mBaseDisplayWidth;
6933 baseH = mBaseDisplayHeight;
6934 }
6935 Rect outer = new Rect(0, 0, initW, initH);
6936 Rect inner = new Rect(0, 0, baseW, baseH);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07006937 try {
6938 mBlackFrame = new BlackFrame(mFxSession, outer, inner, MASK_LAYER);
6939 } catch (Surface.OutOfResourcesException e) {
6940 }
6941 }
6942 } finally {
6943 if (!inTransaction) {
6944 Surface.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -07006945 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn7916ac62011-05-16 20:45:48 -07006946 "<<< CLOSE TRANSACTION rebuildBlackFrame");
6947 }
6948 }
6949 }
6950
Joe Onorato571ae902011-05-24 13:48:43 -07006951 private void readForcedDisplaySizeLocked() {
6952 final String str = Settings.Secure.getString(mContext.getContentResolver(),
6953 Settings.Secure.DISPLAY_SIZE_FORCED);
6954 if (str == null || str.length() == 0) {
6955 return;
6956 }
6957 final int pos = str.indexOf(',');
6958 if (pos <= 0 || str.lastIndexOf(',') != pos) {
6959 return;
6960 }
6961 int width, height;
6962 try {
6963 width = Integer.parseInt(str.substring(0, pos));
6964 height = Integer.parseInt(str.substring(pos+1));
6965 } catch (NumberFormatException ex) {
6966 return;
6967 }
6968 setForcedDisplaySizeLocked(width, height);
6969 }
6970
Dianne Hackborn7916ac62011-05-16 20:45:48 -07006971 private void setForcedDisplaySizeLocked(int width, int height) {
Joe Onorato571ae902011-05-24 13:48:43 -07006972 Slog.i(TAG, "Using new display size: " + width + "x" + height);
6973
Dianne Hackborn7916ac62011-05-16 20:45:48 -07006974 mBaseDisplayWidth = width;
6975 mBaseDisplayHeight = height;
6976 mPolicy.setInitialDisplaySize(mBaseDisplayWidth, mBaseDisplayHeight);
6977
6978 mLayoutNeeded = true;
6979
6980 boolean configChanged = updateOrientationFromAppTokensLocked(false);
6981 mTempConfiguration.setToDefaults();
6982 mTempConfiguration.fontScale = mCurConfiguration.fontScale;
6983 if (computeNewConfigurationLocked(mTempConfiguration)) {
6984 if (mCurConfiguration.diff(mTempConfiguration) != 0) {
6985 configChanged = true;
6986 }
6987 }
6988
6989 if (configChanged) {
6990 mWaitingForConfig = true;
6991 startFreezingDisplayLocked(false);
6992 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
6993 }
6994
6995 rebuildBlackFrame(false);
6996
6997 performLayoutAndPlaceSurfacesLocked();
6998 }
6999
7000 public void clearForcedDisplaySize() {
7001 synchronized(mWindowMap) {
7002 setForcedDisplaySizeLocked(mInitialDisplayWidth, mInitialDisplayHeight);
Joe Onorato571ae902011-05-24 13:48:43 -07007003 Settings.Secure.putString(mContext.getContentResolver(),
7004 Settings.Secure.DISPLAY_SIZE_FORCED, "");
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07007005 }
7006 }
7007
Dianne Hackborn81e56d52011-05-26 00:55:58 -07007008 public boolean canStatusBarHide() {
7009 return mPolicy.canStatusBarHide();
7010 }
7011
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007012 // -------------------------------------------------------------
7013 // Internals
7014 // -------------------------------------------------------------
7015
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007016 final WindowState windowForClientLocked(Session session, IWindow client,
7017 boolean throwOnError) {
7018 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007019 }
Romain Guy06882f82009-06-10 13:36:04 -07007020
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007021 final WindowState windowForClientLocked(Session session, IBinder client,
7022 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007023 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007024 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007025 TAG, "Looking up client " + client + ": " + win);
7026 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007027 RuntimeException ex = new IllegalArgumentException(
7028 "Requested window " + client + " does not exist");
7029 if (throwOnError) {
7030 throw ex;
7031 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007032 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007033 return null;
7034 }
7035 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007036 RuntimeException ex = new IllegalArgumentException(
7037 "Requested window " + client + " is in session " +
7038 win.mSession + ", not " + session);
7039 if (throwOnError) {
7040 throw ex;
7041 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007042 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007043 return null;
7044 }
7045
7046 return win;
7047 }
7048
Dianne Hackborna8f60182009-09-01 19:01:50 -07007049 final void rebuildAppWindowListLocked() {
7050 int NW = mWindows.size();
7051 int i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007052 int lastWallpaper = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007053 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007054
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007055 if (mRebuildTmp.length < NW) {
7056 mRebuildTmp = new WindowState[NW+10];
7057 }
7058
Dianne Hackborna8f60182009-09-01 19:01:50 -07007059 // First remove all existing app windows.
7060 i=0;
7061 while (i < NW) {
Jeff Browne33348b2010-07-15 23:54:05 -07007062 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007063 if (w.mAppToken != null) {
Jeff Browne33348b2010-07-15 23:54:05 -07007064 WindowState win = mWindows.remove(i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007065 win.mRebuilding = true;
7066 mRebuildTmp[numRemoved] = win;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007067 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007068 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007069 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07007070 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007071 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07007072 continue;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007073 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER
7074 && lastWallpaper == i-1) {
7075 lastWallpaper = i;
Dianne Hackborna8f60182009-09-01 19:01:50 -07007076 }
7077 i++;
7078 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007079
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007080 // The wallpaper window(s) typically live at the bottom of the stack,
7081 // so skip them before adding app tokens.
7082 lastWallpaper++;
7083 i = lastWallpaper;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007084
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007085 // First add all of the exiting app tokens... these are no longer
7086 // in the main app list, but still have windows shown. We put them
7087 // in the back because now that the animation is over we no longer
7088 // will care about them.
7089 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07007090 for (int j=0; j<NT; j++) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007091 i = reAddAppWindowsLocked(i, mExitingAppTokens.get(j));
7092 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007093
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007094 // And add in the still active app tokens in Z order.
7095 NT = mAppTokens.size();
7096 for (int j=0; j<NT; j++) {
7097 i = reAddAppWindowsLocked(i, mAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07007098 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007099
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007100 i -= lastWallpaper;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007101 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007102 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007103 + " windows but added " + i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007104 for (i=0; i<numRemoved; i++) {
7105 WindowState ws = mRebuildTmp[i];
7106 if (ws.mRebuilding) {
7107 StringWriter sw = new StringWriter();
7108 PrintWriter pw = new PrintWriter(sw);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07007109 ws.dump(pw, "", true);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007110 pw.flush();
7111 Slog.w(TAG, "This window was lost: " + ws);
7112 Slog.w(TAG, sw.toString());
7113 }
7114 }
7115 Slog.w(TAG, "Current app token list:");
7116 dumpAppTokensLocked();
7117 Slog.w(TAG, "Final window list:");
7118 dumpWindowsLocked();
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007119 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07007120 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007121
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007122 private final void assignLayersLocked() {
7123 int N = mWindows.size();
7124 int curBaseLayer = 0;
7125 int curLayer = 0;
7126 int i;
Romain Guy06882f82009-06-10 13:36:04 -07007127
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007128 if (DEBUG_LAYERS) {
7129 RuntimeException here = new RuntimeException("here");
7130 here.fillInStackTrace();
7131 Log.v(TAG, "Assigning layers", here);
7132 }
7133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007134 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07007135 WindowState w = mWindows.get(i);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007136 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
7137 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007138 curLayer += WINDOW_LAYER_MULTIPLIER;
7139 w.mLayer = curLayer;
7140 } else {
7141 curBaseLayer = curLayer = w.mBaseLayer;
7142 w.mLayer = curLayer;
7143 }
7144 if (w.mTargetAppToken != null) {
7145 w.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
7146 } else if (w.mAppToken != null) {
7147 w.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
7148 } else {
7149 w.mAnimLayer = w.mLayer;
7150 }
7151 if (w.mIsImWindow) {
7152 w.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007153 } else if (w.mIsWallpaper) {
7154 w.mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007155 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007156 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007157 + w.mAnimLayer);
7158 //System.out.println(
7159 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
7160 }
7161 }
7162
7163 private boolean mInLayout = false;
7164 private final void performLayoutAndPlaceSurfacesLocked() {
7165 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07007166 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007167 throw new RuntimeException("Recursive call!");
7168 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007169 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007170 return;
7171 }
7172
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007173 if (mWaitingForConfig) {
7174 // Our configuration has changed (most likely rotation), but we
7175 // don't yet have the complete configuration to report to
7176 // applications. Don't do any window layout until we have it.
7177 return;
7178 }
7179
Dianne Hackbornce2ef762010-09-20 11:39:14 -07007180 if (mDisplay == null) {
7181 // Not yet initialized, nothing to do.
7182 return;
7183 }
7184
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08007185 mInLayout = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007186 boolean recoveringMemory = false;
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08007187
7188 try {
7189 if (mForceRemoves != null) {
7190 recoveringMemory = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007191 // Wait a little bit for things to settle down, and off we go.
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08007192 for (int i=0; i<mForceRemoves.size(); i++) {
7193 WindowState ws = mForceRemoves.get(i);
7194 Slog.i(TAG, "Force removing: " + ws);
7195 removeWindowInnerLocked(ws.mSession, ws);
7196 }
7197 mForceRemoves = null;
7198 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
7199 Object tmp = new Object();
7200 synchronized (tmp) {
7201 try {
7202 tmp.wait(250);
7203 } catch (InterruptedException e) {
7204 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007205 }
7206 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08007207 } catch (RuntimeException e) {
Dianne Hackborn89620282011-09-11 12:47:45 -07007208 Log.wtf(TAG, "Unhandled exception while force removing for memory", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007209 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08007210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007211 try {
7212 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Romain Guy06882f82009-06-10 13:36:04 -07007213
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007214 int N = mPendingRemove.size();
7215 if (N > 0) {
7216 if (mPendingRemoveTmp.length < N) {
7217 mPendingRemoveTmp = new WindowState[N+10];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007218 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007219 mPendingRemove.toArray(mPendingRemoveTmp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007220 mPendingRemove.clear();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007221 for (int i=0; i<N; i++) {
7222 WindowState w = mPendingRemoveTmp[i];
7223 removeWindowInnerLocked(w.mSession, w);
7224 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007225
7226 mInLayout = false;
7227 assignLayersLocked();
7228 mLayoutNeeded = true;
7229 performLayoutAndPlaceSurfacesLocked();
7230
7231 } else {
7232 mInLayout = false;
7233 if (mLayoutNeeded) {
7234 requestAnimationLocked(0);
7235 }
7236 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007237 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07007238 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
7239 mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007240 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007241 } catch (RuntimeException e) {
7242 mInLayout = false;
Dianne Hackborn89620282011-09-11 12:47:45 -07007243 Log.wtf(TAG, "Unhandled exception while laying out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007244 }
7245 }
7246
Jeff Brown3a22cd92011-01-21 13:59:04 -08007247 private final int performLayoutLockedInner(boolean initial, boolean updateInputWindows) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007248 if (!mLayoutNeeded) {
7249 return 0;
7250 }
7251
7252 mLayoutNeeded = false;
7253
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07007254 final int dw = mCurDisplayWidth;
7255 final int dh = mCurDisplayHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007256
Dianne Hackborndf89e652011-10-06 22:35:11 -07007257 final int NFW = mFakeWindows.size();
7258 for (int i=0; i<NFW; i++) {
7259 mFakeWindows.get(i).layout(dw, dh);
7260 }
7261
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007262 final int N = mWindows.size();
7263 int i;
7264
Joe Onorato8a9b2202010-02-26 18:56:32 -08007265 if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
Dianne Hackborn9b52a212009-12-11 14:51:35 -08007266 + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
7267
Dianne Hackborn1f903c32011-09-13 19:18:06 -07007268 mPolicy.beginLayoutLw(dw, dh, mRotation);
Romain Guy06882f82009-06-10 13:36:04 -07007269
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007270 int seq = mLayoutSeq+1;
7271 if (seq < 0) seq = 0;
7272 mLayoutSeq = seq;
7273
7274 // First perform layout of any root windows (not attached
7275 // to another window).
7276 int topAttached = -1;
7277 for (i = N-1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07007278 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007279
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007280 // Don't do layout of a window if it is not visible, or
7281 // soon won't be visible, to avoid wasting time and funky
7282 // changes while a window is animating away.
7283 final AppWindowToken atoken = win.mAppToken;
7284 final boolean gone = win.mViewVisibility == View.GONE
7285 || !win.mRelayoutCalled
Dianne Hackbornff801ec2011-01-22 18:05:38 -08007286 || (atoken == null && win.mRootToken.hidden)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007287 || (atoken != null && atoken.hiddenRequested)
7288 || win.mAttachedHidden
7289 || win.mExiting || win.mDestroying;
7290
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007291 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
7292 Slog.v(TAG, "First pass " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007293 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
7294 + " mLayoutAttached=" + win.mLayoutAttached);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007295 if (gone) Slog.v(TAG, " (mViewVisibility="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007296 + win.mViewVisibility + " mRelayoutCalled="
7297 + win.mRelayoutCalled + " hidden="
7298 + win.mRootToken.hidden + " hiddenRequested="
7299 + (atoken != null && atoken.hiddenRequested)
7300 + " mAttachedHidden=" + win.mAttachedHidden);
7301 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007302
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007303 // If this view is GONE, then skip it -- keep the current
7304 // frame, and let the caller know so they can ignore it
7305 // if they want. (We do the normal layout for INVISIBLE
7306 // windows, since that means "perform layout as normal,
7307 // just don't display").
7308 if (!gone || !win.mHaveFrame) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007309 if (!win.mLayoutAttached) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08007310 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08007311 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08007312 win.mContentChanged = false;
7313 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007314 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007315 mPolicy.layoutWindowLw(win, win.mAttrs, null);
7316 win.mLayoutSeq = seq;
7317 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
7318 + win.mFrame + " mContainingFrame="
7319 + win.mContainingFrame + " mDisplayFrame="
7320 + win.mDisplayFrame);
7321 } else {
7322 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007323 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07007324 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007325 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007326
7327 // Now perform layout of attached windows, which usually
7328 // depend on the position of the window they are attached to.
7329 // XXX does not deal with windows that are attached to windows
7330 // that are themselves attached.
7331 for (i = topAttached; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07007332 WindowState win = mWindows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007333
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007334 if (win.mLayoutAttached) {
7335 if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
7336 + " mHaveFrame=" + win.mHaveFrame
7337 + " mViewVisibility=" + win.mViewVisibility
7338 + " mRelayoutCalled=" + win.mRelayoutCalled);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007339 // If this view is GONE, then skip it -- keep the current
7340 // frame, and let the caller know so they can ignore it
7341 // if they want. (We do the normal layout for INVISIBLE
7342 // windows, since that means "perform layout as normal,
7343 // just don't display").
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007344 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
7345 || !win.mHaveFrame) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08007346 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08007347 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08007348 win.mContentChanged = false;
7349 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007350 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007351 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
7352 win.mLayoutSeq = seq;
7353 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
7354 + win.mFrame + " mContainingFrame="
7355 + win.mContainingFrame + " mDisplayFrame="
7356 + win.mDisplayFrame);
7357 }
7358 }
7359 }
Jeff Brown349703e2010-06-22 01:27:15 -07007360
7361 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown3a22cd92011-01-21 13:59:04 -08007362 mInputMonitor.setUpdateInputWindowsNeededLw();
7363 if (updateInputWindows) {
Jeff Brown2e44b072011-01-24 15:21:56 -08007364 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08007365 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007366
7367 return mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007368 }
Romain Guy06882f82009-06-10 13:36:04 -07007369
Brad Fitzpatrick68044332010-11-22 18:19:48 -08007370 // "Something has changed! Let's make it correct now."
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007371 private final void performLayoutAndPlaceSurfacesLockedInner(
7372 boolean recoveringMemory) {
Joe Onorato34bcebc2010-07-07 18:05:01 -04007373 if (mDisplay == null) {
7374 Slog.i(TAG, "skipping performLayoutAndPlaceSurfacesLockedInner with no mDisplay");
7375 return;
7376 }
7377
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007378 final long currentTime = SystemClock.uptimeMillis();
Dianne Hackborndacea8c2011-04-21 17:26:39 -07007379 final int dw = mCurDisplayWidth;
7380 final int dh = mCurDisplayHeight;
Dianne Hackborn81e56d52011-05-26 00:55:58 -07007381 final int innerDw = mAppDisplayWidth;
7382 final int innerDh = mAppDisplayHeight;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007384 int i;
7385
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007386 if (mFocusMayChange) {
7387 mFocusMayChange = false;
Jeff Brown3a22cd92011-01-21 13:59:04 -08007388 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
7389 false /*updateInputWindows*/);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007390 }
7391
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007392 // Initialize state of exiting tokens.
7393 for (i=mExitingTokens.size()-1; i>=0; i--) {
7394 mExitingTokens.get(i).hasVisible = false;
7395 }
7396
7397 // Initialize state of exiting applications.
7398 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
7399 mExitingAppTokens.get(i).hasVisible = false;
7400 }
7401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007402 boolean orientationChangeComplete = true;
7403 Session holdScreen = null;
7404 float screenBrightness = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -05007405 float buttonBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007406 boolean focusDisplayed = false;
7407 boolean animating = false;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07007408 boolean createWatermark = false;
Dianne Hackborn89ba6752011-01-23 16:51:16 -08007409 boolean updateRotation = false;
Dianne Hackborn50660e22011-02-02 17:12:25 -08007410 boolean screenRotationFinished = false;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07007411
7412 if (mFxSession == null) {
7413 mFxSession = new SurfaceSession();
7414 createWatermark = true;
7415 }
7416
Dianne Hackborn36991742011-10-11 21:35:26 -07007417 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
7418 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007419
7420 Surface.openTransaction();
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07007421
7422 if (createWatermark) {
7423 createWatermark();
7424 }
7425 if (mWatermark != null) {
7426 mWatermark.positionSurface(dw, dh);
7427 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08007428 if (mStrictModeFlash != null) {
7429 mStrictModeFlash.positionSurface(dw, dh);
7430 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07007431
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007432 try {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007433 boolean wallpaperForceHidingChanged = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007434 int repeats = 0;
7435 int changes = 0;
7436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007437 do {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007438 repeats++;
7439 if (repeats > 6) {
7440 Slog.w(TAG, "Animation repeat aborted after too many iterations");
7441 mLayoutNeeded = false;
7442 break;
7443 }
7444
7445 if ((changes&(WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER
7446 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG
7447 | WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
7448 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
7449 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
7450 assignLayersLocked();
7451 mLayoutNeeded = true;
7452 }
7453 }
7454 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
7455 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08007456 if (updateOrientationFromAppTokensLocked(true)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007457 mLayoutNeeded = true;
7458 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
7459 }
7460 }
7461 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
7462 mLayoutNeeded = true;
7463 }
7464 }
7465
7466 // FIRST LOOP: Perform a layout, if needed.
7467 if (repeats < 4) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08007468 changes = performLayoutLockedInner(repeats == 0, false /*updateInputWindows*/);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007469 if (changes != 0) {
7470 continue;
7471 }
7472 } else {
7473 Slog.w(TAG, "Layout repeat skipped after too many iterations");
7474 changes = 0;
7475 }
7476
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007477 final int transactionSequence = ++mTransactionSequence;
7478
7479 // Update animations of all applications, including those
7480 // associated with exiting/removed apps
7481 boolean tokensAnimating = false;
7482 final int NAT = mAppTokens.size();
7483 for (i=0; i<NAT; i++) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007484 if (mAppTokens.get(i).stepAnimationLocked(currentTime,
7485 innerDw, innerDh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007486 tokensAnimating = true;
7487 }
7488 }
7489 final int NEAT = mExitingAppTokens.size();
7490 for (i=0; i<NEAT; i++) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007491 if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime,
7492 innerDw, innerDh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007493 tokensAnimating = true;
7494 }
7495 }
7496
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007497 // SECOND LOOP: Execute animations and update visibility of windows.
7498
Joe Onorato8a9b2202010-02-26 18:56:32 -08007499 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007500 + transactionSequence + " tokensAnimating="
7501 + tokensAnimating);
7502
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007503 animating = tokensAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007504
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007505 if (mScreenRotationAnimation != null) {
7506 if (mScreenRotationAnimation.isAnimating()) {
7507 if (mScreenRotationAnimation.stepAnimation(currentTime)) {
7508 animating = true;
7509 } else {
Dianne Hackborn50660e22011-02-02 17:12:25 -08007510 screenRotationFinished = true;
Dianne Hackborn89ba6752011-01-23 16:51:16 -08007511 updateRotation = true;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007512 }
7513 }
7514 }
7515
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007516 boolean tokenMayBeDrawn = false;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007517 boolean wallpaperMayChange = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007518 boolean forceHiding = false;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007519 WindowState windowDetachedWallpaper = null;
Dianne Hackbornde75cb42011-03-02 17:11:21 -08007520 WindowState windowAnimationBackground = null;
7521 int windowAnimationBackgroundColor = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007522
7523 mPolicy.beginAnimationLw(dw, dh);
7524
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007525 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007526
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007527 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07007528 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007529
7530 final WindowManager.LayoutParams attrs = w.mAttrs;
7531
7532 if (w.mSurface != null) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08007533 // Take care of the window being ready to display.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007534 if (w.commitFinishDrawingLocked(currentTime)) {
7535 if ((w.mAttrs.flags
7536 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007537 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007538 "First draw done in potential wallpaper target " + w);
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007539 wallpaperMayChange = true;
7540 }
7541 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007542
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007543 final boolean wasAnimating = w.mAnimating;
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08007544
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007545 int animDw = innerDw;
7546 int animDh = innerDh;
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08007547
7548 // If the window has moved due to its containing
7549 // content frame changing, then we'd like to animate
7550 // it. The checks here are ordered by what is least
Joe Onorato3fe7f2f2010-11-20 13:48:58 -08007551 // likely to be true first.
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007552 if (w.shouldAnimateMove()) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08007553 // Frame has moved, containing content frame
7554 // has also moved, and we're not currently animating...
7555 // let's do something.
7556 Animation a = AnimationUtils.loadAnimation(mContext,
7557 com.android.internal.R.anim.window_move_from_decor);
7558 w.setAnimation(a);
7559 animDw = w.mLastFrame.left - w.mFrame.left;
7560 animDh = w.mLastFrame.top - w.mFrame.top;
7561 }
7562
7563 // Execute animation.
7564 final boolean nowAnimating = w.stepAnimationLocked(currentTime,
7565 animDw, animDh);
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007566
7567 // If this window is animating, make a note that we have
7568 // an animating window and take care of a request to run
7569 // a detached wallpaper animation.
7570 if (nowAnimating) {
Dianne Hackbornde75cb42011-03-02 17:11:21 -08007571 if (w.mAnimation != null) {
7572 if (w.mAnimation.getDetachWallpaper()) {
7573 windowDetachedWallpaper = w;
7574 }
7575 if (w.mAnimation.getBackgroundColor() != 0) {
Dianne Hackbornd02a9e92011-09-12 13:47:31 -07007576 if (windowAnimationBackground == null || w.mAnimLayer <
7577 windowAnimationBackground.mAnimLayer) {
7578 windowAnimationBackground = w;
7579 windowAnimationBackgroundColor =
7580 w.mAnimation.getBackgroundColor();
7581 }
Dianne Hackbornde75cb42011-03-02 17:11:21 -08007582 }
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007583 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007584 animating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007585 }
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007586
7587 // If this window's app token is running a detached wallpaper
7588 // animation, make a note so we can ensure the wallpaper is
7589 // displayed behind it.
Dianne Hackbornd02a9e92011-09-12 13:47:31 -07007590 if (w.mAppToken != null && w.mAppToken.animation != null
7591 && w.mAppToken.animating) {
Dianne Hackbornde75cb42011-03-02 17:11:21 -08007592 if (w.mAppToken.animation.getDetachWallpaper()) {
7593 windowDetachedWallpaper = w;
7594 }
7595 if (w.mAppToken.animation.getBackgroundColor() != 0) {
Dianne Hackbornd02a9e92011-09-12 13:47:31 -07007596 if (windowAnimationBackground == null || w.mAnimLayer <
7597 windowAnimationBackground.mAnimLayer) {
7598 windowAnimationBackground = w;
7599 windowAnimationBackgroundColor =
7600 w.mAppToken.animation.getBackgroundColor();
7601 }
Dianne Hackbornde75cb42011-03-02 17:11:21 -08007602 }
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007603 }
7604
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007605 if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
7606 wallpaperMayChange = true;
7607 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007608
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007609 if (mPolicy.doesForceHide(w, attrs)) {
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007610 if (!wasAnimating && nowAnimating) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08007611 if (DEBUG_VISIBILITY) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007612 "Animation started that could impact force hide: "
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08007613 + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007614 wallpaperForceHidingChanged = true;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007615 mFocusMayChange = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007616 } else if (w.isReadyForDisplay() && w.mAnimation == null) {
7617 forceHiding = true;
7618 }
7619 } else if (mPolicy.canBeForceHidden(w, attrs)) {
7620 boolean changed;
7621 if (forceHiding) {
7622 changed = w.hideLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08007623 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
7624 "Now policy hidden: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007625 } else {
7626 changed = w.showLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08007627 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
7628 "Now policy shown: " + w);
7629 if (changed) {
7630 if (wallpaperForceHidingChanged
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007631 && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08007632 // Assume we will need to animate. If
7633 // we don't (because the wallpaper will
7634 // stay with the lock screen), then we will
7635 // clean up later.
7636 Animation a = mPolicy.createForceHideEnterAnimation();
7637 if (a != null) {
7638 w.setAnimation(a);
7639 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007640 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08007641 if (mCurrentFocus == null ||
7642 mCurrentFocus.mLayer < w.mLayer) {
7643 // We are showing on to of the current
7644 // focus, so re-evaluate focus to make
7645 // sure it is correct.
7646 mFocusMayChange = true;
7647 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007648 }
7649 }
7650 if (changed && (attrs.flags
7651 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
7652 wallpaperMayChange = true;
7653 }
7654 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007655
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007656 mPolicy.animatingWindowLw(w, attrs);
7657 }
7658
7659 final AppWindowToken atoken = w.mAppToken;
7660 if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
7661 if (atoken.lastTransactionSequence != transactionSequence) {
7662 atoken.lastTransactionSequence = transactionSequence;
7663 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
7664 atoken.startingDisplayed = false;
7665 }
7666 if ((w.isOnScreen() || w.mAttrs.type
7667 == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
7668 && !w.mExiting && !w.mDestroying) {
7669 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007670 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07007671 + w.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007672 + ", isAnimating=" + w.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07007673 if (!w.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007674 Slog.v(TAG, "Not displayed: s=" + w.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007675 + " pv=" + w.mPolicyVisibility
7676 + " dp=" + w.mDrawPending
7677 + " cdp=" + w.mCommitDrawPending
7678 + " ah=" + w.mAttachedHidden
7679 + " th=" + atoken.hiddenRequested
7680 + " a=" + w.mAnimating);
7681 }
7682 }
7683 if (w != atoken.startingWindow) {
7684 if (!atoken.freezingScreen || !w.mAppFreezing) {
7685 atoken.numInterestingWindows++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07007686 if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007687 atoken.numDrawnWindows++;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007688 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007689 "tokenMayBeDrawn: " + atoken
7690 + " freezingScreen=" + atoken.freezingScreen
7691 + " mAppFreezing=" + w.mAppFreezing);
7692 tokenMayBeDrawn = true;
7693 }
7694 }
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07007695 } else if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007696 atoken.startingDisplayed = true;
7697 }
7698 }
7699 } else if (w.mReadyToShow) {
7700 w.performShowLocked();
7701 }
7702 }
7703
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007704 changes |= mPolicy.finishAnimationLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007705
7706 if (tokenMayBeDrawn) {
7707 // See if any windows have been drawn, so they (and others
7708 // associated with them) can now be shown.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007709 final int NT = mAppTokens.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007710 for (i=0; i<NT; i++) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007711 AppWindowToken wtoken = mAppTokens.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007712 if (wtoken.freezingScreen) {
7713 int numInteresting = wtoken.numInterestingWindows;
7714 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007715 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007716 "allDrawn: " + wtoken
7717 + " interesting=" + numInteresting
7718 + " drawn=" + wtoken.numDrawnWindows);
7719 wtoken.showAllWindowsLocked();
7720 unsetAppFreezingScreenLocked(wtoken, false, true);
7721 orientationChangeComplete = true;
7722 }
7723 } else if (!wtoken.allDrawn) {
7724 int numInteresting = wtoken.numInterestingWindows;
7725 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007726 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007727 "allDrawn: " + wtoken
7728 + " interesting=" + numInteresting
7729 + " drawn=" + wtoken.numDrawnWindows);
7730 wtoken.allDrawn = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007731 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007732
7733 // We can now show all of the drawn windows!
7734 if (!mOpeningApps.contains(wtoken)) {
7735 wtoken.showAllWindowsLocked();
7736 }
7737 }
7738 }
7739 }
7740 }
7741
7742 // If we are ready to perform an app transition, check through
7743 // all of the app tokens to be shown and see if they are ready
7744 // to go.
7745 if (mAppTransitionReady) {
7746 int NN = mOpeningApps.size();
7747 boolean goodToGo = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007748 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007749 "Checking " + NN + " opening apps (frozen="
7750 + mDisplayFrozen + " timeout="
7751 + mAppTransitionTimeout + ")...");
7752 if (!mDisplayFrozen && !mAppTransitionTimeout) {
7753 // If the display isn't frozen, wait to do anything until
7754 // all of the apps are ready. Otherwise just go because
7755 // we'll unfreeze the display when everyone is ready.
7756 for (i=0; i<NN && goodToGo; i++) {
7757 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007758 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007759 "Check opening app" + wtoken + ": allDrawn="
7760 + wtoken.allDrawn + " startingDisplayed="
7761 + wtoken.startingDisplayed);
7762 if (!wtoken.allDrawn && !wtoken.startingDisplayed
7763 && !wtoken.startingMoved) {
7764 goodToGo = false;
7765 }
7766 }
7767 }
7768 if (goodToGo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007769 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007770 int transit = mNextAppTransition;
7771 if (mSkipAppTransitionAnimation) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07007772 transit = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007773 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07007774 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007775 mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -07007776 mAppTransitionRunning = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007777 mAppTransitionTimeout = false;
7778 mStartingIconInTransition = false;
7779 mSkipAppTransitionAnimation = false;
7780
7781 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
7782
Dianne Hackborna8f60182009-09-01 19:01:50 -07007783 // If there are applications waiting to come to the
7784 // top of the stack, now is the time to move their windows.
7785 // (Note that we don't do apps going to the bottom
7786 // here -- we want to keep their windows in the old
7787 // Z-order until the animation completes.)
7788 if (mToTopApps.size() > 0) {
7789 NN = mAppTokens.size();
7790 for (i=0; i<NN; i++) {
7791 AppWindowToken wtoken = mAppTokens.get(i);
7792 if (wtoken.sendingToTop) {
7793 wtoken.sendingToTop = false;
7794 moveAppWindowsLocked(wtoken, NN, false);
7795 }
7796 }
7797 mToTopApps.clear();
7798 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007799
Dianne Hackborn25994b42009-09-04 14:21:19 -07007800 WindowState oldWallpaper = mWallpaperTarget;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007801
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007802 adjustWallpaperWindowsLocked();
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007803 wallpaperMayChange = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007804
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07007805 // The top-most window will supply the layout params,
7806 // and we will determine it below.
7807 LayoutParams animLp = null;
7808 int bestAnimLayer = -1;
Dianne Hackborn08121bc2011-01-17 17:54:31 -08007809 boolean fullscreenAnim = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007810
Joe Onorato8a9b2202010-02-26 18:56:32 -08007811 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007812 "New wallpaper target=" + mWallpaperTarget
7813 + ", lower target=" + mLowerWallpaperTarget
7814 + ", upper target=" + mUpperWallpaperTarget);
Dianne Hackborn25994b42009-09-04 14:21:19 -07007815 int foundWallpapers = 0;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07007816 // Do a first pass through the tokens for two
7817 // things:
7818 // (1) Determine if both the closing and opening
7819 // app token sets are wallpaper targets, in which
7820 // case special animations are needed
7821 // (since the wallpaper needs to stay static
7822 // behind them).
7823 // (2) Find the layout params of the top-most
7824 // application window in the tokens, which is
7825 // what will control the animation theme.
7826 final int NC = mClosingApps.size();
7827 NN = NC + mOpeningApps.size();
7828 for (i=0; i<NN; i++) {
7829 AppWindowToken wtoken;
7830 int mode;
7831 if (i < NC) {
7832 wtoken = mClosingApps.get(i);
7833 mode = 1;
7834 } else {
7835 wtoken = mOpeningApps.get(i-NC);
7836 mode = 2;
7837 }
7838 if (mLowerWallpaperTarget != null) {
7839 if (mLowerWallpaperTarget.mAppToken == wtoken
7840 || mUpperWallpaperTarget.mAppToken == wtoken) {
7841 foundWallpapers |= mode;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07007842 }
7843 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07007844 if (wtoken.appFullscreen) {
7845 WindowState ws = wtoken.findMainWindow();
7846 if (ws != null) {
Dianne Hackbornffb3d932011-05-17 17:44:51 -07007847 animLp = ws.mAttrs;
7848 bestAnimLayer = ws.mLayer;
Dianne Hackborn08121bc2011-01-17 17:54:31 -08007849 fullscreenAnim = true;
7850 }
7851 } else if (!fullscreenAnim) {
7852 WindowState ws = wtoken.findMainWindow();
7853 if (ws != null) {
7854 if (ws.mLayer > bestAnimLayer) {
7855 animLp = ws.mAttrs;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07007856 bestAnimLayer = ws.mLayer;
7857 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07007858 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07007859 }
7860 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007861
Dianne Hackborn25994b42009-09-04 14:21:19 -07007862 if (foundWallpapers == 3) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007863 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07007864 "Wallpaper animation!");
7865 switch (transit) {
7866 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
7867 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
7868 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
7869 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
7870 break;
7871 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
7872 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
7873 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
7874 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
7875 break;
7876 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007877 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07007878 "New transit: " + transit);
7879 } else if (oldWallpaper != null) {
7880 // We are transitioning from an activity with
7881 // a wallpaper to one without.
7882 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007883 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07007884 "New transit away from wallpaper: " + transit);
7885 } else if (mWallpaperTarget != null) {
7886 // We are transitioning from an activity without
7887 // a wallpaper to now showing the wallpaper
7888 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007889 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07007890 "New transit into wallpaper: " + transit);
7891 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007892
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007893 // If all closing windows are obscured, then there is
7894 // no need to do an animation. This is the case, for
7895 // example, when this transition is being done behind
7896 // the lock screen.
7897 if (!mPolicy.allowAppAnimationsLw()) {
7898 animLp = null;
7899 }
7900
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007901 NN = mOpeningApps.size();
7902 for (i=0; i<NN; i++) {
7903 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007904 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007905 "Now opening app" + wtoken);
7906 wtoken.reportedVisible = false;
7907 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07007908 wtoken.animation = null;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007909 setTokenVisibilityLocked(wtoken, animLp, true,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07007910 transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007911 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07007912 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007913 wtoken.showAllWindowsLocked();
7914 }
7915 NN = mClosingApps.size();
7916 for (i=0; i<NN; i++) {
7917 AppWindowToken wtoken = mClosingApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007918 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007919 "Now closing app" + wtoken);
7920 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07007921 wtoken.animation = null;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007922 setTokenVisibilityLocked(wtoken, animLp, false,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07007923 transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007924 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07007925 wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007926 // Force the allDrawn flag, because we want to start
7927 // this guy's animations regardless of whether it's
7928 // gotten drawn.
7929 wtoken.allDrawn = true;
7930 }
7931
Dianne Hackborn8b571a82009-09-25 16:09:43 -07007932 mNextAppTransitionPackage = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007933
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007934 mOpeningApps.clear();
7935 mClosingApps.clear();
7936
7937 // This has changed the visibility of windows, so perform
7938 // a new layout to get them all up-to-date.
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08007939 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT
7940 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007941 mLayoutNeeded = true;
Dianne Hackborn20583ff2009-07-27 21:51:05 -07007942 if (!moveInputMethodWindowsIfNeededLocked(true)) {
7943 assignLayersLocked();
7944 }
Jeff Brown3a22cd92011-01-21 13:59:04 -08007945 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
7946 false /*updateInputWindows*/);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007947 mFocusMayChange = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007948 }
7949 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007950
Dianne Hackborn16064f92010-03-25 00:47:24 -07007951 int adjResult = 0;
7952
Dianne Hackborna8f60182009-09-01 19:01:50 -07007953 if (!animating && mAppTransitionRunning) {
7954 // We have finished the animation of an app transition. To do
7955 // this, we have delayed a lot of operations like showing and
7956 // hiding apps, moving apps in Z-order, etc. The app token list
7957 // reflects the correct Z-order, but the window list may now
7958 // be out of sync with it. So here we will just rebuild the
7959 // entire app window list. Fun!
7960 mAppTransitionRunning = false;
7961 // Clear information about apps that were moving.
7962 mToBottomApps.clear();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007963
Dianne Hackborna8f60182009-09-01 19:01:50 -07007964 rebuildAppWindowListLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007965 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn16064f92010-03-25 00:47:24 -07007966 adjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborna8f60182009-09-01 19:01:50 -07007967 moveInputMethodWindowsIfNeededLocked(false);
7968 wallpaperMayChange = true;
Suchi Amalapurapuc9568e32009-11-05 18:51:16 -08007969 // Since the window list has been rebuilt, focus might
7970 // have to be recomputed since the actual order of windows
7971 // might have changed again.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007972 mFocusMayChange = true;
Dianne Hackborna8f60182009-09-01 19:01:50 -07007973 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007974
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007975 if (wallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007976 // At this point, there was a window with a wallpaper that
7977 // was force hiding other windows behind it, but now it
7978 // is going away. This may be simple -- just animate
7979 // away the wallpaper and its window -- or it may be
7980 // hard -- the wallpaper now needs to be shown behind
7981 // something that was hidden.
7982 WindowState oldWallpaper = mWallpaperTarget;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007983 if (mLowerWallpaperTarget != null
7984 && mLowerWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007985 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007986 "wallpaperForceHiding changed with lower="
7987 + mLowerWallpaperTarget);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007988 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007989 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
7990 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
7991 if (mLowerWallpaperTarget.mAppToken.hidden) {
7992 // The lower target has become hidden before we
7993 // actually started the animation... let's completely
7994 // re-evaluate everything.
7995 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007996 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007997 }
7998 }
Dianne Hackborn16064f92010-03-25 00:47:24 -07007999 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008000 wallpaperMayChange = false;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008001 wallpaperForceHidingChanged = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008002 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008003 + " NEW: " + mWallpaperTarget
8004 + " LOWER: " + mLowerWallpaperTarget);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008005 if (mLowerWallpaperTarget == null) {
8006 // Whoops, we don't need a special wallpaper animation.
8007 // Clear them out.
8008 forceHiding = false;
8009 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07008010 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008011 if (w.mSurface != null) {
8012 final WindowManager.LayoutParams attrs = w.mAttrs;
Suchi Amalapurapuc03d28b2009-10-28 14:32:05 -07008013 if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008014 if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008015 forceHiding = true;
8016 } else if (mPolicy.canBeForceHidden(w, attrs)) {
8017 if (!w.mAnimating) {
8018 // We set the animation above so it
8019 // is not yet running.
8020 w.clearAnimation();
8021 }
8022 }
8023 }
8024 }
8025 }
8026 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008027
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08008028 if (mWindowDetachedWallpaper != windowDetachedWallpaper) {
8029 if (DEBUG_WALLPAPER) Slog.v(TAG,
8030 "Detached wallpaper changed from " + mWindowDetachedWallpaper
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07008031 + " to " + windowDetachedWallpaper);
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08008032 mWindowDetachedWallpaper = windowDetachedWallpaper;
8033 wallpaperMayChange = true;
8034 }
8035
Dianne Hackbornde75cb42011-03-02 17:11:21 -08008036 if (windowAnimationBackgroundColor != 0) {
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07008037 // If the window that wants black is the current wallpaper
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07008038 // target, then the black goes *below* the wallpaper so we
8039 // don't cause the wallpaper to suddenly disappear.
8040 WindowState target = windowAnimationBackground;
8041 if (mWallpaperTarget == windowAnimationBackground
8042 || mLowerWallpaperTarget == windowAnimationBackground
8043 || mUpperWallpaperTarget == windowAnimationBackground) {
8044 for (i=0; i<mWindows.size(); i++) {
8045 WindowState w = mWindows.get(i);
8046 if (w.mIsWallpaper) {
8047 target = w;
8048 break;
8049 }
8050 }
8051 }
Dianne Hackbornde75cb42011-03-02 17:11:21 -08008052 if (mWindowAnimationBackgroundSurface == null) {
8053 mWindowAnimationBackgroundSurface = new DimSurface(mFxSession);
8054 }
8055 mWindowAnimationBackgroundSurface.show(dw, dh,
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07008056 target.mAnimLayer - LAYER_OFFSET_DIM,
Dianne Hackbornde75cb42011-03-02 17:11:21 -08008057 windowAnimationBackgroundColor);
8058 } else if (mWindowAnimationBackgroundSurface != null) {
8059 mWindowAnimationBackgroundSurface.hide();
8060 }
8061
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07008062 if (wallpaperMayChange) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008063 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008064 "Wallpaper may change! Adjusting");
Dianne Hackborn16064f92010-03-25 00:47:24 -07008065 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008066 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008067
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008068 if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008069 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008070 "Wallpaper layer changed: assigning layers + relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008071 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008072 assignLayersLocked();
8073 } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008074 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008075 "Wallpaper visibility changed: relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008076 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008077 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008078
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008079 if (mFocusMayChange) {
8080 mFocusMayChange = false;
Jeff Brown3a22cd92011-01-21 13:59:04 -08008081 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
8082 false /*updateInputWindows*/)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008083 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008084 adjResult = 0;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07008085 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008086 }
8087
8088 if (mLayoutNeeded) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008089 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07008090 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008091
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008092 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
8093 + Integer.toHexString(changes));
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008094 } while (changes != 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008095
8096 // THIRD LOOP: Update the surfaces of all windows.
8097
8098 final boolean someoneLosingFocus = mLosingFocus.size() != 0;
8099
8100 boolean obscured = false;
8101 boolean blurring = false;
8102 boolean dimming = false;
8103 boolean covered = false;
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07008104 boolean syswin = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008105
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008106 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008108 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07008109 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008110
8111 boolean displayed = false;
8112 final WindowManager.LayoutParams attrs = w.mAttrs;
8113 final int attrFlags = attrs.flags;
8114
8115 if (w.mSurface != null) {
Dianne Hackbornac3587d2010-03-11 11:12:11 -08008116 // XXX NOTE: The logic here could be improved. We have
8117 // the decision about whether to resize a window separated
8118 // from whether to hide the surface. This can cause us to
8119 // resize a surface even if we are going to hide it. You
8120 // can see this by (1) holding device in landscape mode on
8121 // home screen; (2) tapping browser icon (device will rotate
8122 // to landscape; (3) tap home. The wallpaper will be resized
8123 // in step 2 but then immediately hidden, causing us to
8124 // have to resize and then redraw it again in step 3. It
8125 // would be nice to figure out how to avoid this, but it is
8126 // difficult because we do need to resize surfaces in some
8127 // cases while they are hidden such as when first showing a
8128 // window.
8129
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008130 w.computeShownFrameLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08008131 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008132 TAG, "Placing surface #" + i + " " + w.mSurface
Dianne Hackbornffb3d932011-05-17 17:44:51 -07008133 + ": new=" + w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008134
Jeff Brownfbae7222011-01-23 13:07:25 -08008135 if (w.mSurface != null) {
Dianne Hackbornb961cd22011-06-21 12:13:37 -07008136 int width, height;
8137 if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
8138 // for a scaled surface, we just want to use
8139 // the requested size.
8140 width = w.mRequestedWidth;
8141 height = w.mRequestedHeight;
8142 } else {
8143 width = w.mCompatFrame.width();
8144 height = w.mCompatFrame.height();
8145 }
8146
8147 if (width < 1) {
8148 width = 1;
8149 }
8150 if (height < 1) {
8151 height = 1;
8152 }
8153 final boolean surfaceResized = w.mSurfaceW != width || w.mSurfaceH != height;
8154 if (surfaceResized) {
8155 w.mSurfaceW = width;
8156 w.mSurfaceH = height;
8157 }
8158
Jeff Brownfbae7222011-01-23 13:07:25 -08008159 if (w.mSurfaceX != w.mShownFrame.left
8160 || w.mSurfaceY != w.mShownFrame.top) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008161 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008162 if (SHOW_TRANSACTIONS) logSurface(w,
Jeff Brownfbae7222011-01-23 13:07:25 -08008163 "POS " + w.mShownFrame.left
8164 + ", " + w.mShownFrame.top, null);
8165 w.mSurfaceX = w.mShownFrame.left;
8166 w.mSurfaceY = w.mShownFrame.top;
8167 w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
8168 } catch (RuntimeException e) {
8169 Slog.w(TAG, "Error positioning surface of " + w
8170 + " pos=(" + w.mShownFrame.left
8171 + "," + w.mShownFrame.top + ")", e);
8172 if (!recoveringMemory) {
Dianne Hackborn64825172011-03-02 21:32:58 -08008173 reclaimSomeSurfaceMemoryLocked(w, "position", true);
Jeff Brownfbae7222011-01-23 13:07:25 -08008174 }
8175 }
8176 }
8177
Dianne Hackbornb961cd22011-06-21 12:13:37 -07008178 if (surfaceResized) {
Jeff Brownfbae7222011-01-23 13:07:25 -08008179 try {
8180 if (SHOW_TRANSACTIONS) logSurface(w,
Dianne Hackbornb961cd22011-06-21 12:13:37 -07008181 "SIZE " + width + "x" + height, null);
Dianne Hackbornac3587d2010-03-11 11:12:11 -08008182 w.mSurfaceResized = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008183 w.mSurface.setSize(width, height);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008184 } catch (RuntimeException e) {
8185 // If something goes wrong with the surface (such
8186 // as running out of memory), don't take down the
8187 // entire system.
Jeff Brownfbae7222011-01-23 13:07:25 -08008188 Slog.e(TAG, "Error resizing surface of " + w
8189 + " size=(" + width + "x" + height + ")", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008190 if (!recoveringMemory) {
Dianne Hackborn64825172011-03-02 21:32:58 -08008191 reclaimSomeSurfaceMemoryLocked(w, "size", true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008192 }
8193 }
8194 }
8195 }
Jeff Brownfbae7222011-01-23 13:07:25 -08008196
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008197 if (!w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
Dianne Hackbornb961cd22011-06-21 12:13:37 -07008198 w.mContentInsetsChanged |=
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008199 !w.mLastContentInsets.equals(w.mContentInsets);
Dianne Hackbornb961cd22011-06-21 12:13:37 -07008200 w.mVisibleInsetsChanged |=
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008201 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008202 boolean configChanged =
8203 w.mConfiguration != mCurConfiguration
8204 && (w.mConfiguration == null
8205 || mCurConfiguration.diff(w.mConfiguration) != 0);
Dianne Hackborn694f79b2010-03-17 19:44:59 -07008206 if (DEBUG_CONFIGURATION && configChanged) {
8207 Slog.v(TAG, "Win " + w + " config changed: "
8208 + mCurConfiguration);
8209 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008210 if (localLOGV) Slog.v(TAG, "Resizing " + w
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008211 + ": configChanged=" + configChanged
Dianne Hackbornb961cd22011-06-21 12:13:37 -07008212 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
8213 w.mLastFrame.set(w.mFrame);
8214 if (w.mContentInsetsChanged
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008215 || w.mVisibleInsetsChanged
Dianne Hackbornac3587d2010-03-11 11:12:11 -08008216 || w.mSurfaceResized
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008217 || configChanged) {
Jeff Brownfbae7222011-01-23 13:07:25 -08008218 if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
8219 Slog.v(TAG, "Resize reasons: "
Jeff Brownfbae7222011-01-23 13:07:25 -08008220 + " contentInsetsChanged=" + w.mContentInsetsChanged
8221 + " visibleInsetsChanged=" + w.mVisibleInsetsChanged
8222 + " surfaceResized=" + w.mSurfaceResized
8223 + " configChanged=" + configChanged);
8224 }
8225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008226 w.mLastContentInsets.set(w.mContentInsets);
8227 w.mLastVisibleInsets.set(w.mVisibleInsets);
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07008228 // If the screen is currently frozen or off, then keep
8229 // it frozen/off until this window draws at its new
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008230 // orientation.
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07008231 if (mDisplayFrozen || !mPolicy.isScreenOnFully()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008232 if (DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008233 "Resizing while display frozen: " + w);
8234 w.mOrientationChanging = true;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008235 if (!mWindowsFreezingScreen) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008236 mWindowsFreezingScreen = true;
8237 // XXX should probably keep timeout from
8238 // when we first froze the display.
8239 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
8240 mH.sendMessageDelayed(mH.obtainMessage(
8241 H.WINDOW_FREEZE_TIMEOUT), 2000);
8242 }
8243 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008244 // If the orientation is changing, then we need to
8245 // hold off on unfreezing the display until this
8246 // window has been redrawn; to do that, we need
8247 // to go through the process of getting informed
8248 // by the application when it has finished drawing.
8249 if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008250 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008251 "Orientation start waiting for draw in "
8252 + w + ", surface " + w.mSurface);
8253 w.mDrawPending = true;
8254 w.mCommitDrawPending = false;
8255 w.mReadyToShow = false;
8256 if (w.mAppToken != null) {
8257 w.mAppToken.allDrawn = false;
8258 }
8259 }
Dianne Hackbornb961cd22011-06-21 12:13:37 -07008260 if (!mResizingWindows.contains(w)) {
8261 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
8262 "Resizing window " + w + " to " + w.mSurfaceW
8263 + "x" + w.mSurfaceH);
8264 mResizingWindows.add(w);
8265 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008266 } else if (w.mOrientationChanging) {
8267 if (!w.mDrawPending && !w.mCommitDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008268 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008269 "Orientation not waiting for draw in "
8270 + w + ", surface " + w.mSurface);
8271 w.mOrientationChanging = false;
8272 }
8273 }
8274 }
8275
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008276 if (w.mAttachedHidden || !w.isReadyForDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008277 if (!w.mLastHidden) {
8278 //dump();
8279 w.mLastHidden = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008280 if (SHOW_TRANSACTIONS) logSurface(w,
8281 "HIDE (performLayout)", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008282 if (w.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -07008283 w.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008284 try {
8285 w.mSurface.hide();
8286 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008287 Slog.w(TAG, "Exception hiding surface in " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008288 }
8289 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008290 }
8291 // If we are waiting for this window to handle an
8292 // orientation change, well, it is hidden, so
8293 // doesn't really matter. Note that this does
8294 // introduce a potential glitch if the window
8295 // becomes unhidden before it has drawn for the
8296 // new orientation.
8297 if (w.mOrientationChanging) {
8298 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008299 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008300 "Orientation change skips hidden " + w);
8301 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008302 } else if (w.mLastLayer != w.mAnimLayer
8303 || w.mLastAlpha != w.mShownAlpha
8304 || w.mLastDsDx != w.mDsDx
8305 || w.mLastDtDx != w.mDtDx
8306 || w.mLastDsDy != w.mDsDy
8307 || w.mLastDtDy != w.mDtDy
8308 || w.mLastHScale != w.mHScale
8309 || w.mLastVScale != w.mVScale
8310 || w.mLastHidden) {
8311 displayed = true;
8312 w.mLastAlpha = w.mShownAlpha;
8313 w.mLastLayer = w.mAnimLayer;
8314 w.mLastDsDx = w.mDsDx;
8315 w.mLastDtDx = w.mDtDx;
8316 w.mLastDsDy = w.mDsDy;
8317 w.mLastDtDy = w.mDtDy;
8318 w.mLastHScale = w.mHScale;
8319 w.mLastVScale = w.mVScale;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008320 if (SHOW_TRANSACTIONS) logSurface(w,
8321 "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008322 + " matrix=[" + (w.mDsDx*w.mHScale)
8323 + "," + (w.mDtDx*w.mVScale)
8324 + "][" + (w.mDsDy*w.mHScale)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008325 + "," + (w.mDtDy*w.mVScale) + "]", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008326 if (w.mSurface != null) {
8327 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07008328 w.mSurfaceAlpha = w.mShownAlpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008329 w.mSurface.setAlpha(w.mShownAlpha);
Dianne Hackborn16064f92010-03-25 00:47:24 -07008330 w.mSurfaceLayer = w.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008331 w.mSurface.setLayer(w.mAnimLayer);
8332 w.mSurface.setMatrix(
8333 w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
8334 w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
8335 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008336 Slog.w(TAG, "Error updating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008337 if (!recoveringMemory) {
Dianne Hackborn64825172011-03-02 21:32:58 -08008338 reclaimSomeSurfaceMemoryLocked(w, "update", true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008339 }
8340 }
8341 }
8342
8343 if (w.mLastHidden && !w.mDrawPending
8344 && !w.mCommitDrawPending
8345 && !w.mReadyToShow) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008346 if (SHOW_TRANSACTIONS) logSurface(w,
8347 "SHOW (performLayout)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008348 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008349 + " during relayout");
8350 if (showSurfaceRobustlyLocked(w)) {
8351 w.mHasDrawn = true;
8352 w.mLastHidden = false;
8353 } else {
8354 w.mOrientationChanging = false;
8355 }
8356 }
8357 if (w.mSurface != null) {
8358 w.mToken.hasVisible = true;
8359 }
8360 } else {
8361 displayed = true;
8362 }
8363
8364 if (displayed) {
8365 if (!covered) {
Romain Guy980a9382010-01-08 15:06:28 -08008366 if (attrs.width == LayoutParams.MATCH_PARENT
8367 && attrs.height == LayoutParams.MATCH_PARENT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008368 covered = true;
8369 }
8370 }
8371 if (w.mOrientationChanging) {
8372 if (w.mDrawPending || w.mCommitDrawPending) {
8373 orientationChangeComplete = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008374 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008375 "Orientation continue waiting for draw in " + w);
8376 } else {
8377 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008378 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008379 "Orientation change complete in " + w);
8380 }
8381 }
8382 w.mToken.hasVisible = true;
8383 }
8384 } else if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008385 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008386 "Orientation change skips hidden " + w);
8387 w.mOrientationChanging = false;
8388 }
8389
Dianne Hackborn0f761d62010-11-30 22:06:10 -08008390 if (w.mContentChanged) {
8391 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
8392 w.mContentChanged = false;
8393 }
8394
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008395 final boolean canBeSeen = w.isDisplayedLw();
8396
8397 if (someoneLosingFocus && w == mCurrentFocus && canBeSeen) {
8398 focusDisplayed = true;
8399 }
8400
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07008401 final boolean obscuredChanged = w.mObscured != obscured;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008403 // Update effect.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008404 if (!(w.mObscured=obscured)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008405 if (w.mSurface != null) {
8406 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
8407 holdScreen = w.mSession;
8408 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07008409 if (!syswin && w.mAttrs.screenBrightness >= 0
8410 && screenBrightness < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008411 screenBrightness = w.mAttrs.screenBrightness;
8412 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05008413 if (!syswin && w.mAttrs.buttonBrightness >= 0
8414 && buttonBrightness < 0) {
8415 buttonBrightness = w.mAttrs.buttonBrightness;
8416 }
Mike Lockwood46af6a82010-03-09 08:28:22 -05008417 if (canBeSeen
8418 && (attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
8419 || attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD
8420 || attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_ERROR)) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07008421 syswin = true;
8422 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008423 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008424
Dianne Hackborn25994b42009-09-04 14:21:19 -07008425 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008426 if (opaqueDrawn && w.isFullscreen(innerDw, innerDh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008427 // This window completely covers everything behind it,
8428 // so we want to leave all of them as unblurred (for
8429 // performance reasons).
8430 obscured = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008431 } else if (canBeSeen && !obscured &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008432 (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008433 if (localLOGV) Slog.v(TAG, "Win " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008434 + ": blurring=" + blurring
8435 + " obscured=" + obscured
8436 + " displayed=" + displayed);
8437 if ((attrFlags&FLAG_DIM_BEHIND) != 0) {
8438 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008439 //Slog.i(TAG, "DIM BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008440 dimming = true;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07008441 if (mDimAnimator == null) {
8442 mDimAnimator = new DimAnimator(mFxSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008443 }
Dianne Hackborn48a76512011-06-08 21:51:44 -07008444 mDimAnimator.show(innerDw, innerDh);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008445 mDimAnimator.updateParameters(mContext.getResources(),
8446 w, currentTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008447 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008448 }
8449 if ((attrFlags&FLAG_BLUR_BEHIND) != 0) {
8450 if (!blurring) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008451 //Slog.i(TAG, "BLUR BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008452 blurring = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008453 if (mBlurSurface == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008454 try {
Romain Guy06882f82009-06-10 13:36:04 -07008455 mBlurSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08008456 "BlurSurface",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008457 -1, 16, 16,
8458 PixelFormat.OPAQUE,
8459 Surface.FX_SURFACE_BLUR);
8460 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008461 Slog.e(TAG, "Exception creating Blur surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008462 }
Dianne Hackbornac1471a2011-02-03 13:46:06 -08008463 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
8464 + mBlurSurface + ": CREATE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008465 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008466 if (mBlurSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -07008467 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
8468 + mBlurSurface + ": pos=(0,0) (" +
8469 dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008470 mBlurSurface.setPosition(0, 0);
8471 mBlurSurface.setSize(dw, dh);
Dianne Hackbornde75cb42011-03-02 17:11:21 -08008472 mBlurSurface.setLayer(w.mAnimLayer-LAYER_OFFSET_BLUR);
Dianne Hackborn16064f92010-03-25 00:47:24 -07008473 if (!mBlurShown) {
8474 try {
8475 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
8476 + mBlurSurface + ": SHOW");
8477 mBlurSurface.show();
8478 } catch (RuntimeException e) {
8479 Slog.w(TAG, "Failure showing blur surface", e);
8480 }
8481 mBlurShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008482 }
8483 }
8484 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008485 }
8486 }
8487 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008488
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07008489 if (obscuredChanged && mWallpaperTarget == w) {
8490 // This is the wallpaper target and its obscured state
8491 // changed... make sure the current wallaper's visibility
8492 // has been updated accordingly.
8493 updateWallpaperVisibilityLocked();
8494 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008495 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008496
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07008497 if (mDimAnimator != null && mDimAnimator.mDimShown) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008498 animating |= mDimAnimator.updateSurface(dimming, currentTime,
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07008499 mDisplayFrozen || !mDisplayEnabled || !mPolicy.isScreenOnFully());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008500 }
Romain Guy06882f82009-06-10 13:36:04 -07008501
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008502 if (!blurring && mBlurShown) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008503 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR " + mBlurSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008504 + ": HIDE");
8505 try {
8506 mBlurSurface.hide();
8507 } catch (IllegalArgumentException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008508 Slog.w(TAG, "Illegal argument exception hiding blur surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008509 }
8510 mBlurShown = false;
8511 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07008512
8513 if (mBlackFrame != null) {
8514 if (mScreenRotationAnimation != null) {
8515 mBlackFrame.setMatrix(
8516 mScreenRotationAnimation.getEnterTransformation().getMatrix());
8517 } else {
8518 mBlackFrame.clearMatrix();
8519 }
8520 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008521 } catch (RuntimeException e) {
Dianne Hackborn89620282011-09-11 12:47:45 -07008522 Log.wtf(TAG, "Unhandled exception in Window Manager", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008523 }
8524
8525 Surface.closeTransaction();
Romain Guy06882f82009-06-10 13:36:04 -07008526
Dianne Hackborn36991742011-10-11 21:35:26 -07008527 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
8528 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008529
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07008530 if (mWatermark != null) {
8531 mWatermark.drawIfNeeded();
8532 }
8533
Joe Onorato8a9b2202010-02-26 18:56:32 -08008534 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008535 "With display frozen, orientationChangeComplete="
8536 + orientationChangeComplete);
8537 if (orientationChangeComplete) {
8538 if (mWindowsFreezingScreen) {
8539 mWindowsFreezingScreen = false;
8540 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
8541 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008542 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008543 }
Romain Guy06882f82009-06-10 13:36:04 -07008544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008545 i = mResizingWindows.size();
8546 if (i > 0) {
8547 do {
8548 i--;
8549 WindowState win = mResizingWindows.get(i);
8550 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -08008551 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07008552 "Reporting new frame to " + win + ": " + win.mCompatFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -07008553 int diff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008554 boolean configChanged =
8555 win.mConfiguration != mCurConfiguration
8556 && (win.mConfiguration == null
Dianne Hackborn694f79b2010-03-17 19:44:59 -07008557 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0);
8558 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
8559 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008560 Slog.i(TAG, "Sending new config to window " + win + ": "
Dianne Hackbornb961cd22011-06-21 12:13:37 -07008561 + win.mSurfaceW + "x" + win.mSurfaceH
Dianne Hackborn694f79b2010-03-17 19:44:59 -07008562 + " / " + mCurConfiguration + " / 0x"
8563 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008564 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07008565 win.mConfiguration = mCurConfiguration;
Dianne Hackbornd040edb2011-08-31 12:47:58 -07008566 win.mClient.resized((int)win.mSurfaceW, (int)win.mSurfaceH,
8567 win.mLastContentInsets, win.mLastVisibleInsets, win.mDrawPending,
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008568 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008569 win.mContentInsetsChanged = false;
8570 win.mVisibleInsetsChanged = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -08008571 win.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008572 } catch (RemoteException e) {
8573 win.mOrientationChanging = false;
8574 }
8575 } while (i > 0);
8576 mResizingWindows.clear();
8577 }
Romain Guy06882f82009-06-10 13:36:04 -07008578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008579 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008580 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008581 i = mDestroySurface.size();
8582 if (i > 0) {
8583 do {
8584 i--;
8585 WindowState win = mDestroySurface.get(i);
8586 win.mDestroying = false;
8587 if (mInputMethodWindow == win) {
8588 mInputMethodWindow = null;
8589 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008590 if (win == mWallpaperTarget) {
8591 wallpaperDestroyed = true;
8592 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008593 win.destroySurfaceLocked();
8594 } while (i > 0);
8595 mDestroySurface.clear();
8596 }
8597
8598 // Time to remove any exiting tokens?
8599 for (i=mExitingTokens.size()-1; i>=0; i--) {
8600 WindowToken token = mExitingTokens.get(i);
8601 if (!token.hasVisible) {
8602 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07008603 if (token.windowType == TYPE_WALLPAPER) {
8604 mWallpaperTokens.remove(token);
8605 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008606 }
8607 }
8608
8609 // Time to remove any exiting applications?
8610 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
8611 AppWindowToken token = mExitingAppTokens.get(i);
8612 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008613 // Make sure there is no animation running on this token,
8614 // so any windows associated with it will be removed as
8615 // soon as their animations are complete
8616 token.animation = null;
8617 token.animating = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008618 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
8619 "performLayout: App token exiting now removed" + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008620 mAppTokens.remove(token);
8621 mExitingAppTokens.remove(i);
8622 }
8623 }
8624
Dianne Hackborna8f60182009-09-01 19:01:50 -07008625 boolean needRelayout = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008626
Dianne Hackborna8f60182009-09-01 19:01:50 -07008627 if (!animating && mAppTransitionRunning) {
8628 // We have finished the animation of an app transition. To do
8629 // this, we have delayed a lot of operations like showing and
8630 // hiding apps, moving apps in Z-order, etc. The app token list
8631 // reflects the correct Z-order, but the window list may now
8632 // be out of sync with it. So here we will just rebuild the
8633 // entire app window list. Fun!
8634 mAppTransitionRunning = false;
8635 needRelayout = true;
8636 rebuildAppWindowListLocked();
Dianne Hackborn16064f92010-03-25 00:47:24 -07008637 assignLayersLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07008638 // Clear information about apps that were moving.
8639 mToBottomApps.clear();
8640 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008642 if (focusDisplayed) {
8643 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
8644 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008645 if (wallpaperDestroyed) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008646 needRelayout = adjustWallpaperWindowsLocked() != 0;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008647 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07008648 if (needRelayout) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008649 requestAnimationLocked(0);
8650 } else if (animating) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008651 requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
8652 }
Jeff Browneb857f12010-07-16 10:06:33 -07008653
Jeff Brown3a22cd92011-01-21 13:59:04 -08008654 // Finally update all input windows now that the window changes have stabilized.
Jeff Brown2e44b072011-01-24 15:21:56 -08008655 mInputMonitor.updateInputWindowsLw(true /*force*/);
Jeff Browneb857f12010-07-16 10:06:33 -07008656
Jeff Brown8e03b752010-06-13 19:16:55 -07008657 setHoldScreenLocked(holdScreen != null);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08008658 if (!mDisplayFrozen) {
8659 if (screenBrightness < 0 || screenBrightness > 1.0f) {
8660 mPowerManager.setScreenBrightnessOverride(-1);
8661 } else {
8662 mPowerManager.setScreenBrightnessOverride((int)
8663 (screenBrightness * Power.BRIGHTNESS_ON));
8664 }
8665 if (buttonBrightness < 0 || buttonBrightness > 1.0f) {
8666 mPowerManager.setButtonBrightnessOverride(-1);
8667 } else {
8668 mPowerManager.setButtonBrightnessOverride((int)
8669 (buttonBrightness * Power.BRIGHTNESS_ON));
8670 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05008671 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008672 if (holdScreen != mHoldingScreenOn) {
8673 mHoldingScreenOn = holdScreen;
8674 Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
8675 mH.sendMessage(m);
8676 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008677
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008678 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008679 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008680 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
8681 LocalPowerManager.BUTTON_EVENT, true);
8682 mTurnOnScreen = false;
8683 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08008684
Dianne Hackborn50660e22011-02-02 17:12:25 -08008685 if (screenRotationFinished && mScreenRotationAnimation != null) {
8686 mScreenRotationAnimation.kill();
8687 mScreenRotationAnimation = null;
8688 }
8689
Dianne Hackborn89ba6752011-01-23 16:51:16 -08008690 if (updateRotation) {
8691 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Jeff Brown01a98dd2011-09-20 15:08:29 -07008692 boolean changed = updateRotationUncheckedLocked(false);
Dianne Hackborn89ba6752011-01-23 16:51:16 -08008693 if (changed) {
Dianne Hackborn3e4f9d02011-02-04 14:05:55 -08008694 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07008695 } else {
8696 updateRotation = false;
Dianne Hackborn89ba6752011-01-23 16:51:16 -08008697 }
8698 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07008699
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07008700 if (orientationChangeComplete && !needRelayout && !updateRotation) {
8701 checkDrawnWindowsLocked();
8702 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07008703
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08008704 // Check to see if we are now in a state where the screen should
8705 // be enabled, because the window obscured flags have changed.
8706 enableScreenIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008707 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07008708
Dianne Hackborn38e29a62011-09-18 14:43:08 -07008709 void checkDrawnWindowsLocked() {
8710 if (mWaitingForDrawn.size() > 0) {
8711 for (int j=mWaitingForDrawn.size()-1; j>=0; j--) {
8712 Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(j);
8713 WindowState win = pair.first;
8714 //Slog.i(TAG, "Waiting for drawn " + win + ": removed="
8715 // + win.mRemoved + " visible=" + win.isVisibleLw()
8716 // + " shown=" + win.mSurfaceShown);
8717 if (win.mRemoved || !win.isVisibleLw()) {
8718 // Window has been removed or made invisible; no draw
8719 // will now happen, so stop waiting.
8720 Slog.w(TAG, "Aborted waiting for drawn: " + pair.first);
8721 try {
8722 pair.second.sendResult(null);
8723 } catch (RemoteException e) {
8724 }
8725 mWaitingForDrawn.remove(pair);
8726 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
8727 } else if (win.mSurfaceShown) {
8728 // Window is now drawn (and shown).
8729 try {
8730 pair.second.sendResult(null);
8731 } catch (RemoteException e) {
8732 }
8733 mWaitingForDrawn.remove(pair);
8734 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
8735 }
8736 }
8737 }
8738 }
8739
8740 public void waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07008741 synchronized (mWindowMap) {
Dianne Hackborn38e29a62011-09-18 14:43:08 -07008742 WindowState win = windowForClientLocked(null, token, true);
8743 if (win != null) {
8744 Pair<WindowState, IRemoteCallback> pair =
8745 new Pair<WindowState, IRemoteCallback>(win, callback);
8746 Message m = mH.obtainMessage(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
8747 mH.sendMessageDelayed(m, 2000);
8748 mWaitingForDrawn.add(pair);
8749 checkDrawnWindowsLocked();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07008750 }
8751 }
8752 }
8753
Jeff Brown46b9ac02010-04-22 18:58:52 -07008754 /**
8755 * Must be called with the main window manager lock held.
8756 */
8757 void setHoldScreenLocked(boolean holding) {
8758 boolean state = mHoldingScreenWakeLock.isHeld();
8759 if (holding != state) {
8760 if (holding) {
Daniel Sandler0601eb72011-04-13 01:01:32 -04008761 mPolicy.screenOnStartedLw();
Jeff Brown46b9ac02010-04-22 18:58:52 -07008762 mHoldingScreenWakeLock.acquire();
8763 } else {
8764 mPolicy.screenOnStoppedLw();
8765 mHoldingScreenWakeLock.release();
8766 }
8767 }
8768 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008769
8770 void requestAnimationLocked(long delay) {
8771 if (!mAnimationPending) {
8772 mAnimationPending = true;
8773 mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
8774 }
8775 }
Romain Guy06882f82009-06-10 13:36:04 -07008776
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008777 /**
8778 * Have the surface flinger show a surface, robustly dealing with
8779 * error conditions. In particular, if there is not enough memory
8780 * to show the surface, then we will try to get rid of other surfaces
8781 * in order to succeed.
Romain Guy06882f82009-06-10 13:36:04 -07008782 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008783 * @return Returns true if the surface was successfully shown.
8784 */
8785 boolean showSurfaceRobustlyLocked(WindowState win) {
8786 try {
8787 if (win.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -07008788 win.mSurfaceShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008789 win.mSurface.show();
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008790 if (win.mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008791 if (DEBUG_VISIBILITY) Slog.v(TAG,
8792 "Show surface turning screen on: " + win);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008793 win.mTurnOnScreen = false;
8794 mTurnOnScreen = true;
8795 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008796 }
8797 return true;
8798 } catch (RuntimeException e) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008799 Slog.w(TAG, "Failure showing surface " + win.mSurface + " in " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008800 }
Romain Guy06882f82009-06-10 13:36:04 -07008801
Dianne Hackborn64825172011-03-02 21:32:58 -08008802 reclaimSomeSurfaceMemoryLocked(win, "show", true);
Romain Guy06882f82009-06-10 13:36:04 -07008803
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008804 return false;
8805 }
Romain Guy06882f82009-06-10 13:36:04 -07008806
Dianne Hackborn64825172011-03-02 21:32:58 -08008807 boolean reclaimSomeSurfaceMemoryLocked(WindowState win, String operation, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008808 final Surface surface = win.mSurface;
Dianne Hackborn64825172011-03-02 21:32:58 -08008809 boolean leakedSurface = false;
8810 boolean killedApps = false;
Romain Guy06882f82009-06-10 13:36:04 -07008811
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008812 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, win.toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008813 win.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -07008814
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008815 if (mForceRemoves == null) {
8816 mForceRemoves = new ArrayList<WindowState>();
8817 }
Romain Guy06882f82009-06-10 13:36:04 -07008818
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008819 long callingIdentity = Binder.clearCallingIdentity();
8820 try {
8821 // There was some problem... first, do a sanity check of the
8822 // window list to make sure we haven't left any dangling surfaces
8823 // around.
8824 int N = mWindows.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08008825 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008826 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07008827 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008828 if (ws.mSurface != null) {
8829 if (!mSessions.contains(ws.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008830 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008831 + ws + " surface=" + ws.mSurface
8832 + " token=" + win.mToken
8833 + " pid=" + ws.mSession.mPid
8834 + " uid=" + ws.mSession.mUid);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008835 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008836 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -07008837 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008838 ws.mSurface = null;
8839 mForceRemoves.add(ws);
8840 i--;
8841 N--;
8842 leakedSurface = true;
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008843 } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008844 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008845 + ws + " surface=" + ws.mSurface
8846 + " token=" + win.mAppToken);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008847 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008848 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -07008849 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008850 ws.mSurface = null;
8851 leakedSurface = true;
8852 }
8853 }
8854 }
Romain Guy06882f82009-06-10 13:36:04 -07008855
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008856 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008857 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008858 SparseIntArray pidCandidates = new SparseIntArray();
8859 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07008860 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008861 if (ws.mSurface != null) {
8862 pidCandidates.append(ws.mSession.mPid, ws.mSession.mPid);
8863 }
8864 }
8865 if (pidCandidates.size() > 0) {
8866 int[] pids = new int[pidCandidates.size()];
8867 for (int i=0; i<pids.length; i++) {
8868 pids[i] = pidCandidates.keyAt(i);
8869 }
8870 try {
Dianne Hackborn64825172011-03-02 21:32:58 -08008871 if (mActivityManager.killPids(pids, "Free memory", secure)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008872 killedApps = true;
8873 }
8874 } catch (RemoteException e) {
8875 }
8876 }
8877 }
Romain Guy06882f82009-06-10 13:36:04 -07008878
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008879 if (leakedSurface || killedApps) {
8880 // We managed to reclaim some memory, so get rid of the trouble
8881 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -08008882 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008883 if (surface != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -07008884 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(win,
8885 "RECOVER DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008886 surface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -07008887 win.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008888 win.mSurface = null;
8889 }
Romain Guy06882f82009-06-10 13:36:04 -07008890
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008891 try {
8892 win.mClient.dispatchGetNewSurface();
8893 } catch (RemoteException e) {
8894 }
8895 }
8896 } finally {
8897 Binder.restoreCallingIdentity(callingIdentity);
8898 }
Dianne Hackborn64825172011-03-02 21:32:58 -08008899
8900 return leakedSurface || killedApps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008901 }
Romain Guy06882f82009-06-10 13:36:04 -07008902
Jeff Brown3a22cd92011-01-21 13:59:04 -08008903 private boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008904 WindowState newFocus = computeFocusedWindowLocked();
8905 if (mCurrentFocus != newFocus) {
8906 // This check makes sure that we don't already have the focus
8907 // change message pending.
8908 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
8909 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008910 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008911 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
8912 final WindowState oldFocus = mCurrentFocus;
8913 mCurrentFocus = newFocus;
8914 mLosingFocus.remove(newFocus);
Dianne Hackborndf89e652011-10-06 22:35:11 -07008915 int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus);
Romain Guy06882f82009-06-10 13:36:04 -07008916
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008917 final WindowState imWindow = mInputMethodWindow;
8918 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08008919 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008920 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08008921 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
8922 mLayoutNeeded = true;
8923 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008924 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08008925 performLayoutLockedInner(true /*initial*/, updateInputWindows);
Dianne Hackborndf89e652011-10-06 22:35:11 -07008926 focusChanged &= ~WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08008927 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
8928 // Client will do the layout, but we need to assign layers
8929 // for handleNewWindowLocked() below.
8930 assignLayersLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008931 }
8932 }
Dianne Hackborndf89e652011-10-06 22:35:11 -07008933
8934 if ((focusChanged&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
8935 // The change in focus caused us to need to do a layout. Okay.
8936 mLayoutNeeded = true;
8937 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
8938 performLayoutLockedInner(true /*initial*/, updateInputWindows);
8939 }
8940 }
8941
Jeff Brown349703e2010-06-22 01:27:15 -07008942 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
8943 // If we defer assigning layers, then the caller is responsible for
8944 // doing this part.
Jeff Brown3a22cd92011-01-21 13:59:04 -08008945 finishUpdateFocusedWindowAfterAssignLayersLocked(updateInputWindows);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08008946 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008947 return true;
8948 }
8949 return false;
8950 }
Jeff Brown349703e2010-06-22 01:27:15 -07008951
Jeff Brown3a22cd92011-01-21 13:59:04 -08008952 private void finishUpdateFocusedWindowAfterAssignLayersLocked(boolean updateInputWindows) {
8953 mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows);
Jeff Brown349703e2010-06-22 01:27:15 -07008954 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008955
8956 private WindowState computeFocusedWindowLocked() {
8957 WindowState result = null;
8958 WindowState win;
8959
8960 int i = mWindows.size() - 1;
8961 int nextAppIndex = mAppTokens.size()-1;
8962 WindowToken nextApp = nextAppIndex >= 0
8963 ? mAppTokens.get(nextAppIndex) : null;
8964
8965 while (i >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07008966 win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008967
Joe Onorato8a9b2202010-02-26 18:56:32 -08008968 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008969 TAG, "Looking for focus: " + i
8970 + " = " + win
8971 + ", flags=" + win.mAttrs.flags
8972 + ", canReceive=" + win.canReceiveKeys());
8973
8974 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -07008975
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008976 // If this window's application has been removed, just skip it.
8977 if (thisApp != null && thisApp.removed) {
8978 i--;
8979 continue;
8980 }
Romain Guy06882f82009-06-10 13:36:04 -07008981
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008982 // If there is a focused app, don't allow focus to go to any
8983 // windows below it. If this is an application window, step
8984 // through the app tokens until we find its app.
8985 if (thisApp != null && nextApp != null && thisApp != nextApp
8986 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
8987 int origAppIndex = nextAppIndex;
8988 while (nextAppIndex > 0) {
8989 if (nextApp == mFocusedApp) {
8990 // Whoops, we are below the focused app... no focus
8991 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -08008992 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008993 TAG, "Reached focused app: " + mFocusedApp);
8994 return null;
8995 }
8996 nextAppIndex--;
8997 nextApp = mAppTokens.get(nextAppIndex);
8998 if (nextApp == thisApp) {
8999 break;
9000 }
9001 }
9002 if (thisApp != nextApp) {
9003 // Uh oh, the app token doesn't exist! This shouldn't
9004 // happen, but if it does we can get totally hosed...
9005 // so restart at the original app.
9006 nextAppIndex = origAppIndex;
9007 nextApp = mAppTokens.get(nextAppIndex);
9008 }
9009 }
9010
9011 // Dispatch to this window if it is wants key events.
9012 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009013 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009014 TAG, "Found focus @ " + i + " = " + win);
9015 result = win;
9016 break;
9017 }
9018
9019 i--;
9020 }
9021
9022 return result;
9023 }
9024
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08009025 private void startFreezingDisplayLocked(boolean inTransaction) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009026 if (mDisplayFrozen) {
9027 return;
9028 }
Romain Guy06882f82009-06-10 13:36:04 -07009029
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07009030 if (mDisplay == null || !mPolicy.isScreenOnFully()) {
Dianne Hackborn8e8d65f2011-08-11 19:36:18 -07009031 // No need to freeze the screen before the system is ready or if
9032 // the screen is off.
9033 return;
9034 }
9035
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009036 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -07009037
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009038 mDisplayFrozen = true;
Jeff Brown349703e2010-06-22 01:27:15 -07009039
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009040 mInputMonitor.freezeInputDispatchingLw();
Jeff Brown349703e2010-06-22 01:27:15 -07009041
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009042 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
9043 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009044 mNextAppTransitionPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009045 mAppTransitionReady = true;
9046 }
Romain Guy06882f82009-06-10 13:36:04 -07009047
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009048 if (PROFILE_ORIENTATION) {
9049 File file = new File("/data/system/frozen");
9050 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
9051 }
Dianne Hackborna1111872010-11-23 20:55:11 -08009052
9053 if (CUSTOM_SCREEN_ROTATION) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08009054 if (mScreenRotationAnimation != null && mScreenRotationAnimation.isAnimating()) {
9055 mScreenRotationAnimation.kill();
9056 mScreenRotationAnimation = null;
9057 }
Dianne Hackborna1111872010-11-23 20:55:11 -08009058 if (mScreenRotationAnimation == null) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08009059 mScreenRotationAnimation = new ScreenRotationAnimation(mContext,
Jeff Brownbc68a592011-07-25 12:58:12 -07009060 mFxSession, inTransaction, mCurDisplayWidth, mCurDisplayHeight,
9061 mDisplay.getRotation());
Dianne Hackborna1111872010-11-23 20:55:11 -08009062 }
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009063 if (!mScreenRotationAnimation.hasScreenshot()) {
9064 Surface.freezeDisplay(0);
9065 }
Dianne Hackborna1111872010-11-23 20:55:11 -08009066 } else {
9067 Surface.freezeDisplay(0);
9068 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009069 }
Romain Guy06882f82009-06-10 13:36:04 -07009070
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009071 private void stopFreezingDisplayLocked() {
9072 if (!mDisplayFrozen) {
9073 return;
9074 }
Romain Guy06882f82009-06-10 13:36:04 -07009075
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009076 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
9077 return;
9078 }
9079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009080 mDisplayFrozen = false;
9081 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
9082 if (PROFILE_ORIENTATION) {
9083 Debug.stopMethodTracing();
9084 }
Dianne Hackborna1111872010-11-23 20:55:11 -08009085
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009086 boolean updateRotation = false;
9087
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009088 if (CUSTOM_SCREEN_ROTATION && mScreenRotationAnimation != null
9089 && mScreenRotationAnimation.hasScreenshot()) {
9090 if (mScreenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
Jeff Brownbc68a592011-07-25 12:58:12 -07009091 mTransitionAnimationScale, mCurDisplayWidth, mCurDisplayHeight)) {
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009092 requestAnimationLocked(0);
9093 } else {
9094 mScreenRotationAnimation = null;
9095 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -08009096 }
9097 } else {
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009098 if (mScreenRotationAnimation != null) {
9099 mScreenRotationAnimation.kill();
9100 mScreenRotationAnimation = null;
9101 }
9102 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -08009103 }
Dianne Hackborn161dc802011-10-04 19:18:25 -07009104 Surface.unfreezeDisplay(0);
Romain Guy06882f82009-06-10 13:36:04 -07009105
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009106 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009107
Dianne Hackborn420829e2011-01-28 11:30:35 -08009108 boolean configChanged;
9109
Christopher Tateb696aee2010-04-02 19:08:30 -07009110 // While the display is frozen we don't re-compute the orientation
9111 // to avoid inconsistent states. However, something interesting
9112 // could have actually changed during that time so re-evaluate it
9113 // now to catch that.
Dianne Hackborn420829e2011-01-28 11:30:35 -08009114 configChanged = updateOrientationFromAppTokensLocked(false);
Christopher Tateb696aee2010-04-02 19:08:30 -07009115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009116 // A little kludge: a lot could have happened while the
9117 // display was frozen, so now that we are coming back we
9118 // do a gc so that any remote references the system
9119 // processes holds on others can be released if they are
9120 // no longer needed.
9121 mH.removeMessages(H.FORCE_GC);
9122 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
9123 2000);
Romain Guy06882f82009-06-10 13:36:04 -07009124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009125 mScreenFrozenLock.release();
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009126
9127 if (updateRotation) {
9128 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Jeff Brown01a98dd2011-09-20 15:08:29 -07009129 configChanged |= updateRotationUncheckedLocked(false);
Dianne Hackborn420829e2011-01-28 11:30:35 -08009130 }
9131
9132 if (configChanged) {
9133 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009134 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009135 }
Romain Guy06882f82009-06-10 13:36:04 -07009136
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07009137 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
9138 DisplayMetrics dm) {
9139 if (index < tokens.length) {
9140 String str = tokens[index];
9141 if (str != null && str.length() > 0) {
9142 try {
9143 int val = Integer.parseInt(str);
9144 return val;
9145 } catch (Exception e) {
9146 }
9147 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009148 }
9149 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
9150 return defDps;
9151 }
9152 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
9153 return val;
9154 }
9155
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009156 void createWatermark() {
9157 if (mWatermark != null) {
9158 return;
9159 }
9160
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07009161 File file = new File("/system/etc/setup.conf");
9162 FileInputStream in = null;
9163 try {
9164 in = new FileInputStream(file);
9165 DataInputStream ind = new DataInputStream(in);
9166 String line = ind.readLine();
9167 if (line != null) {
9168 String[] toks = line.split("%");
9169 if (toks != null && toks.length > 0) {
Jeff Brownbc68a592011-07-25 12:58:12 -07009170 mWatermark = new Watermark(mRealDisplayMetrics, mFxSession, toks);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07009171 }
9172 }
9173 } catch (FileNotFoundException e) {
9174 } catch (IOException e) {
9175 } finally {
9176 if (in != null) {
9177 try {
9178 in.close();
9179 } catch (IOException e) {
9180 }
9181 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009182 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009183 }
9184
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009185 @Override
Joe Onorato664644d2011-01-23 17:53:23 -08009186 public void statusBarVisibilityChanged(int visibility) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07009187 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
9188 != PackageManager.PERMISSION_GRANTED) {
9189 throw new SecurityException("Caller does not hold permission "
9190 + android.Manifest.permission.STATUS_BAR);
9191 }
Dianne Hackborn9a230e02011-10-06 11:51:27 -07009192
Joe Onorato664644d2011-01-23 17:53:23 -08009193 synchronized (mWindowMap) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07009194 mLastStatusBarVisibility = visibility;
9195 visibility = mPolicy.adjustSystemUiVisibilityLw(visibility);
9196 updateStatusBarVisibilityLocked(visibility);
9197 }
9198 }
9199
9200 void updateStatusBarVisibilityLocked(int visibility) {
9201 mInputManager.setSystemUiVisibility(visibility);
9202 final int N = mWindows.size();
9203 for (int i = 0; i < N; i++) {
9204 WindowState ws = mWindows.get(i);
9205 try {
9206 int curValue = ws.mSystemUiVisibility;
9207 int diff = curValue ^ visibility;
9208 // We are only interested in differences of one of the
9209 // clearable flags...
9210 diff &= View.SYSTEM_UI_CLEARABLE_FLAGS;
9211 // ...if it has actually been cleared.
9212 diff &= ~visibility;
9213 int newValue = (curValue&~diff) | (visibility&diff);
9214 if (newValue != curValue) {
9215 ws.mSeq++;
9216 ws.mSystemUiVisibility = newValue;
9217 }
9218 if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) {
9219 ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq,
9220 visibility, newValue, diff);
9221 }
9222 } catch (RemoteException e) {
9223 // so sorry
9224 }
9225 }
9226 }
9227
9228 @Override
9229 public void reevaluateStatusBarVisibility() {
9230 synchronized (mWindowMap) {
9231 int visibility = mPolicy.adjustSystemUiVisibilityLw(mLastStatusBarVisibility);
9232 updateStatusBarVisibilityLocked(visibility);
9233 performLayoutAndPlaceSurfacesLocked();
9234 }
9235 }
9236
9237 @Override
9238 public FakeWindow addFakeWindow(Looper looper, InputHandler inputHandler,
9239 String name, int windowType, int layoutParamsFlags, boolean canReceiveKeys,
9240 boolean hasFocus, boolean touchFullscreen) {
9241 synchronized (mWindowMap) {
9242 FakeWindowImpl fw = new FakeWindowImpl(this, looper, inputHandler, name, windowType,
9243 layoutParamsFlags, canReceiveKeys, hasFocus, touchFullscreen);
9244 int i=0;
9245 while (i<mFakeWindows.size()) {
9246 if (mFakeWindows.get(i).mWindowLayer <= fw.mWindowLayer) {
9247 break;
Joe Onorato664644d2011-01-23 17:53:23 -08009248 }
9249 }
Dianne Hackborndf89e652011-10-06 22:35:11 -07009250 mFakeWindows.add(i, fw);
9251 mInputMonitor.updateInputWindowsLw(true);
9252 return fw;
9253 }
9254 }
9255
9256 boolean removeFakeWindowLocked(FakeWindow window) {
9257 synchronized (mWindowMap) {
9258 if (mFakeWindows.remove(window)) {
9259 mInputMonitor.updateInputWindowsLw(true);
9260 return true;
9261 }
9262 return false;
Joe Onorato664644d2011-01-23 17:53:23 -08009263 }
9264 }
9265
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009266 void dumpInput(FileDescriptor fd, PrintWriter pw, boolean dumpAll) {
9267 pw.println("WINDOW MANAGER INPUT (dumpsys window input)");
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009268 mInputManager.dump(pw);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009269 }
9270
9271 void dumpPolicyLocked(FileDescriptor fd, PrintWriter pw, String[] args, boolean dumpAll) {
9272 pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
9273 mPolicy.dump(" ", fd, pw, args);
9274 }
9275
9276 void dumpTokensLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll) {
9277 pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
9278 if (mTokenMap.size() > 0) {
9279 pw.println(" All tokens:");
9280 Iterator<WindowToken> it = mTokenMap.values().iterator();
9281 while (it.hasNext()) {
9282 WindowToken token = it.next();
9283 pw.print(" Token "); pw.print(token.token);
9284 if (dumpAll) {
9285 pw.println(':');
9286 token.dump(pw, " ");
9287 } else {
9288 pw.println();
9289 }
9290 }
9291 }
9292 if (mWallpaperTokens.size() > 0) {
9293 pw.println();
9294 pw.println(" Wallpaper tokens:");
9295 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
9296 WindowToken token = mWallpaperTokens.get(i);
9297 pw.print(" Wallpaper #"); pw.print(i);
9298 pw.print(' '); pw.print(token);
9299 if (dumpAll) {
9300 pw.println(':');
9301 token.dump(pw, " ");
9302 } else {
9303 pw.println();
9304 }
9305 }
9306 }
9307 if (mAppTokens.size() > 0) {
9308 pw.println();
9309 pw.println(" Application tokens in Z order:");
9310 for (int i=mAppTokens.size()-1; i>=0; i--) {
9311 pw.print(" App #"); pw.print(i); pw.print(": ");
9312 pw.println(mAppTokens.get(i));
9313 }
9314 }
9315 if (mFinishedStarting.size() > 0) {
9316 pw.println();
9317 pw.println(" Finishing start of application tokens:");
9318 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
9319 WindowToken token = mFinishedStarting.get(i);
9320 pw.print(" Finished Starting #"); pw.print(i);
9321 pw.print(' '); pw.print(token);
9322 if (dumpAll) {
9323 pw.println(':');
9324 token.dump(pw, " ");
9325 } else {
9326 pw.println();
9327 }
9328 }
9329 }
9330 if (mExitingTokens.size() > 0) {
9331 pw.println();
9332 pw.println(" Exiting tokens:");
9333 for (int i=mExitingTokens.size()-1; i>=0; i--) {
9334 WindowToken token = mExitingTokens.get(i);
9335 pw.print(" Exiting #"); pw.print(i);
9336 pw.print(' '); pw.print(token);
9337 if (dumpAll) {
9338 pw.println(':');
9339 token.dump(pw, " ");
9340 } else {
9341 pw.println();
9342 }
9343 }
9344 }
9345 if (mExitingAppTokens.size() > 0) {
9346 pw.println();
9347 pw.println(" Exiting application tokens:");
9348 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
9349 WindowToken token = mExitingAppTokens.get(i);
9350 pw.print(" Exiting App #"); pw.print(i);
9351 pw.print(' '); pw.print(token);
9352 if (dumpAll) {
9353 pw.println(':');
9354 token.dump(pw, " ");
9355 } else {
9356 pw.println();
9357 }
9358 }
9359 }
9360 pw.println();
9361 if (mOpeningApps.size() > 0) {
9362 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
9363 }
9364 if (mClosingApps.size() > 0) {
9365 pw.print(" mClosingApps="); pw.println(mClosingApps);
9366 }
9367 if (mToTopApps.size() > 0) {
9368 pw.print(" mToTopApps="); pw.println(mToTopApps);
9369 }
9370 if (mToBottomApps.size() > 0) {
9371 pw.print(" mToBottomApps="); pw.println(mToBottomApps);
9372 }
9373 }
9374
9375 void dumpSessionsLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll) {
9376 pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
9377 if (mSessions.size() > 0) {
9378 Iterator<Session> it = mSessions.iterator();
9379 while (it.hasNext()) {
9380 Session s = it.next();
9381 pw.print(" Session "); pw.print(s); pw.println(':');
9382 s.dump(pw, " ");
9383 }
9384 }
9385 }
9386
9387 void dumpWindowsLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
9388 ArrayList<WindowState> windows) {
9389 pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)");
9390 for (int i=mWindows.size()-1; i>=0; i--) {
9391 WindowState w = mWindows.get(i);
9392 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009393 pw.print(" Window #"); pw.print(i); pw.print(' ');
9394 pw.print(w); pw.println(":");
Dianne Hackborn89620282011-09-11 12:47:45 -07009395 w.dump(pw, " ", dumpAll || windows != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009396 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009397 }
9398 if (mInputMethodDialogs.size() > 0) {
9399 pw.println();
9400 pw.println(" Input method dialogs:");
9401 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
9402 WindowState w = mInputMethodDialogs.get(i);
9403 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009404 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009405 }
9406 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009407 }
9408 if (mPendingRemove.size() > 0) {
9409 pw.println();
9410 pw.println(" Remove pending for:");
9411 for (int i=mPendingRemove.size()-1; i>=0; i--) {
9412 WindowState w = mPendingRemove.get(i);
9413 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009414 pw.print(" Remove #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009415 pw.print(w);
9416 if (dumpAll) {
9417 pw.println(":");
9418 w.dump(pw, " ", true);
9419 } else {
9420 pw.println();
9421 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009422 }
9423 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009424 }
9425 if (mForceRemoves != null && mForceRemoves.size() > 0) {
9426 pw.println();
9427 pw.println(" Windows force removing:");
9428 for (int i=mForceRemoves.size()-1; i>=0; i--) {
9429 WindowState w = mForceRemoves.get(i);
9430 pw.print(" Removing #"); pw.print(i); pw.print(' ');
9431 pw.print(w);
9432 if (dumpAll) {
9433 pw.println(":");
9434 w.dump(pw, " ", true);
9435 } else {
9436 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009437 }
9438 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009439 }
9440 if (mDestroySurface.size() > 0) {
9441 pw.println();
9442 pw.println(" Windows waiting to destroy their surface:");
9443 for (int i=mDestroySurface.size()-1; i>=0; i--) {
9444 WindowState w = mDestroySurface.get(i);
9445 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009446 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009447 pw.print(w);
9448 if (dumpAll) {
9449 pw.println(":");
9450 w.dump(pw, " ", true);
9451 } else {
9452 pw.println();
9453 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009454 }
9455 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009456 }
9457 if (mLosingFocus.size() > 0) {
9458 pw.println();
9459 pw.println(" Windows losing focus:");
9460 for (int i=mLosingFocus.size()-1; i>=0; i--) {
9461 WindowState w = mLosingFocus.get(i);
9462 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009463 pw.print(" Losing #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009464 pw.print(w);
9465 if (dumpAll) {
9466 pw.println(":");
9467 w.dump(pw, " ", true);
9468 } else {
9469 pw.println();
9470 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009471 }
9472 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009473 }
9474 if (mResizingWindows.size() > 0) {
9475 pw.println();
9476 pw.println(" Windows waiting to resize:");
9477 for (int i=mResizingWindows.size()-1; i>=0; i--) {
9478 WindowState w = mResizingWindows.get(i);
9479 if (windows == null || windows.contains(w)) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009480 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009481 pw.print(w);
9482 if (dumpAll) {
9483 pw.println(":");
9484 w.dump(pw, " ", true);
9485 } else {
9486 pw.println();
9487 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009488 }
9489 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009490 }
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009491 if (mWaitingForDrawn.size() > 0) {
9492 pw.println();
9493 pw.println(" Clients waiting for these windows to be drawn:");
9494 for (int i=mWaitingForDrawn.size()-1; i>=0; i--) {
9495 Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(i);
9496 pw.print(" Waiting #"); pw.print(i); pw.print(' '); pw.print(pair.first);
9497 pw.print(": "); pw.println(pair.second);
9498 }
9499 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009500 pw.println();
9501 if (mDisplay != null) {
9502 pw.print(" Display: init="); pw.print(mInitialDisplayWidth); pw.print("x");
9503 pw.print(mInitialDisplayHeight); pw.print(" base=");
9504 pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight);
9505 pw.print(" cur=");
9506 pw.print(mCurDisplayWidth); pw.print("x"); pw.print(mCurDisplayHeight);
9507 pw.print(" app=");
9508 pw.print(mAppDisplayWidth); pw.print("x"); pw.print(mAppDisplayHeight);
9509 pw.print(" raw="); pw.print(mDisplay.getRawWidth());
9510 pw.print("x"); pw.println(mDisplay.getRawHeight());
9511 } else {
9512 pw.println(" NO DISPLAY");
9513 }
9514 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
9515 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
9516 if (mLastFocus != mCurrentFocus) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009517 pw.print(" mLastFocus="); pw.println(mLastFocus);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009518 }
9519 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
9520 if (mInputMethodTarget != null) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009521 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009522 }
9523 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
9524 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
9525 if (dumpAll) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07009526 if (mLastStatusBarVisibility != 0) {
9527 pw.print(" mLastStatusBarVisibility=0x");
9528 pw.println(Integer.toHexString(mLastStatusBarVisibility));
9529 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009530 if (mInputMethodWindow != null) {
9531 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
9532 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -07009533 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -07009534 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
9535 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
9536 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
9537 }
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009538 if (mWindowDetachedWallpaper != null) {
9539 pw.print(" mWindowDetachedWallpaper="); pw.println(mWindowDetachedWallpaper);
9540 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009541 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
9542 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
9543 if (mInputMethodAnimLayerAdjustment != 0 ||
9544 mWallpaperAnimLayerAdjustment != 0) {
9545 pw.print(" mInputMethodAnimLayerAdjustment=");
9546 pw.print(mInputMethodAnimLayerAdjustment);
9547 pw.print(" mWallpaperAnimLayerAdjustment=");
9548 pw.println(mWallpaperAnimLayerAdjustment);
9549 }
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009550 if (mWindowAnimationBackgroundSurface != null) {
9551 pw.println(" mWindowAnimationBackgroundSurface:");
9552 mWindowAnimationBackgroundSurface.printTo(" ", pw);
9553 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009554 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
9555 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
9556 pw.print(" mLayoutNeeded="); pw.print(mLayoutNeeded);
9557 pw.print(" mBlurShown="); pw.println(mBlurShown);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07009558 if (mDimAnimator != null) {
Dianne Hackbornde75cb42011-03-02 17:11:21 -08009559 pw.println(" mDimAnimator:");
9560 mDimAnimator.printTo(" ", pw);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07009561 } else {
Dianne Hackborna2e92262010-03-02 17:19:29 -08009562 pw.println( " no DimAnimator ");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07009563 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009564 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
9565 pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009566 pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
9567 pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009568 pw.print(" mRotation="); pw.print(mRotation);
Dianne Hackborndacea8c2011-04-21 17:26:39 -07009569 pw.print(" mAltOrientation="); pw.println(mAltOrientation);
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07009570 pw.print(" mLastWindowForcedOrientation"); pw.print(mLastWindowForcedOrientation);
9571 pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation);
Jeff Brown01a98dd2011-09-20 15:08:29 -07009572 pw.print(" mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009573 pw.print(" mAnimationPending="); pw.print(mAnimationPending);
9574 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
9575 pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale);
9576 pw.print(" mNextAppTransition=0x");
9577 pw.print(Integer.toHexString(mNextAppTransition));
Dianne Hackborn9d132642011-04-21 17:26:39 -07009578 pw.print(" mAppTransitionReady="); pw.println(mAppTransitionReady);
9579 pw.print(" mAppTransitionRunning="); pw.print(mAppTransitionRunning);
9580 pw.print(" mAppTransitionTimeout="); pw.println( mAppTransitionTimeout);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009581 if (mNextAppTransitionPackage != null) {
9582 pw.print(" mNextAppTransitionPackage=");
9583 pw.print(mNextAppTransitionPackage);
Dianne Hackborn9d132642011-04-21 17:26:39 -07009584 pw.print(" mNextAppTransitionEnter=0x");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009585 pw.print(Integer.toHexString(mNextAppTransitionEnter));
Dianne Hackborn9d132642011-04-21 17:26:39 -07009586 pw.print(" mNextAppTransitionExit=0x");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009587 pw.print(Integer.toHexString(mNextAppTransitionExit));
9588 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009589 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
9590 pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009591 }
9592 }
9593
9594 boolean dumpWindows(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9595 int opti, boolean dumpAll) {
9596 ArrayList<WindowState> windows = new ArrayList<WindowState>();
9597 if ("visible".equals(name)) {
9598 synchronized(mWindowMap) {
9599 for (int i=mWindows.size()-1; i>=0; i--) {
9600 WindowState w = mWindows.get(i);
9601 if (w.mSurfaceShown) {
9602 windows.add(w);
9603 }
9604 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009605 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009606 } else {
9607 int objectId = 0;
9608 // See if this is an object ID.
9609 try {
9610 objectId = Integer.parseInt(name, 16);
9611 name = null;
9612 } catch (RuntimeException e) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009613 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009614 synchronized(mWindowMap) {
9615 for (int i=mWindows.size()-1; i>=0; i--) {
9616 WindowState w = mWindows.get(i);
9617 if (name != null) {
9618 if (w.mAttrs.getTitle().toString().contains(name)) {
9619 windows.add(w);
9620 }
9621 } else if (System.identityHashCode(w) == objectId) {
9622 windows.add(w);
9623 }
9624 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07009625 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009626 }
9627
9628 if (windows.size() <= 0) {
9629 return false;
9630 }
9631
9632 synchronized(mWindowMap) {
9633 dumpWindowsLocked(fd, pw, dumpAll, windows);
9634 }
9635 return true;
9636 }
9637
9638 @Override
9639 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
9640 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
9641 != PackageManager.PERMISSION_GRANTED) {
9642 pw.println("Permission Denial: can't dump WindowManager from from pid="
9643 + Binder.getCallingPid()
9644 + ", uid=" + Binder.getCallingUid());
9645 return;
9646 }
9647
9648 boolean dumpAll = false;
9649
9650 int opti = 0;
9651 while (opti < args.length) {
9652 String opt = args[opti];
9653 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9654 break;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009655 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009656 opti++;
9657 if ("-a".equals(opt)) {
9658 dumpAll = true;
9659 } else if ("-h".equals(opt)) {
9660 pw.println("Window manager dump options:");
9661 pw.println(" [-a] [-h] [cmd] ...");
9662 pw.println(" cmd may be one of:");
9663 pw.println(" i[input]: input subsystem state");
9664 pw.println(" p[policy]: policy state");
9665 pw.println(" s[essions]: active sessions");
9666 pw.println(" t[okens]: token list");
9667 pw.println(" w[indows]: window list");
9668 pw.println(" cmd may also be a NAME to dump windows. NAME may");
9669 pw.println(" be a partial substring in a window name, a");
9670 pw.println(" Window hex object identifier, or");
9671 pw.println(" \"all\" for all windows, or");
9672 pw.println(" \"visible\" for the visible windows.");
9673 pw.println(" -a: include all available server state.");
9674 return;
Dianne Hackborn87fc3082010-12-03 13:09:12 -08009675 } else {
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009676 pw.println("Unknown argument: " + opt + "; use -h for help");
Dianne Hackborn87fc3082010-12-03 13:09:12 -08009677 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07009678 }
9679
9680 // Is the caller requesting to dump a particular piece of data?
9681 if (opti < args.length) {
9682 String cmd = args[opti];
9683 opti++;
9684 if ("input".equals(cmd) || "i".equals(cmd)) {
9685 dumpInput(fd, pw, true);
9686 return;
9687 } else if ("policy".equals(cmd) || "p".equals(cmd)) {
9688 synchronized(mWindowMap) {
9689 dumpPolicyLocked(fd, pw, args, true);
9690 }
9691 return;
9692 } else if ("sessions".equals(cmd) || "s".equals(cmd)) {
9693 synchronized(mWindowMap) {
9694 dumpSessionsLocked(fd, pw, true);
9695 }
9696 return;
9697 } else if ("tokens".equals(cmd) || "t".equals(cmd)) {
9698 synchronized(mWindowMap) {
9699 dumpTokensLocked(fd, pw, true);
9700 }
9701 return;
9702 } else if ("windows".equals(cmd) || "w".equals(cmd)) {
9703 synchronized(mWindowMap) {
9704 dumpWindowsLocked(fd, pw, true, null);
9705 }
9706 return;
9707 } else if ("all".equals(cmd) || "a".equals(cmd)) {
9708 synchronized(mWindowMap) {
9709 dumpWindowsLocked(fd, pw, true, null);
9710 }
9711 return;
9712 } else {
9713 // Dumping a single name?
9714 if (!dumpWindows(fd, pw, cmd, args, opti, dumpAll)) {
9715 pw.println("Bad window command, or no windows match: " + cmd);
9716 pw.println("Use -h for help.");
9717 }
9718 return;
9719 }
9720 }
9721
9722 dumpInput(fd, pw, dumpAll);
9723
9724 synchronized(mWindowMap) {
9725 if (dumpAll) {
9726 pw.println("-------------------------------------------------------------------------------");
9727 }
9728 dumpPolicyLocked(fd, pw, args, dumpAll);
9729 pw.println();
9730 if (dumpAll) {
9731 pw.println("-------------------------------------------------------------------------------");
9732 }
9733 dumpSessionsLocked(fd, pw, dumpAll);
9734 pw.println();
9735 if (dumpAll) {
9736 pw.println("-------------------------------------------------------------------------------");
9737 }
9738 dumpTokensLocked(fd, pw, dumpAll);
9739 pw.println();
9740 if (dumpAll) {
9741 pw.println("-------------------------------------------------------------------------------");
9742 }
9743 dumpWindowsLocked(fd, pw, dumpAll, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009744 }
9745 }
9746
Jeff Brown349703e2010-06-22 01:27:15 -07009747 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009748 public void monitor() {
9749 synchronized (mWindowMap) { }
Mike Lockwood983ee092009-11-22 01:42:24 -05009750 synchronized (mKeyguardTokenWatcher) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -07009751 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009752
Jeff Brown2992ea72011-01-28 22:04:14 -08009753 public interface OnHardKeyboardStatusChangeListener {
9754 public void onHardKeyboardStatusChange(boolean available, boolean enabled);
9755 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009756}