blob: 2efb4449eb90827ba2d5223d430acf84fec750e9 [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
17package com.android.server;
18
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;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -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;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -070025import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
27import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070028import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
30import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
32import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
33import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
34import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070035import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036
37import com.android.internal.app.IBatteryStats;
38import com.android.internal.policy.PolicyManager;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080039import com.android.internal.policy.impl.PhoneWindowManager;
Christopher Tatea53146c2010-09-07 11:57:52 -070040import com.android.internal.view.BaseInputHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import com.android.internal.view.IInputContext;
42import com.android.internal.view.IInputMethodClient;
43import com.android.internal.view.IInputMethodManager;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080044import com.android.internal.view.WindowManagerPolicyThread;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import com.android.server.am.BatteryStatsService;
46
47import android.Manifest;
48import android.app.ActivityManagerNative;
49import android.app.IActivityManager;
Joe Onoratoac0ee892011-01-30 15:38:30 -080050import android.app.StatusBarManager;
Jim Millerd6b57052010-06-07 17:52:42 -070051import android.app.admin.DevicePolicyManager;
Jim Miller284b62e2010-06-08 14:27:42 -070052import android.content.BroadcastReceiver;
Christopher Tatea53146c2010-09-07 11:57:52 -070053import android.content.ClipData;
54import android.content.ClipDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055import android.content.Context;
Jim Miller284b62e2010-06-08 14:27:42 -070056import android.content.Intent;
57import android.content.IntentFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import android.content.pm.ActivityInfo;
59import android.content.pm.PackageManager;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070060import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.content.res.Configuration;
Dianne Hackborn1c24e952010-11-23 00:34:30 -080062import android.content.res.Resources;
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;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070066import android.graphics.Paint;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import android.graphics.PixelFormat;
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070068import android.graphics.PorterDuff;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069import android.graphics.Rect;
70import android.graphics.Region;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070071import android.graphics.Typeface;
72import android.graphics.Paint.FontMetricsInt;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.os.BatteryStats;
74import android.os.Binder;
Dianne Hackborn75804932009-10-20 20:15:20 -070075import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076import android.os.Debug;
77import android.os.Handler;
78import android.os.IBinder;
79import android.os.LocalPowerManager;
80import android.os.Looper;
81import android.os.Message;
82import android.os.Parcel;
83import android.os.ParcelFileDescriptor;
84import android.os.Power;
85import android.os.PowerManager;
86import android.os.Process;
87import android.os.RemoteException;
88import android.os.ServiceManager;
Brad Fitzpatrickec062f62010-11-03 09:56:54 -070089import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.os.SystemClock;
91import android.os.SystemProperties;
92import android.os.TokenWatcher;
93import android.provider.Settings;
Dianne Hackborn723738c2009-06-25 19:48:04 -070094import android.util.DisplayMetrics;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095import android.util.EventLog;
Jim Millerd6b57052010-06-07 17:52:42 -070096import android.util.Log;
Joe Onorato8a9b2202010-02-26 18:56:32 -080097import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098import android.util.SparseIntArray;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070099import android.util.TypedValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100import android.view.Display;
Christopher Tatea53146c2010-09-07 11:57:52 -0700101import android.view.DragEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import android.view.Gravity;
103import android.view.IApplicationToken;
104import android.view.IOnKeyguardExitResult;
105import android.view.IRotationWatcher;
106import android.view.IWindow;
107import android.view.IWindowManager;
108import android.view.IWindowSession;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700109import android.view.InputChannel;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700110import android.view.InputDevice;
Jeff Brownbbda99d2010-07-28 15:48:59 -0700111import android.view.InputEvent;
Christopher Tatea53146c2010-09-07 11:57:52 -0700112import android.view.InputHandler;
113import android.view.InputQueue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114import android.view.KeyEvent;
115import android.view.MotionEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116import android.view.Surface;
117import android.view.SurfaceSession;
118import android.view.View;
119import android.view.ViewTreeObserver;
120import android.view.WindowManager;
121import android.view.WindowManagerImpl;
122import android.view.WindowManagerPolicy;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700123import android.view.Surface.OutOfResourcesException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124import android.view.WindowManager.LayoutParams;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700125import android.view.animation.AccelerateInterpolator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126import android.view.animation.Animation;
127import android.view.animation.AnimationUtils;
128import android.view.animation.Transformation;
129
130import java.io.BufferedWriter;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700131import java.io.DataInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132import java.io.File;
133import java.io.FileDescriptor;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700134import java.io.FileInputStream;
135import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136import java.io.IOException;
137import java.io.OutputStream;
138import java.io.OutputStreamWriter;
139import java.io.PrintWriter;
140import java.io.StringWriter;
141import java.net.Socket;
142import java.util.ArrayList;
143import java.util.HashMap;
144import java.util.HashSet;
145import java.util.Iterator;
146import java.util.List;
147
148/** {@hide} */
Dianne Hackbornddca3ee2009-07-23 19:01:31 -0700149public class WindowManagerService extends IWindowManager.Stub
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700150 implements Watchdog.Monitor {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 static final String TAG = "WindowManager";
152 static final boolean DEBUG = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800153 static final boolean DEBUG_ADD_REMOVE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154 static final boolean DEBUG_FOCUS = false;
155 static final boolean DEBUG_ANIM = false;
Dianne Hackborn9b52a212009-12-11 14:51:35 -0800156 static final boolean DEBUG_LAYOUT = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800157 static final boolean DEBUG_RESIZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 static final boolean DEBUG_LAYERS = false;
159 static final boolean DEBUG_INPUT = false;
160 static final boolean DEBUG_INPUT_METHOD = false;
161 static final boolean DEBUG_VISIBILITY = false;
Dianne Hackbornbdd52b22009-09-02 21:46:19 -0700162 static final boolean DEBUG_WINDOW_MOVEMENT = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800163 static final boolean DEBUG_TOKEN_MOVEMENT = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164 static final boolean DEBUG_ORIENTATION = false;
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700165 static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 static final boolean DEBUG_APP_TRANSITIONS = false;
167 static final boolean DEBUG_STARTING_WINDOW = false;
168 static final boolean DEBUG_REORDER = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700169 static final boolean DEBUG_WALLPAPER = false;
Christopher Tate994ef922011-01-12 20:06:07 -0800170 static final boolean DEBUG_DRAG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 static final boolean SHOW_TRANSACTIONS = false;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700172 static final boolean HIDE_STACK_CRAWLS = true;
Michael Chan53071d62009-05-13 17:29:48 -0700173
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 static final boolean PROFILE_ORIENTATION = false;
175 static final boolean BLUR = true;
Dave Bortcfe65242009-04-09 14:51:04 -0700176 static final boolean localLOGV = DEBUG;
Romain Guy06882f82009-06-10 13:36:04 -0700177
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178 /** How much to multiply the policy's type layer, to reserve room
179 * for multiple windows of the same type and Z-ordering adjustment
180 * with TYPE_LAYER_OFFSET. */
181 static final int TYPE_LAYER_MULTIPLIER = 10000;
Romain Guy06882f82009-06-10 13:36:04 -0700182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
184 * or below others in the same layer. */
185 static final int TYPE_LAYER_OFFSET = 1000;
Romain Guy06882f82009-06-10 13:36:04 -0700186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 /** How much to increment the layer for each window, to reserve room
188 * for effect surfaces between them.
189 */
190 static final int WINDOW_LAYER_MULTIPLIER = 5;
Romain Guy06882f82009-06-10 13:36:04 -0700191
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192 /** The maximum length we will accept for a loaded animation duration:
193 * this is 10 seconds.
194 */
195 static final int MAX_ANIMATION_DURATION = 10*1000;
196
197 /** Amount of time (in milliseconds) to animate the dim surface from one
198 * value to another, when no window animation is driving it.
199 */
200 static final int DEFAULT_DIM_DURATION = 200;
201
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700202 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
203 * compatible windows.
204 */
205 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
206
Dianne Hackborna1111872010-11-23 20:55:11 -0800207 /**
208 * If true, the window manager will do its own custom freezing and general
209 * management of the screen during rotation.
210 */
211 static final boolean CUSTOM_SCREEN_ROTATION = true;
212
Jeff Brown7fbdc842010-06-17 20:52:56 -0700213 // Maximum number of milliseconds to wait for input event injection.
214 // FIXME is this value reasonable?
215 private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000;
Jeff Brownb09abc12011-01-13 21:08:27 -0800216
217 // Maximum number of milliseconds to wait for input devices to be enumerated before
218 // proceding with safe mode detection.
219 private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
Jeff Brown349703e2010-06-22 01:27:15 -0700220
221 // Default input dispatching timeout in nanoseconds.
222 private static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
Romain Guy06882f82009-06-10 13:36:04 -0700223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 static final int UPDATE_FOCUS_NORMAL = 0;
225 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
226 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
227 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700228
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700230 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231
232 /**
233 * Condition waited on by {@link #reenableKeyguard} to know the call to
234 * the window policy has finished.
Mike Lockwood983ee092009-11-22 01:42:24 -0500235 * This is set to true only if mKeyguardTokenWatcher.acquired() has
236 * actually disabled the keyguard.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800237 */
Mike Lockwood983ee092009-11-22 01:42:24 -0500238 private boolean mKeyguardDisabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239
Jim Miller284b62e2010-06-08 14:27:42 -0700240 private static final int ALLOW_DISABLE_YES = 1;
241 private static final int ALLOW_DISABLE_NO = 0;
242 private static final int ALLOW_DISABLE_UNKNOWN = -1; // check with DevicePolicyManager
243 private int mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN; // sync'd by mKeyguardTokenWatcher
244
Mike Lockwood983ee092009-11-22 01:42:24 -0500245 final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher(
246 new Handler(), "WindowManagerService.mKeyguardTokenWatcher") {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 public void acquired() {
Jim Miller284b62e2010-06-08 14:27:42 -0700248 if (shouldAllowDisableKeyguard()) {
249 mPolicy.enableKeyguard(false);
250 mKeyguardDisabled = true;
251 } else {
252 Log.v(TAG, "Not disabling keyguard since device policy is enforced");
253 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254 }
255 public void released() {
Dianne Hackborna33e3f72009-09-29 17:28:24 -0700256 mPolicy.enableKeyguard(true);
Mike Lockwood983ee092009-11-22 01:42:24 -0500257 synchronized (mKeyguardTokenWatcher) {
258 mKeyguardDisabled = false;
259 mKeyguardTokenWatcher.notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260 }
261 }
262 };
263
Jim Miller284b62e2010-06-08 14:27:42 -0700264 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
265 @Override
266 public void onReceive(Context context, Intent intent) {
267 mPolicy.enableKeyguard(true);
268 synchronized(mKeyguardTokenWatcher) {
269 // lazily evaluate this next time we're asked to disable keyguard
270 mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
271 mKeyguardDisabled = false;
272 }
273 }
274 };
275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 final Context mContext;
277
278 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700279
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800282 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
283
284 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288 /**
289 * All currently active sessions with clients.
290 */
291 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700292
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800293 /**
294 * Mapping from an IWindow IBinder to the server's Window object.
295 * This is also used as the lock for all of our state.
296 */
297 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
298
299 /**
300 * Mapping from a token IBinder to a WindowToken object.
301 */
302 final HashMap<IBinder, WindowToken> mTokenMap =
303 new HashMap<IBinder, WindowToken>();
304
305 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 * Window tokens that are in the process of exiting, but still
307 * on screen for animations.
308 */
309 final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
310
311 /**
312 * Z-ordered (bottom-most first) list of all application tokens, for
313 * controlling the ordering of windows in different applications. This
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800314 * contains AppWindowToken objects.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 */
316 final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
317
318 /**
319 * Application tokens that are in the process of exiting, but still
320 * on screen for animations.
321 */
322 final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
323
324 /**
325 * List of window tokens that have finished starting their application,
326 * and now need to have the policy remove their windows.
327 */
328 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
329
330 /**
331 * Z-ordered (bottom-most first) list of all Window objects.
332 */
Jeff Browne33348b2010-07-15 23:54:05 -0700333 final ArrayList<WindowState> mWindows = new ArrayList<WindowState>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334
335 /**
336 * Windows that are being resized. Used so we can tell the client about
337 * the resize after closing the transaction in which we resized the
338 * underlying surface.
339 */
340 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
341
342 /**
343 * Windows whose animations have ended and now must be removed.
344 */
345 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
346
347 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800348 * Used when processing mPendingRemove to avoid working on the original array.
349 */
350 WindowState[] mPendingRemoveTmp = new WindowState[20];
351
352 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800353 * Windows whose surface should be destroyed.
354 */
355 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
356
357 /**
358 * Windows that have lost input focus and are waiting for the new
359 * focus window to be displayed before they are told about this.
360 */
361 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
362
363 /**
364 * This is set when we have run out of memory, and will either be an empty
365 * list or contain windows that need to be force removed.
366 */
367 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700368
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800369 /**
370 * Used when rebuilding window list to keep track of windows that have
371 * been removed.
372 */
373 WindowState[] mRebuildTmp = new WindowState[20];
374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800375 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700376
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 SurfaceSession mFxSession;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700378 private DimAnimator mDimAnimator = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800379 Surface mBlurSurface;
380 boolean mBlurShown;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700381 Watermark mWatermark;
Brad Fitzpatrick68044332010-11-22 18:19:48 -0800382 StrictModeFlash mStrictModeFlash;
Dianne Hackborna1111872010-11-23 20:55:11 -0800383 ScreenRotationAnimation mScreenRotationAnimation;
Romain Guy06882f82009-06-10 13:36:04 -0700384
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800385 int mTransactionSequence = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700386
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 final float[] mTmpFloats = new float[9];
388
389 boolean mSafeMode;
390 boolean mDisplayEnabled = false;
391 boolean mSystemBooted = false;
Christopher Tateb696aee2010-04-02 19:08:30 -0700392 int mInitialDisplayWidth = 0;
393 int mInitialDisplayHeight = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 int mRotation = 0;
395 int mRequestedRotation = 0;
396 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborn321ae682009-03-27 16:16:03 -0700397 int mLastRotationFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 ArrayList<IRotationWatcher> mRotationWatchers
399 = new ArrayList<IRotationWatcher>();
Dianne Hackborn89ba6752011-01-23 16:51:16 -0800400 int mDeferredRotation;
401 int mDeferredRotationAnimFlags;
Romain Guy06882f82009-06-10 13:36:04 -0700402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 boolean mLayoutNeeded = true;
404 boolean mAnimationPending = false;
405 boolean mDisplayFrozen = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800406 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800407 boolean mWindowsFreezingScreen = false;
408 long mFreezeGcPending = 0;
409 int mAppsFreezingScreen = 0;
410
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800411 int mLayoutSeq = 0;
412
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800413 // State while inside of layoutAndPlaceSurfacesLocked().
414 boolean mFocusMayChange;
415
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800416 Configuration mCurConfiguration = new Configuration();
417
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418 // This is held as long as we have the screen frozen, to give us time to
419 // perform a rotation animation when turning off shows the lock screen which
420 // changes the orientation.
421 PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700422
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800423 // State management of app transitions. When we are preparing for a
424 // transition, mNextAppTransition will be the kind of transition to
425 // perform or TRANSIT_NONE if we are not waiting. If we are waiting,
426 // mOpeningApps and mClosingApps are the lists of tokens that will be
427 // made visible or hidden at the next transition.
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700428 int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700429 String mNextAppTransitionPackage;
430 int mNextAppTransitionEnter;
431 int mNextAppTransitionExit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800432 boolean mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -0700433 boolean mAppTransitionRunning = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800434 boolean mAppTransitionTimeout = false;
435 boolean mStartingIconInTransition = false;
436 boolean mSkipAppTransitionAnimation = false;
437 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
438 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Dianne Hackborna8f60182009-09-01 19:01:50 -0700439 final ArrayList<AppWindowToken> mToTopApps = new ArrayList<AppWindowToken>();
440 final ArrayList<AppWindowToken> mToBottomApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700441
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442 Display mDisplay;
Romain Guy06882f82009-06-10 13:36:04 -0700443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800444 H mH = new H();
445
446 WindowState mCurrentFocus = null;
447 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 // This just indicates the window the input method is on top of, not
450 // necessarily the window its input is going to.
451 WindowState mInputMethodTarget = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452 boolean mInputMethodTargetWaitingAnim;
453 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700454
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800455 WindowState mInputMethodWindow = null;
456 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
457
Jeff Brown2992ea72011-01-28 22:04:14 -0800458 boolean mHardKeyboardAvailable;
459 boolean mHardKeyboardEnabled;
460 OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
461
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700462 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800463
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700464 // If non-null, this is the currently visible window that is associated
465 // with the wallpaper.
466 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700467 // If non-null, we are in the middle of animating from one wallpaper target
468 // to another, and this is the lower one in Z-order.
469 WindowState mLowerWallpaperTarget = null;
470 // If non-null, we are in the middle of animating from one wallpaper target
471 // to another, and this is the higher one in Z-order.
472 WindowState mUpperWallpaperTarget = null;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -0800473 // Window currently running an animation that has requested it be detached
474 // from the wallpaper. This means we need to ensure the wallpaper is
475 // visible behind it in case it animates in a way that would allow it to be
476 // seen.
477 WindowState mWindowDetachedWallpaper = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700478 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700479 float mLastWallpaperX = -1;
480 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800481 float mLastWallpaperXStep = -1;
482 float mLastWallpaperYStep = -1;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700483 // This is set when we are waiting for a wallpaper to tell us it is done
484 // changing its scroll position.
485 WindowState mWaitingOnWallpaper;
486 // The last time we had a timeout when waiting for a wallpaper.
487 long mLastWallpaperTimeoutTime;
488 // We give a wallpaper up to 150ms to finish scrolling.
489 static final long WALLPAPER_TIMEOUT = 150;
490 // Time we wait after a timeout before trying to wait again.
491 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 AppWindowToken mFocusedApp = null;
494
495 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700496
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800497 float mWindowAnimationScale = 1.0f;
498 float mTransitionAnimationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700499
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700500 final InputManager mInputManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501
502 // Who is holding the screen on.
503 Session mHoldingScreenOn;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700504 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700505
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700506 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800507
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800508 /**
Christopher Tatea53146c2010-09-07 11:57:52 -0700509 * Drag/drop state
510 */
511 class DragState {
512 IBinder mToken;
513 Surface mSurface;
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800514 int mFlags;
Chris Tate7b362e42010-11-04 16:02:52 -0700515 IBinder mLocalWin;
Christopher Tatea53146c2010-09-07 11:57:52 -0700516 ClipData mData;
517 ClipDescription mDataDescription;
Chris Tated4533f142010-10-19 15:15:08 -0700518 boolean mDragResult;
Chris Tateb478f462010-10-15 16:02:26 -0700519 float mCurrentX, mCurrentY;
Christopher Tatea53146c2010-09-07 11:57:52 -0700520 float mThumbOffsetX, mThumbOffsetY;
521 InputChannel mServerChannel, mClientChannel;
522 WindowState mTargetWindow;
523 ArrayList<WindowState> mNotifiedWindows;
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700524 boolean mDragInProgress;
Christopher Tatea53146c2010-09-07 11:57:52 -0700525
Jeff Brownfbf09772011-01-16 14:06:57 -0800526 private final Region mTmpRegion = new Region();
Christopher Tatea53146c2010-09-07 11:57:52 -0700527
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800528 DragState(IBinder token, Surface surface, int flags, IBinder localWin) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700529 mToken = token;
530 mSurface = surface;
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800531 mFlags = flags;
Chris Tate7b362e42010-11-04 16:02:52 -0700532 mLocalWin = localWin;
Christopher Tatea53146c2010-09-07 11:57:52 -0700533 mNotifiedWindows = new ArrayList<WindowState>();
534 }
535
536 void reset() {
537 if (mSurface != null) {
538 mSurface.destroy();
539 }
540 mSurface = null;
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800541 mFlags = 0;
Chris Tate7b362e42010-11-04 16:02:52 -0700542 mLocalWin = null;
Christopher Tatea53146c2010-09-07 11:57:52 -0700543 mToken = null;
544 mData = null;
545 mThumbOffsetX = mThumbOffsetY = 0;
546 mNotifiedWindows = null;
547 }
548
549 void register() {
550 if (DEBUG_DRAG) Slog.d(TAG, "registering drag input channel");
551 if (mClientChannel != null) {
552 Slog.e(TAG, "Duplicate register of drag input channel");
553 } else {
554 InputChannel[] channels = InputChannel.openInputChannelPair("drag");
555 mServerChannel = channels[0];
556 mClientChannel = channels[1];
Jeff Brown928e0542011-01-10 11:17:36 -0800557 mInputManager.registerInputChannel(mServerChannel, null);
Christopher Tatea53146c2010-09-07 11:57:52 -0700558 InputQueue.registerInputChannel(mClientChannel, mDragInputHandler,
559 mH.getLooper().getQueue());
560 }
561 }
562
563 void unregister() {
564 if (DEBUG_DRAG) Slog.d(TAG, "unregistering drag input channel");
565 if (mClientChannel == null) {
566 Slog.e(TAG, "Unregister of nonexistent drag input channel");
567 } else {
568 mInputManager.unregisterInputChannel(mServerChannel);
569 InputQueue.unregisterInputChannel(mClientChannel);
570 mClientChannel.dispose();
Chris Tateef70a072010-10-22 19:10:34 -0700571 mServerChannel.dispose();
Christopher Tatea53146c2010-09-07 11:57:52 -0700572 mClientChannel = null;
573 mServerChannel = null;
574 }
575 }
576
Chris Tatea32dcf72010-10-14 12:13:50 -0700577 int getDragLayerLw() {
578 return mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_DRAG)
579 * TYPE_LAYER_MULTIPLIER
580 + TYPE_LAYER_OFFSET;
581 }
582
Christopher Tatea53146c2010-09-07 11:57:52 -0700583 /* call out to each visible window/session informing it about the drag
584 */
Chris Tateb8203e92010-10-12 14:23:21 -0700585 void broadcastDragStartedLw(final float touchX, final float touchY) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700586 // Cache a base-class instance of the clip metadata so that parceling
587 // works correctly in calling out to the apps.
Christopher Tate1fc014f2011-01-19 12:56:26 -0800588 mDataDescription = (mData != null) ? mData.getDescription() : null;
Christopher Tatea53146c2010-09-07 11:57:52 -0700589 mNotifiedWindows.clear();
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700590 mDragInProgress = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700591
592 if (DEBUG_DRAG) {
Chris Tateb478f462010-10-15 16:02:26 -0700593 Slog.d(TAG, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
Christopher Tatea53146c2010-09-07 11:57:52 -0700594 }
595
Christopher Tate2c095f32010-10-04 14:13:40 -0700596 final int N = mWindows.size();
597 for (int i = 0; i < N; i++) {
Chris Tateb478f462010-10-15 16:02:26 -0700598 sendDragStartedLw(mWindows.get(i), touchX, touchY, mDataDescription);
Christopher Tatea53146c2010-09-07 11:57:52 -0700599 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700600 }
601
602 /* helper - send a caller-provided event, presumed to be DRAG_STARTED, if the
603 * designated window is potentially a drop recipient. There are race situations
604 * around DRAG_ENDED broadcast, so we make sure that once we've declared that
605 * the drag has ended, we never send out another DRAG_STARTED for this drag action.
Christopher Tate2c095f32010-10-04 14:13:40 -0700606 *
607 * This method clones the 'event' parameter if it's being delivered to the same
608 * process, so it's safe for the caller to call recycle() on the event afterwards.
Christopher Tatea53146c2010-09-07 11:57:52 -0700609 */
Chris Tateb478f462010-10-15 16:02:26 -0700610 private void sendDragStartedLw(WindowState newWin, float touchX, float touchY,
611 ClipDescription desc) {
Chris Tate7b362e42010-11-04 16:02:52 -0700612 // Don't actually send the event if the drag is supposed to be pinned
613 // to the originating window but 'newWin' is not that window.
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800614 if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
Chris Tate7b362e42010-11-04 16:02:52 -0700615 final IBinder winBinder = newWin.mClient.asBinder();
616 if (winBinder != mLocalWin) {
617 if (DEBUG_DRAG) {
618 Slog.d(TAG, "Not dispatching local DRAG_STARTED to " + newWin);
619 }
620 return;
621 }
622 }
623
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700624 if (mDragInProgress && newWin.isPotentialDragTarget()) {
Chris Tateb478f462010-10-15 16:02:26 -0700625 DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED,
626 touchX - newWin.mFrame.left, touchY - newWin.mFrame.top,
Christopher Tate407b4e92010-11-30 17:14:08 -0800627 null, desc, null, false);
Christopher Tatea53146c2010-09-07 11:57:52 -0700628 try {
629 newWin.mClient.dispatchDragEvent(event);
630 // track each window that we've notified that the drag is starting
631 mNotifiedWindows.add(newWin);
632 } catch (RemoteException e) {
633 Slog.w(TAG, "Unable to drag-start window " + newWin);
Chris Tateb478f462010-10-15 16:02:26 -0700634 } finally {
635 // if the callee was local, the dispatch has already recycled the event
636 if (Process.myPid() != newWin.mSession.mPid) {
637 event.recycle();
638 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700639 }
640 }
641 }
642
643 /* helper - construct and send a DRAG_STARTED event only if the window has not
644 * previously been notified, i.e. it became visible after the drag operation
645 * was begun. This is a rare case.
646 */
647 private void sendDragStartedIfNeededLw(WindowState newWin) {
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700648 if (mDragInProgress) {
649 // If we have sent the drag-started, we needn't do so again
650 for (WindowState ws : mNotifiedWindows) {
651 if (ws == newWin) {
652 return;
653 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700654 }
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700655 if (DEBUG_DRAG) {
Chris Tateef70a072010-10-22 19:10:34 -0700656 Slog.d(TAG, "need to send DRAG_STARTED to new window " + newWin);
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700657 }
Chris Tateb478f462010-10-15 16:02:26 -0700658 sendDragStartedLw(newWin, mCurrentX, mCurrentY, mDataDescription);
Christopher Tatea53146c2010-09-07 11:57:52 -0700659 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700660 }
661
Chris Tated4533f142010-10-19 15:15:08 -0700662 void broadcastDragEndedLw() {
Christopher Tatea53146c2010-09-07 11:57:52 -0700663 if (DEBUG_DRAG) {
664 Slog.d(TAG, "broadcasting DRAG_ENDED");
665 }
Chris Tated4533f142010-10-19 15:15:08 -0700666 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED,
Christopher Tate407b4e92010-11-30 17:14:08 -0800667 0, 0, null, null, null, mDragResult);
Chris Tated4533f142010-10-19 15:15:08 -0700668 for (WindowState ws: mNotifiedWindows) {
669 try {
670 ws.mClient.dispatchDragEvent(evt);
671 } catch (RemoteException e) {
672 Slog.w(TAG, "Unable to drag-end window " + ws);
Christopher Tatea53146c2010-09-07 11:57:52 -0700673 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700674 }
Chris Tated4533f142010-10-19 15:15:08 -0700675 mNotifiedWindows.clear();
676 mDragInProgress = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700677 evt.recycle();
678 }
679
Chris Tated4533f142010-10-19 15:15:08 -0700680 void endDragLw() {
681 mDragState.broadcastDragEndedLw();
682
683 // stop intercepting input
684 mDragState.unregister();
Jeff Brown2e44b072011-01-24 15:21:56 -0800685 mInputMonitor.updateInputWindowsLw(true /*force*/);
Chris Tated4533f142010-10-19 15:15:08 -0700686
687 // free our resources and drop all the object references
688 mDragState.reset();
689 mDragState = null;
Christopher Tateccd24de2011-01-12 15:02:55 -0800690
Dianne Hackborn89ba6752011-01-23 16:51:16 -0800691 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-drag rotation");
692 boolean changed = setRotationUncheckedLocked(
693 WindowManagerPolicy.USE_LAST_ROTATION, 0, false);
694 if (changed) {
Dianne Hackborn3e4f9d042011-02-04 14:05:55 -0800695 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Christopher Tateccd24de2011-01-12 15:02:55 -0800696 }
Chris Tated4533f142010-10-19 15:15:08 -0700697 }
698
Christopher Tatea53146c2010-09-07 11:57:52 -0700699 void notifyMoveLw(float x, float y) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700700 final int myPid = Process.myPid();
701
702 // Move the surface to the given touch
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800703 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION notifyMoveLw");
Christopher Tatef01af752011-01-19 16:22:07 -0800704 Surface.openTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800705 try {
706 mSurface.setPosition((int)(x - mThumbOffsetX), (int)(y - mThumbOffsetY));
Dianne Hackbornac1471a2011-02-03 13:46:06 -0800707 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DRAG "
708 + mSurface + ": pos=(" +
709 (int)(x - mThumbOffsetX) + "," + (int)(y - mThumbOffsetY) + ")");
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800710 } finally {
Christopher Tatef01af752011-01-19 16:22:07 -0800711 Surface.closeTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800712 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION notifyMoveLw");
713 }
Christopher Tate2c095f32010-10-04 14:13:40 -0700714
715 // Tell the affected window
Christopher Tatea53146c2010-09-07 11:57:52 -0700716 WindowState touchedWin = getTouchedWinAtPointLw(x, y);
Christopher Tatef01af752011-01-19 16:22:07 -0800717 if (touchedWin == null) {
718 if (DEBUG_DRAG) Slog.d(TAG, "No touched win at x=" + x + " y=" + y);
719 return;
720 }
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800721 if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
Chris Tate7b362e42010-11-04 16:02:52 -0700722 final IBinder touchedBinder = touchedWin.mClient.asBinder();
723 if (touchedBinder != mLocalWin) {
724 // This drag is pinned only to the originating window, but the drag
725 // point is outside that window. Pretend it's over empty space.
726 touchedWin = null;
727 }
728 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700729 try {
730 // have we dragged over a new window?
731 if ((touchedWin != mTargetWindow) && (mTargetWindow != null)) {
732 if (DEBUG_DRAG) {
733 Slog.d(TAG, "sending DRAG_EXITED to " + mTargetWindow);
734 }
735 // force DRAG_EXITED_EVENT if appropriate
736 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_EXITED,
Chris Tateb478f462010-10-15 16:02:26 -0700737 x - mTargetWindow.mFrame.left, y - mTargetWindow.mFrame.top,
Christopher Tate407b4e92010-11-30 17:14:08 -0800738 null, null, null, false);
Christopher Tatea53146c2010-09-07 11:57:52 -0700739 mTargetWindow.mClient.dispatchDragEvent(evt);
Christopher Tate2c095f32010-10-04 14:13:40 -0700740 if (myPid != mTargetWindow.mSession.mPid) {
741 evt.recycle();
742 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700743 }
744 if (touchedWin != null) {
Chris Tate9d1ab882010-11-02 15:55:39 -0700745 if (false && DEBUG_DRAG) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700746 Slog.d(TAG, "sending DRAG_LOCATION to " + touchedWin);
747 }
748 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_LOCATION,
Chris Tateb478f462010-10-15 16:02:26 -0700749 x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
Christopher Tate407b4e92010-11-30 17:14:08 -0800750 null, null, null, false);
Christopher Tatea53146c2010-09-07 11:57:52 -0700751 touchedWin.mClient.dispatchDragEvent(evt);
Christopher Tate2c095f32010-10-04 14:13:40 -0700752 if (myPid != touchedWin.mSession.mPid) {
753 evt.recycle();
754 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700755 }
756 } catch (RemoteException e) {
757 Slog.w(TAG, "can't send drag notification to windows");
758 }
759 mTargetWindow = touchedWin;
760 }
761
Chris Tated4533f142010-10-19 15:15:08 -0700762 // Tell the drop target about the data. Returns 'true' if we can immediately
763 // dispatch the global drag-ended message, 'false' if we need to wait for a
764 // result from the recipient.
765 boolean notifyDropLw(float x, float y) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700766 WindowState touchedWin = getTouchedWinAtPointLw(x, y);
Chris Tated4533f142010-10-19 15:15:08 -0700767 if (touchedWin == null) {
768 // "drop" outside a valid window -- no recipient to apply a
769 // timeout to, and we can send the drag-ended message immediately.
770 mDragResult = false;
771 return true;
772 }
773
774 if (DEBUG_DRAG) {
775 Slog.d(TAG, "sending DROP to " + touchedWin);
776 }
777 final int myPid = Process.myPid();
778 final IBinder token = touchedWin.mClient.asBinder();
779 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DROP,
780 x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
Christopher Tate407b4e92010-11-30 17:14:08 -0800781 null, null, mData, false);
Chris Tated4533f142010-10-19 15:15:08 -0700782 try {
783 touchedWin.mClient.dispatchDragEvent(evt);
784
785 // 5 second timeout for this window to respond to the drop
786 mH.removeMessages(H.DRAG_END_TIMEOUT, token);
787 Message msg = mH.obtainMessage(H.DRAG_END_TIMEOUT, token);
788 mH.sendMessageDelayed(msg, 5000);
789 } catch (RemoteException e) {
790 Slog.w(TAG, "can't send drop notification to win " + touchedWin);
791 return true;
792 } finally {
Christopher Tate2c095f32010-10-04 14:13:40 -0700793 if (myPid != touchedWin.mSession.mPid) {
794 evt.recycle();
795 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700796 }
Chris Tated4533f142010-10-19 15:15:08 -0700797 mToken = token;
798 return false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700799 }
800
801 // Find the visible, touch-deliverable window under the given point
802 private WindowState getTouchedWinAtPointLw(float xf, float yf) {
803 WindowState touchedWin = null;
804 final int x = (int) xf;
805 final int y = (int) yf;
806 final ArrayList<WindowState> windows = mWindows;
807 final int N = windows.size();
808 for (int i = N - 1; i >= 0; i--) {
809 WindowState child = windows.get(i);
810 final int flags = child.mAttrs.flags;
811 if (!child.isVisibleLw()) {
812 // not visible == don't tell about drags
813 continue;
814 }
815 if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
816 // not touchable == don't tell about drags
817 continue;
818 }
Jeff Brownfbf09772011-01-16 14:06:57 -0800819
820 child.getTouchableRegion(mTmpRegion);
821
Christopher Tatea53146c2010-09-07 11:57:52 -0700822 final int touchFlags = flags &
Jeff Brownfbf09772011-01-16 14:06:57 -0800823 (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
824 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
825 if (mTmpRegion.contains(x, y) || touchFlags == 0) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700826 // Found it
827 touchedWin = child;
828 break;
829 }
830 }
831
832 return touchedWin;
833 }
834 }
835
836 DragState mDragState = null;
837 private final InputHandler mDragInputHandler = new BaseInputHandler() {
838 @Override
Jeff Brown3915bb82010-11-05 15:02:16 -0700839 public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
840 boolean handled = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700841 try {
Jeff Brown3915bb82010-11-05 15:02:16 -0700842 if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
843 && mDragState != null) {
844 boolean endDrag = false;
845 final float newX = event.getRawX();
846 final float newY = event.getRawY();
847
Christopher Tatea53146c2010-09-07 11:57:52 -0700848 switch (event.getAction()) {
849 case MotionEvent.ACTION_DOWN: {
850 if (DEBUG_DRAG) {
851 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
852 }
853 } break;
854
855 case MotionEvent.ACTION_MOVE: {
856 synchronized (mWindowMap) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700857 // move the surface and tell the involved window(s) where we are
Christopher Tatea53146c2010-09-07 11:57:52 -0700858 mDragState.notifyMoveLw(newX, newY);
859 }
860 } break;
861
862 case MotionEvent.ACTION_UP: {
863 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
864 + newX + "," + newY);
865 synchronized (mWindowMap) {
Chris Tated4533f142010-10-19 15:15:08 -0700866 endDrag = mDragState.notifyDropLw(newX, newY);
Christopher Tatea53146c2010-09-07 11:57:52 -0700867 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700868 } break;
869
870 case MotionEvent.ACTION_CANCEL: {
871 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
872 endDrag = true;
873 } break;
874 }
875
876 if (endDrag) {
877 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
878 // tell all the windows that the drag has ended
Chris Tate59943592010-10-11 20:33:44 -0700879 synchronized (mWindowMap) {
Chris Tated4533f142010-10-19 15:15:08 -0700880 mDragState.endDragLw();
Chris Tate59943592010-10-11 20:33:44 -0700881 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700882 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700883
884 handled = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700885 }
886 } catch (Exception e) {
887 Slog.e(TAG, "Exception caught by drag handleMotion", e);
888 } finally {
Jeff Brown3915bb82010-11-05 15:02:16 -0700889 finishedCallback.finished(handled);
Christopher Tatea53146c2010-09-07 11:57:52 -0700890 }
891 }
892 };
893
894 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800895 * Whether the UI is currently running in touch mode (not showing
896 * navigational focus because the user is directly pressing the screen).
897 */
898 boolean mInTouchMode = false;
899
900 private ViewServer mViewServer;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700901 private ArrayList<WindowChangeListener> mWindowChangeListeners =
902 new ArrayList<WindowChangeListener>();
903 private boolean mWindowsChanged = false;
904
905 public interface WindowChangeListener {
906 public void windowsChanged();
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -0700907 public void focusChanged();
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700908 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800909
Dianne Hackbornc485a602009-03-24 22:39:49 -0700910 final Configuration mTempConfiguration = new Configuration();
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700911 int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700912
913 // The frame use to limit the size of the app running in compatibility mode.
914 Rect mCompatibleScreenFrame = new Rect();
915 // The surface used to fill the outer rim of the app running in compatibility mode.
916 Surface mBackgroundFillerSurface = null;
Dianne Hackbornac1471a2011-02-03 13:46:06 -0800917 WindowState mBackgroundFillerTarget = null;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700918
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 public static WindowManagerService main(Context context,
920 PowerManagerService pm, boolean haveInputMethods) {
921 WMThread thr = new WMThread(context, pm, haveInputMethods);
922 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700923
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800924 synchronized (thr) {
925 while (thr.mService == null) {
926 try {
927 thr.wait();
928 } catch (InterruptedException e) {
929 }
930 }
931 }
Romain Guy06882f82009-06-10 13:36:04 -0700932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 return thr.mService;
934 }
Romain Guy06882f82009-06-10 13:36:04 -0700935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800936 static class WMThread extends Thread {
937 WindowManagerService mService;
Romain Guy06882f82009-06-10 13:36:04 -0700938
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800939 private final Context mContext;
940 private final PowerManagerService mPM;
941 private final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800943 public WMThread(Context context, PowerManagerService pm,
944 boolean haveInputMethods) {
945 super("WindowManager");
946 mContext = context;
947 mPM = pm;
948 mHaveInputMethods = haveInputMethods;
949 }
Romain Guy06882f82009-06-10 13:36:04 -0700950
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800951 public void run() {
952 Looper.prepare();
953 WindowManagerService s = new WindowManagerService(mContext, mPM,
954 mHaveInputMethods);
955 android.os.Process.setThreadPriority(
956 android.os.Process.THREAD_PRIORITY_DISPLAY);
Christopher Tate160edb32010-06-30 17:46:30 -0700957 android.os.Process.setCanSelfBackground(false);
Romain Guy06882f82009-06-10 13:36:04 -0700958
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959 synchronized (this) {
960 mService = s;
961 notifyAll();
962 }
Romain Guy06882f82009-06-10 13:36:04 -0700963
Brad Fitzpatrickec062f62010-11-03 09:56:54 -0700964 // For debug builds, log event loop stalls to dropbox for analysis.
965 if (StrictMode.conditionallyEnableDebugLogging()) {
966 Slog.i(TAG, "Enabled StrictMode logging for WMThread's Looper");
967 }
968
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969 Looper.loop();
970 }
971 }
972
973 static class PolicyThread extends Thread {
974 private final WindowManagerPolicy mPolicy;
975 private final WindowManagerService mService;
976 private final Context mContext;
977 private final PowerManagerService mPM;
978 boolean mRunning = false;
Romain Guy06882f82009-06-10 13:36:04 -0700979
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800980 public PolicyThread(WindowManagerPolicy policy,
981 WindowManagerService service, Context context,
982 PowerManagerService pm) {
983 super("WindowManagerPolicy");
984 mPolicy = policy;
985 mService = service;
986 mContext = context;
987 mPM = pm;
988 }
Romain Guy06882f82009-06-10 13:36:04 -0700989
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800990 public void run() {
991 Looper.prepare();
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800992 WindowManagerPolicyThread.set(this, Looper.myLooper());
993
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994 //Looper.myLooper().setMessageLogging(new LogPrinter(
Joe Onorato8a9b2202010-02-26 18:56:32 -0800995 // Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800996 android.os.Process.setThreadPriority(
997 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -0700998 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800999 mPolicy.init(mContext, mService, mPM);
Romain Guy06882f82009-06-10 13:36:04 -07001000
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001001 synchronized (this) {
1002 mRunning = true;
1003 notifyAll();
1004 }
Romain Guy06882f82009-06-10 13:36:04 -07001005
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001006 // For debug builds, log event loop stalls to dropbox for analysis.
1007 if (StrictMode.conditionallyEnableDebugLogging()) {
1008 Slog.i(TAG, "Enabled StrictMode for PolicyThread's Looper");
1009 }
1010
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001011 Looper.loop();
1012 }
1013 }
1014
1015 private WindowManagerService(Context context, PowerManagerService pm,
1016 boolean haveInputMethods) {
1017 mContext = context;
1018 mHaveInputMethods = haveInputMethods;
1019 mLimitedAlphaCompositing = context.getResources().getBoolean(
1020 com.android.internal.R.bool.config_sf_limitedAlpha);
Romain Guy06882f82009-06-10 13:36:04 -07001021
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001022 mPowerManager = pm;
1023 mPowerManager.setPolicy(mPolicy);
1024 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
1025 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
1026 "SCREEN_FROZEN");
1027 mScreenFrozenLock.setReferenceCounted(false);
1028
1029 mActivityManager = ActivityManagerNative.getDefault();
1030 mBatteryStats = BatteryStatsService.getService();
1031
1032 // Get persisted window scale setting
1033 mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
1034 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
1035 mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
1036 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Romain Guy06882f82009-06-10 13:36:04 -07001037
Jim Miller284b62e2010-06-08 14:27:42 -07001038 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
1039 IntentFilter filter = new IntentFilter();
1040 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
1041 mContext.registerReceiver(mBroadcastReceiver, filter);
1042
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001043 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
1044 "KEEP_SCREEN_ON_FLAG");
1045 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001046
Jeff Browne33348b2010-07-15 23:54:05 -07001047 mInputManager = new InputManager(context, this);
Romain Guy06882f82009-06-10 13:36:04 -07001048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001049 PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
1050 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -07001051
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001052 synchronized (thr) {
1053 while (!thr.mRunning) {
1054 try {
1055 thr.wait();
1056 } catch (InterruptedException e) {
1057 }
1058 }
1059 }
Romain Guy06882f82009-06-10 13:36:04 -07001060
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001061 mInputManager.start();
Romain Guy06882f82009-06-10 13:36:04 -07001062
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001063 // Add ourself to the Watchdog monitors.
1064 Watchdog.getInstance().addMonitor(this);
1065 }
1066
1067 @Override
1068 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1069 throws RemoteException {
1070 try {
1071 return super.onTransact(code, data, reply, flags);
1072 } catch (RuntimeException e) {
1073 // The window manager only throws security exceptions, so let's
1074 // log all others.
1075 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001076 Slog.e(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001077 }
1078 throw e;
1079 }
1080 }
1081
Jeff Browne33348b2010-07-15 23:54:05 -07001082 private void placeWindowAfter(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001083 final int i = mWindows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001084 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001085 TAG, "Adding window " + window + " at "
1086 + (i+1) + " of " + mWindows.size() + " (after " + pos + ")");
1087 mWindows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001088 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001089 }
1090
Jeff Browne33348b2010-07-15 23:54:05 -07001091 private void placeWindowBefore(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001092 final int i = mWindows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001093 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001094 TAG, "Adding window " + window + " at "
1095 + i + " of " + mWindows.size() + " (before " + pos + ")");
1096 mWindows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001097 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001098 }
1099
1100 //This method finds out the index of a window that has the same app token as
1101 //win. used for z ordering the windows in mWindows
1102 private int findIdxBasedOnAppTokens(WindowState win) {
1103 //use a local variable to cache mWindows
Jeff Browne33348b2010-07-15 23:54:05 -07001104 ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001105 int jmax = localmWindows.size();
1106 if(jmax == 0) {
1107 return -1;
1108 }
1109 for(int j = (jmax-1); j >= 0; j--) {
Jeff Browne33348b2010-07-15 23:54:05 -07001110 WindowState wentry = localmWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001111 if(wentry.mAppToken == win.mAppToken) {
1112 return j;
1113 }
1114 }
1115 return -1;
1116 }
Romain Guy06882f82009-06-10 13:36:04 -07001117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001118 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
1119 final IWindow client = win.mClient;
1120 final WindowToken token = win.mToken;
Jeff Browne33348b2010-07-15 23:54:05 -07001121 final ArrayList<WindowState> localmWindows = mWindows;
Romain Guy06882f82009-06-10 13:36:04 -07001122
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001123 final int N = localmWindows.size();
1124 final WindowState attached = win.mAttachedWindow;
1125 int i;
1126 if (attached == null) {
1127 int tokenWindowsPos = token.windows.size();
1128 if (token.appWindowToken != null) {
1129 int index = tokenWindowsPos-1;
1130 if (index >= 0) {
1131 // If this application has existing windows, we
1132 // simply place the new window on top of them... but
1133 // keep the starting window on top.
1134 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
1135 // Base windows go behind everything else.
1136 placeWindowBefore(token.windows.get(0), win);
1137 tokenWindowsPos = 0;
1138 } else {
1139 AppWindowToken atoken = win.mAppToken;
1140 if (atoken != null &&
1141 token.windows.get(index) == atoken.startingWindow) {
1142 placeWindowBefore(token.windows.get(index), win);
1143 tokenWindowsPos--;
1144 } else {
1145 int newIdx = findIdxBasedOnAppTokens(win);
1146 if(newIdx != -1) {
Romain Guy06882f82009-06-10 13:36:04 -07001147 //there is a window above this one associated with the same
1148 //apptoken note that the window could be a floating window
1149 //that was created later or a window at the top of the list of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001150 //windows associated with this token.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001151 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
1152 Slog.v(TAG, "Adding window " + win + " at "
1153 + (newIdx+1) + " of " + N);
1154 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001155 localmWindows.add(newIdx+1, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001156 mWindowsChanged = true;
Romain Guy06882f82009-06-10 13:36:04 -07001157 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001158 }
1159 }
1160 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001161 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001162 TAG, "Figuring out where to add app window "
1163 + client.asBinder() + " (token=" + token + ")");
1164 // Figure out where the window should go, based on the
1165 // order of applications.
1166 final int NA = mAppTokens.size();
Jeff Browne33348b2010-07-15 23:54:05 -07001167 WindowState pos = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001168 for (i=NA-1; i>=0; i--) {
1169 AppWindowToken t = mAppTokens.get(i);
1170 if (t == token) {
1171 i--;
1172 break;
1173 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001174
Dianne Hackborna8f60182009-09-01 19:01:50 -07001175 // We haven't reached the token yet; if this token
1176 // is not going to the bottom and has windows, we can
1177 // use it as an anchor for when we do reach the token.
1178 if (!t.sendingToBottom && t.windows.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001179 pos = t.windows.get(0);
1180 }
1181 }
1182 // We now know the index into the apps. If we found
1183 // an app window above, that gives us the position; else
1184 // we need to look some more.
1185 if (pos != null) {
1186 // Move behind any windows attached to this one.
Jeff Browne33348b2010-07-15 23:54:05 -07001187 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001188 if (atoken != null) {
1189 final int NC = atoken.windows.size();
1190 if (NC > 0) {
1191 WindowState bottom = atoken.windows.get(0);
1192 if (bottom.mSubLayer < 0) {
1193 pos = bottom;
1194 }
1195 }
1196 }
1197 placeWindowBefore(pos, win);
1198 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -07001199 // Continue looking down until we find the first
1200 // token that has windows.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001201 while (i >= 0) {
1202 AppWindowToken t = mAppTokens.get(i);
1203 final int NW = t.windows.size();
1204 if (NW > 0) {
1205 pos = t.windows.get(NW-1);
1206 break;
1207 }
1208 i--;
1209 }
1210 if (pos != null) {
1211 // Move in front of any windows attached to this
1212 // one.
Jeff Browne33348b2010-07-15 23:54:05 -07001213 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001214 if (atoken != null) {
1215 final int NC = atoken.windows.size();
1216 if (NC > 0) {
1217 WindowState top = atoken.windows.get(NC-1);
1218 if (top.mSubLayer >= 0) {
1219 pos = top;
1220 }
1221 }
1222 }
1223 placeWindowAfter(pos, win);
1224 } else {
1225 // Just search for the start of this layer.
1226 final int myLayer = win.mBaseLayer;
1227 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07001228 WindowState w = localmWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001229 if (w.mBaseLayer > myLayer) {
1230 break;
1231 }
1232 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001233 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
1234 Slog.v(TAG, "Adding window " + win + " at "
1235 + i + " of " + N);
1236 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001237 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001238 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001239 }
1240 }
1241 }
1242 } else {
1243 // Figure out where window should go, based on layer.
1244 final int myLayer = win.mBaseLayer;
1245 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07001246 if (localmWindows.get(i).mBaseLayer <= myLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001247 i++;
1248 break;
1249 }
1250 }
1251 if (i < 0) i = 0;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001252 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001253 TAG, "Adding window " + win + " at "
1254 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001255 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001256 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001257 }
1258 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001259 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001260 token.windows.add(tokenWindowsPos, win);
1261 }
1262
1263 } else {
1264 // Figure out this window's ordering relative to the window
1265 // it is attached to.
1266 final int NA = token.windows.size();
1267 final int sublayer = win.mSubLayer;
1268 int largestSublayer = Integer.MIN_VALUE;
1269 WindowState windowWithLargestSublayer = null;
1270 for (i=0; i<NA; i++) {
1271 WindowState w = token.windows.get(i);
1272 final int wSublayer = w.mSubLayer;
1273 if (wSublayer >= largestSublayer) {
1274 largestSublayer = wSublayer;
1275 windowWithLargestSublayer = w;
1276 }
1277 if (sublayer < 0) {
1278 // For negative sublayers, we go below all windows
1279 // in the same sublayer.
1280 if (wSublayer >= sublayer) {
1281 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001282 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001283 token.windows.add(i, win);
1284 }
1285 placeWindowBefore(
1286 wSublayer >= 0 ? attached : w, win);
1287 break;
1288 }
1289 } else {
1290 // For positive sublayers, we go above all windows
1291 // in the same sublayer.
1292 if (wSublayer > sublayer) {
1293 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001294 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001295 token.windows.add(i, win);
1296 }
1297 placeWindowBefore(w, win);
1298 break;
1299 }
1300 }
1301 }
1302 if (i >= NA) {
1303 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001304 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001305 token.windows.add(win);
1306 }
1307 if (sublayer < 0) {
1308 placeWindowBefore(attached, win);
1309 } else {
1310 placeWindowAfter(largestSublayer >= 0
1311 ? windowWithLargestSublayer
1312 : attached,
1313 win);
1314 }
1315 }
1316 }
Romain Guy06882f82009-06-10 13:36:04 -07001317
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001318 if (win.mAppToken != null && addToToken) {
1319 win.mAppToken.allAppWindows.add(win);
1320 }
1321 }
Romain Guy06882f82009-06-10 13:36:04 -07001322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001323 static boolean canBeImeTarget(WindowState w) {
1324 final int fl = w.mAttrs.flags
1325 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
Dianne Hackborne75d8722011-01-27 19:37:40 -08001326 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)
1327 || w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
1328 if (DEBUG_INPUT_METHOD) {
1329 Slog.i(TAG, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
1330 if (!w.isVisibleOrAdding()) {
1331 Slog.i(TAG, " mSurface=" + w.mSurface + " reportDestroy=" + w.mReportDestroySurface
1332 + " relayoutCalled=" + w.mRelayoutCalled + " viewVis=" + w.mViewVisibility
1333 + " policyVis=" + w.mPolicyVisibility + " attachHid=" + w.mAttachedHidden
1334 + " exiting=" + w.mExiting + " destroying=" + w.mDestroying);
1335 if (w.mAppToken != null) {
1336 Slog.i(TAG, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
1337 }
1338 }
1339 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001340 return w.isVisibleOrAdding();
1341 }
1342 return false;
1343 }
Romain Guy06882f82009-06-10 13:36:04 -07001344
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001345 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
Jeff Browne33348b2010-07-15 23:54:05 -07001346 final ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001347 final int N = localmWindows.size();
1348 WindowState w = null;
1349 int i = N;
1350 while (i > 0) {
1351 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001352 w = localmWindows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -07001353
Dianne Hackborne75d8722011-01-27 19:37:40 -08001354 if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG, "Checking window @" + i
1355 + " " + w + " fl=0x" + Integer.toHexString(w.mAttrs.flags));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001356 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001357 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -07001358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001359 // Yet more tricksyness! If this window is a "starting"
1360 // window, we do actually want to be on top of it, but
1361 // it is not -really- where input will go. So if the caller
1362 // is not actually looking to move the IME, look down below
1363 // for a real window to target...
1364 if (!willMove
1365 && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
1366 && i > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001367 WindowState wb = localmWindows.get(i-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001368 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1369 i--;
1370 w = wb;
1371 }
1372 }
1373 break;
1374 }
1375 }
Romain Guy06882f82009-06-10 13:36:04 -07001376
Dianne Hackborne75d8722011-01-27 19:37:40 -08001377 if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG, "Proposed new IME target: " + w);
1378
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001379 // Now, a special case -- if the last target's window is in the
1380 // process of exiting, and is above the new target, keep on the
1381 // last target to avoid flicker. Consider for example a Dialog with
1382 // the IME shown: when the Dialog is dismissed, we want to keep
1383 // the IME above it until it is completely gone so it doesn't drop
1384 // behind the dialog or its full-screen scrim.
1385 if (mInputMethodTarget != null && w != null
1386 && mInputMethodTarget.isDisplayedLw()
1387 && mInputMethodTarget.mExiting) {
1388 if (mInputMethodTarget.mAnimLayer > w.mAnimLayer) {
1389 w = mInputMethodTarget;
1390 i = localmWindows.indexOf(w);
Dianne Hackborne75d8722011-01-27 19:37:40 -08001391 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Current target higher, switching to: " + w);
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001392 }
1393 }
Romain Guy06882f82009-06-10 13:36:04 -07001394
Joe Onorato8a9b2202010-02-26 18:56:32 -08001395 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001396 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -07001397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001398 if (willMove && w != null) {
1399 final WindowState curTarget = mInputMethodTarget;
1400 if (curTarget != null && curTarget.mAppToken != null) {
Romain Guy06882f82009-06-10 13:36:04 -07001401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001402 // Now some fun for dealing with window animations that
1403 // modify the Z order. We need to look at all windows below
1404 // the current target that are in this app, finding the highest
1405 // visible one in layering.
1406 AppWindowToken token = curTarget.mAppToken;
1407 WindowState highestTarget = null;
1408 int highestPos = 0;
1409 if (token.animating || token.animation != null) {
1410 int pos = 0;
1411 pos = localmWindows.indexOf(curTarget);
1412 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001413 WindowState win = localmWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001414 if (win.mAppToken != token) {
1415 break;
1416 }
1417 if (!win.mRemoved) {
1418 if (highestTarget == null || win.mAnimLayer >
1419 highestTarget.mAnimLayer) {
1420 highestTarget = win;
1421 highestPos = pos;
1422 }
1423 }
1424 pos--;
1425 }
1426 }
Romain Guy06882f82009-06-10 13:36:04 -07001427
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001428 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001429 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001430 + mNextAppTransition + " " + highestTarget
1431 + " animating=" + highestTarget.isAnimating()
1432 + " layer=" + highestTarget.mAnimLayer
1433 + " new layer=" + w.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001434
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001435 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001436 // If we are currently setting up for an animation,
1437 // hold everything until we can find out what will happen.
1438 mInputMethodTargetWaitingAnim = true;
1439 mInputMethodTarget = highestTarget;
1440 return highestPos + 1;
1441 } else if (highestTarget.isAnimating() &&
1442 highestTarget.mAnimLayer > w.mAnimLayer) {
1443 // If the window we are currently targeting is involved
1444 // with an animation, and it is on top of the next target
1445 // we will be over, then hold off on moving until
1446 // that is done.
Dianne Hackborne75d8722011-01-27 19:37:40 -08001447 mInputMethodTargetWaitingAnim = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001448 mInputMethodTarget = highestTarget;
1449 return highestPos + 1;
1450 }
1451 }
1452 }
1453 }
Romain Guy06882f82009-06-10 13:36:04 -07001454
Joe Onorato8a9b2202010-02-26 18:56:32 -08001455 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456 if (w != null) {
1457 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001458 if (DEBUG_INPUT_METHOD) {
1459 RuntimeException e = null;
1460 if (!HIDE_STACK_CRAWLS) {
1461 e = new RuntimeException();
1462 e.fillInStackTrace();
1463 }
1464 Slog.w(TAG, "Moving IM target from "
1465 + mInputMethodTarget + " to " + w, e);
1466 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001467 mInputMethodTarget = w;
Dianne Hackborne75d8722011-01-27 19:37:40 -08001468 mInputMethodTargetWaitingAnim = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001469 if (w.mAppToken != null) {
1470 setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment);
1471 } else {
1472 setInputMethodAnimLayerAdjustment(0);
1473 }
1474 }
1475 return i+1;
1476 }
1477 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001478 if (DEBUG_INPUT_METHOD) {
1479 RuntimeException e = null;
1480 if (!HIDE_STACK_CRAWLS) {
1481 e = new RuntimeException();
1482 e.fillInStackTrace();
1483 }
1484 Slog.w(TAG, "Moving IM target from "
1485 + mInputMethodTarget + " to null", e);
1486 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487 mInputMethodTarget = null;
1488 setInputMethodAnimLayerAdjustment(0);
1489 }
1490 return -1;
1491 }
Romain Guy06882f82009-06-10 13:36:04 -07001492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001493 void addInputMethodWindowToListLocked(WindowState win) {
1494 int pos = findDesiredInputMethodWindowIndexLocked(true);
1495 if (pos >= 0) {
1496 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001497 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001498 TAG, "Adding input method window " + win + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001499 mWindows.add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001500 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001501 moveInputMethodDialogsLocked(pos+1);
1502 return;
1503 }
1504 win.mTargetAppToken = null;
1505 addWindowToListInOrderLocked(win, true);
1506 moveInputMethodDialogsLocked(pos);
1507 }
Romain Guy06882f82009-06-10 13:36:04 -07001508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001509 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001510 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 mInputMethodAnimLayerAdjustment = adj;
1512 WindowState imw = mInputMethodWindow;
1513 if (imw != null) {
1514 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001515 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001516 + " anim layer: " + imw.mAnimLayer);
1517 int wi = imw.mChildWindows.size();
1518 while (wi > 0) {
1519 wi--;
Jeff Browne33348b2010-07-15 23:54:05 -07001520 WindowState cw = imw.mChildWindows.get(wi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001521 cw.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001522 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001523 + " anim layer: " + cw.mAnimLayer);
1524 }
1525 }
1526 int di = mInputMethodDialogs.size();
1527 while (di > 0) {
1528 di --;
1529 imw = mInputMethodDialogs.get(di);
1530 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001531 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001532 + " anim layer: " + imw.mAnimLayer);
1533 }
1534 }
Romain Guy06882f82009-06-10 13:36:04 -07001535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001536 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
1537 int wpos = mWindows.indexOf(win);
1538 if (wpos >= 0) {
1539 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001540 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001541 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001542 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001543 int NC = win.mChildWindows.size();
1544 while (NC > 0) {
1545 NC--;
Jeff Browne33348b2010-07-15 23:54:05 -07001546 WindowState cw = win.mChildWindows.get(NC);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001547 int cpos = mWindows.indexOf(cw);
1548 if (cpos >= 0) {
1549 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001550 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001551 + cpos + ": " + cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001552 mWindows.remove(cpos);
1553 }
1554 }
1555 }
1556 return interestingPos;
1557 }
Romain Guy06882f82009-06-10 13:36:04 -07001558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001559 private void reAddWindowToListInOrderLocked(WindowState win) {
1560 addWindowToListInOrderLocked(win, false);
1561 // This is a hack to get all of the child windows added as well
1562 // at the right position. Child windows should be rare and
1563 // this case should be rare, so it shouldn't be that big a deal.
1564 int wpos = mWindows.indexOf(win);
1565 if (wpos >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001566 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001567 + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001569 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001570 reAddWindowLocked(wpos, win);
1571 }
1572 }
Romain Guy06882f82009-06-10 13:36:04 -07001573
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001574 void logWindowList(String prefix) {
1575 int N = mWindows.size();
1576 while (N > 0) {
1577 N--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001578 Slog.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001579 }
1580 }
Romain Guy06882f82009-06-10 13:36:04 -07001581
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001582 void moveInputMethodDialogsLocked(int pos) {
1583 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001584
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001585 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001586 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001587 for (int i=0; i<N; i++) {
1588 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1589 }
1590 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001591 Slog.v(TAG, "Window list w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001592 logWindowList(" ");
1593 }
Romain Guy06882f82009-06-10 13:36:04 -07001594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001595 if (pos >= 0) {
1596 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
1597 if (pos < mWindows.size()) {
Jeff Browne33348b2010-07-15 23:54:05 -07001598 WindowState wp = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001599 if (wp == mInputMethodWindow) {
1600 pos++;
1601 }
1602 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001603 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001604 for (int i=0; i<N; i++) {
1605 WindowState win = dialogs.get(i);
1606 win.mTargetAppToken = targetAppToken;
1607 pos = reAddWindowLocked(pos, win);
1608 }
1609 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001610 Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001611 logWindowList(" ");
1612 }
1613 return;
1614 }
1615 for (int i=0; i<N; i++) {
1616 WindowState win = dialogs.get(i);
1617 win.mTargetAppToken = null;
1618 reAddWindowToListInOrderLocked(win);
1619 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001620 Slog.v(TAG, "No IM target, final list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001621 logWindowList(" ");
1622 }
1623 }
1624 }
Romain Guy06882f82009-06-10 13:36:04 -07001625
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001626 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1627 final WindowState imWin = mInputMethodWindow;
1628 final int DN = mInputMethodDialogs.size();
1629 if (imWin == null && DN == 0) {
1630 return false;
1631 }
Romain Guy06882f82009-06-10 13:36:04 -07001632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001633 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1634 if (imPos >= 0) {
1635 // In this case, the input method windows are to be placed
1636 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001637
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001638 // First check to see if the input method windows are already
1639 // located here, and contiguous.
1640 final int N = mWindows.size();
1641 WindowState firstImWin = imPos < N
Jeff Browne33348b2010-07-15 23:54:05 -07001642 ? mWindows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001643
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001644 // Figure out the actual input method window that should be
1645 // at the bottom of their stack.
1646 WindowState baseImWin = imWin != null
1647 ? imWin : mInputMethodDialogs.get(0);
1648 if (baseImWin.mChildWindows.size() > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001649 WindowState cw = baseImWin.mChildWindows.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001650 if (cw.mSubLayer < 0) baseImWin = cw;
1651 }
Romain Guy06882f82009-06-10 13:36:04 -07001652
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001653 if (firstImWin == baseImWin) {
1654 // The windows haven't moved... but are they still contiguous?
1655 // First find the top IM window.
1656 int pos = imPos+1;
1657 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001658 if (!(mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001659 break;
1660 }
1661 pos++;
1662 }
1663 pos++;
1664 // Now there should be no more input method windows above.
1665 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001666 if ((mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001667 break;
1668 }
1669 pos++;
1670 }
1671 if (pos >= N) {
1672 // All is good!
1673 return false;
1674 }
1675 }
Romain Guy06882f82009-06-10 13:36:04 -07001676
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001677 if (imWin != null) {
1678 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001679 Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001680 logWindowList(" ");
1681 }
1682 imPos = tmpRemoveWindowLocked(imPos, imWin);
1683 if (DEBUG_INPUT_METHOD) {
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001684 Slog.v(TAG, "List after removing with new pos " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001685 logWindowList(" ");
1686 }
1687 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1688 reAddWindowLocked(imPos, imWin);
1689 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001690 Slog.v(TAG, "List after moving IM to " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001691 logWindowList(" ");
1692 }
1693 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1694 } else {
1695 moveInputMethodDialogsLocked(imPos);
1696 }
Romain Guy06882f82009-06-10 13:36:04 -07001697
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001698 } else {
1699 // In this case, the input method windows go in a fixed layer,
1700 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001701
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001702 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001703 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001704 tmpRemoveWindowLocked(0, imWin);
1705 imWin.mTargetAppToken = null;
1706 reAddWindowToListInOrderLocked(imWin);
1707 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001708 Slog.v(TAG, "List with no IM target:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001709 logWindowList(" ");
1710 }
1711 if (DN > 0) moveInputMethodDialogsLocked(-1);;
1712 } else {
1713 moveInputMethodDialogsLocked(-1);;
1714 }
Romain Guy06882f82009-06-10 13:36:04 -07001715
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001716 }
Romain Guy06882f82009-06-10 13:36:04 -07001717
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001718 if (needAssignLayers) {
1719 assignLayersLocked();
1720 }
Romain Guy06882f82009-06-10 13:36:04 -07001721
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001722 return true;
1723 }
Romain Guy06882f82009-06-10 13:36:04 -07001724
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001725 void adjustInputMethodDialogsLocked() {
1726 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1727 }
Romain Guy06882f82009-06-10 13:36:04 -07001728
Dianne Hackborn25994b42009-09-04 14:21:19 -07001729 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001730 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001731 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1732 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
1733 ? wallpaperTarget.mAppToken.animation : null)
1734 + " upper=" + mUpperWallpaperTarget
1735 + " lower=" + mLowerWallpaperTarget);
1736 return (wallpaperTarget != null
1737 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
1738 && wallpaperTarget.mAppToken.animation != null)))
1739 || mUpperWallpaperTarget != null
1740 || mLowerWallpaperTarget != null;
1741 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001742
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001743 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1744 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001745
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001746 int adjustWallpaperWindowsLocked() {
1747 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001748
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001749 final int dw = mDisplay.getWidth();
1750 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001751
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001752 // First find top-most window that has asked to be on top of the
1753 // wallpaper; all wallpapers go behind it.
Jeff Browne33348b2010-07-15 23:54:05 -07001754 final ArrayList<WindowState> localmWindows = mWindows;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001755 int N = localmWindows.size();
1756 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001757 WindowState foundW = null;
1758 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001759 WindowState topCurW = null;
1760 int topCurI = 0;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001761 int windowDetachedI = -1;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001762 int i = N;
1763 while (i > 0) {
1764 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001765 w = localmWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001766 if ((w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER)) {
1767 if (topCurW == null) {
1768 topCurW = w;
1769 topCurI = i;
1770 }
1771 continue;
1772 }
1773 topCurW = null;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001774 if (w != mWindowDetachedWallpaper && w.mAppToken != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001775 // If this window's app token is hidden and not animating,
1776 // it is of no interest to us.
1777 if (w.mAppToken.hidden && w.mAppToken.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001778 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001779 "Skipping not hidden or animating token: " + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001780 continue;
1781 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001782 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001783 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": readyfordisplay="
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001784 + w.isReadyForDisplay() + " drawpending=" + w.mDrawPending
1785 + " commitdrawpending=" + w.mCommitDrawPending);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001786 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07001787 && (mWallpaperTarget == w
1788 || (!w.mDrawPending && !w.mCommitDrawPending))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001789 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001790 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001791 foundW = w;
1792 foundI = i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001793 if (w == mWallpaperTarget && ((w.mAppToken != null
1794 && w.mAppToken.animation != null)
1795 || w.mAnimation != null)) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001796 // The current wallpaper target is animating, so we'll
1797 // look behind it for another possible target and figure
1798 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001799 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001800 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001801 continue;
1802 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001803 break;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001804 } else if (w == mWindowDetachedWallpaper) {
1805 windowDetachedI = i;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001806 }
1807 }
1808
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001809 if (foundW == null && windowDetachedI >= 0) {
1810 if (DEBUG_WALLPAPER) Slog.v(TAG,
1811 "Found animating detached wallpaper activity: #" + i + "=" + w);
1812 foundW = w;
1813 foundI = windowDetachedI;
1814 }
1815
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001816 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001817 // If we are currently waiting for an app transition, and either
1818 // the current target or the next target are involved with it,
1819 // then hold off on doing anything with the wallpaper.
1820 // Note that we are checking here for just whether the target
1821 // is part of an app token... which is potentially overly aggressive
1822 // (the app token may not be involved in the transition), but good
1823 // enough (we'll just wait until whatever transition is pending
1824 // executes).
1825 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001826 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001827 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001828 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001829 }
1830 if (foundW != null && foundW.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001831 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001832 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001833 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001834 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001835 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001836
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001837 if (mWallpaperTarget != foundW) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001838 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001839 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001840 + " oldTarget: " + mWallpaperTarget);
1841 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001842
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001843 mLowerWallpaperTarget = null;
1844 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001845
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001846 WindowState oldW = mWallpaperTarget;
1847 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001848
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001849 // Now what is happening... if the current and new targets are
1850 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001851 if (foundW != null && oldW != null) {
1852 boolean oldAnim = oldW.mAnimation != null
1853 || (oldW.mAppToken != null && oldW.mAppToken.animation != null);
1854 boolean foundAnim = foundW.mAnimation != null
1855 || (foundW.mAppToken != null && foundW.mAppToken.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001856 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001857 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001858 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001859 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001860 if (foundAnim && oldAnim) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001861 int oldI = localmWindows.indexOf(oldW);
1862 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001863 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001864 }
1865 if (oldI >= 0) {
1866 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001867 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001868 + "=" + oldW + "; new#" + foundI
1869 + "=" + foundW);
1870 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001871
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001872 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001873 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001874 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001875 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001876 }
1877 mWallpaperTarget = oldW;
1878 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001879
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001880 // Now set the upper and lower wallpaper targets
1881 // correctly, and make sure that we are positioning
1882 // the wallpaper below the lower.
1883 if (foundI > oldI) {
1884 // The new target is on top of the old one.
1885 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001886 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001887 }
1888 mUpperWallpaperTarget = foundW;
1889 mLowerWallpaperTarget = oldW;
1890 foundW = oldW;
1891 foundI = oldI;
1892 } else {
1893 // The new target is below the old one.
1894 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001895 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001896 }
1897 mUpperWallpaperTarget = oldW;
1898 mLowerWallpaperTarget = foundW;
1899 }
1900 }
1901 }
1902 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001903
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001904 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001905 // Is it time to stop animating?
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001906 boolean lowerAnimating = mLowerWallpaperTarget.mAnimation != null
1907 || (mLowerWallpaperTarget.mAppToken != null
1908 && mLowerWallpaperTarget.mAppToken.animation != null);
1909 boolean upperAnimating = mUpperWallpaperTarget.mAnimation != null
1910 || (mUpperWallpaperTarget.mAppToken != null
1911 && mUpperWallpaperTarget.mAppToken.animation != null);
1912 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001913 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001914 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001915 }
1916 mLowerWallpaperTarget = null;
1917 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001918 }
1919 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001920
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001921 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001922 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001923 // The window is visible to the compositor... but is it visible
1924 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001925 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001926 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001927
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001928 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001929 // its layer adjustment. Only do this if we are not transfering
1930 // between two wallpaper targets.
1931 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001932 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001933 ? foundW.mAppToken.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001934
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001935 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1936 * TYPE_LAYER_MULTIPLIER
1937 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001938
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001939 // Now w is the window we are supposed to be behind... but we
1940 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001941 // AND any starting window associated with it, AND below the
1942 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001943 while (foundI > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001944 WindowState wb = localmWindows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001945 if (wb.mBaseLayer < maxLayer &&
1946 wb.mAttachedWindow != foundW &&
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001947 (foundW.mAttachedWindow == null ||
1948 wb.mAttachedWindow != foundW.mAttachedWindow) &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001949 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001950 foundW.mToken == null || wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001951 // This window is not related to the previous one in any
1952 // interesting way, so stop here.
1953 break;
1954 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001955 foundW = wb;
1956 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001957 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001958 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001959 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001960 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001961
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001962 if (foundW == null && topCurW != null) {
1963 // There is no wallpaper target, so it goes at the bottom.
1964 // We will assume it is the same place as last time, if known.
1965 foundW = topCurW;
1966 foundI = topCurI+1;
1967 } else {
1968 // Okay i is the position immediately above the wallpaper. Look at
1969 // what is below it for later.
Jeff Browne33348b2010-07-15 23:54:05 -07001970 foundW = foundI > 0 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001971 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001972
Dianne Hackborn284ac932009-08-28 10:34:25 -07001973 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001974 if (mWallpaperTarget.mWallpaperX >= 0) {
1975 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001976 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001977 }
1978 if (mWallpaperTarget.mWallpaperY >= 0) {
1979 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001980 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001981 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001982 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001983
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001984 // Start stepping backwards from here, ensuring that our wallpaper windows
1985 // are correctly placed.
1986 int curTokenIndex = mWallpaperTokens.size();
1987 while (curTokenIndex > 0) {
1988 curTokenIndex--;
1989 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001990 if (token.hidden == visible) {
1991 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1992 token.hidden = !visible;
1993 // Need to do a layout to ensure the wallpaper now has the
1994 // correct size.
1995 mLayoutNeeded = true;
1996 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001997
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001998 int curWallpaperIndex = token.windows.size();
1999 while (curWallpaperIndex > 0) {
2000 curWallpaperIndex--;
2001 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002002
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002003 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002004 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002005 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002006
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002007 // First, make sure the client has the current visibility
2008 // state.
2009 if (wallpaper.mWallpaperVisible != visible) {
2010 wallpaper.mWallpaperVisible = visible;
2011 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002012 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002013 "Setting visibility of wallpaper " + wallpaper
2014 + ": " + visible);
2015 wallpaper.mClient.dispatchAppVisibility(visible);
2016 } catch (RemoteException e) {
2017 }
2018 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002019
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002020 wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002021 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002022 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002023
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002024 // First, if this window is at the current index, then all
2025 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002026 if (wallpaper == foundW) {
2027 foundI--;
2028 foundW = foundI > 0
Jeff Browne33348b2010-07-15 23:54:05 -07002029 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002030 continue;
2031 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002032
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002033 // The window didn't match... the current wallpaper window,
2034 // wherever it is, is in the wrong place, so make sure it is
2035 // not in the list.
2036 int oldIndex = localmWindows.indexOf(wallpaper);
2037 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002038 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07002039 + oldIndex + ": " + wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002040 localmWindows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002041 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002042 if (oldIndex < foundI) {
2043 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002044 }
2045 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002046
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002047 // Now stick it in.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002048 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
2049 Slog.v(TAG, "Moving wallpaper " + wallpaper
2050 + " from " + oldIndex + " to " + foundI);
2051 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002052
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002053 localmWindows.add(foundI, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002054 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002055 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002056 }
2057 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002058
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002059 return changed;
2060 }
2061
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002062 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002063 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002064 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002065 mWallpaperAnimLayerAdjustment = adj;
2066 int curTokenIndex = mWallpaperTokens.size();
2067 while (curTokenIndex > 0) {
2068 curTokenIndex--;
2069 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2070 int curWallpaperIndex = token.windows.size();
2071 while (curWallpaperIndex > 0) {
2072 curWallpaperIndex--;
2073 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2074 wallpaper.mAnimLayer = wallpaper.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002075 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002076 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002077 }
2078 }
2079 }
2080
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002081 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
2082 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002083 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002084 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002085 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002086 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002087 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
2088 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
2089 changed = wallpaperWin.mXOffset != offset;
2090 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002091 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002092 + wallpaperWin + " x: " + offset);
2093 wallpaperWin.mXOffset = offset;
2094 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002095 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002096 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002097 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002098 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002099 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002100
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002101 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002102 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002103 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
2104 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
2105 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002106 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002107 + wallpaperWin + " y: " + offset);
2108 changed = true;
2109 wallpaperWin.mYOffset = offset;
2110 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002111 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002112 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002113 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002114 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002115 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002116
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002117 if (rawChanged) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002118 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002119 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002120 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
2121 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002122 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002123 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002124 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002125 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002126 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
2127 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002128 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002129 if (mWaitingOnWallpaper != null) {
2130 long start = SystemClock.uptimeMillis();
2131 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
2132 < start) {
2133 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002134 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07002135 "Waiting for offset complete...");
2136 mWindowMap.wait(WALLPAPER_TIMEOUT);
2137 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002138 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002139 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07002140 if ((start+WALLPAPER_TIMEOUT)
2141 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002142 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07002143 + wallpaperWin);
2144 mLastWallpaperTimeoutTime = start;
2145 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002146 }
Dianne Hackborn75804932009-10-20 20:15:20 -07002147 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002148 }
2149 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002150 } catch (RemoteException e) {
2151 }
2152 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002153
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002154 return changed;
2155 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002156
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002157 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002158 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002159 if (mWaitingOnWallpaper != null &&
2160 mWaitingOnWallpaper.mClient.asBinder() == window) {
2161 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07002162 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002163 }
2164 }
2165 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002166
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002167 boolean updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002168 final int dw = mDisplay.getWidth();
2169 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002170
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002171 boolean changed = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002172
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002173 WindowState target = mWallpaperTarget;
2174 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002175 if (target.mWallpaperX >= 0) {
2176 mLastWallpaperX = target.mWallpaperX;
2177 } else if (changingTarget.mWallpaperX >= 0) {
2178 mLastWallpaperX = changingTarget.mWallpaperX;
2179 }
2180 if (target.mWallpaperY >= 0) {
2181 mLastWallpaperY = target.mWallpaperY;
2182 } else if (changingTarget.mWallpaperY >= 0) {
2183 mLastWallpaperY = changingTarget.mWallpaperY;
2184 }
2185 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002186
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002187 int curTokenIndex = mWallpaperTokens.size();
2188 while (curTokenIndex > 0) {
2189 curTokenIndex--;
2190 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2191 int curWallpaperIndex = token.windows.size();
2192 while (curWallpaperIndex > 0) {
2193 curWallpaperIndex--;
2194 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2195 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
2196 wallpaper.computeShownFrameLocked();
2197 changed = true;
2198 // We only want to be synchronous with one wallpaper.
2199 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002200 }
2201 }
2202 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002203
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002204 return changed;
2205 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002206
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002207 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07002208 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002209 final int dw = mDisplay.getWidth();
2210 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002211
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002212 int curTokenIndex = mWallpaperTokens.size();
2213 while (curTokenIndex > 0) {
2214 curTokenIndex--;
2215 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002216 if (token.hidden == visible) {
2217 token.hidden = !visible;
2218 // Need to do a layout to ensure the wallpaper now has the
2219 // correct size.
2220 mLayoutNeeded = true;
2221 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002222
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002223 int curWallpaperIndex = token.windows.size();
2224 while (curWallpaperIndex > 0) {
2225 curWallpaperIndex--;
2226 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2227 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002228 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002229 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002230
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002231 if (wallpaper.mWallpaperVisible != visible) {
2232 wallpaper.mWallpaperVisible = visible;
2233 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002234 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07002235 "Updating visibility of wallpaper " + wallpaper
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002236 + ": " + visible);
2237 wallpaper.mClient.dispatchAppVisibility(visible);
2238 } catch (RemoteException e) {
2239 }
2240 }
2241 }
2242 }
2243 }
Dianne Hackborn90d2db32010-02-11 22:19:06 -08002244
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002245 public int addWindow(Session session, IWindow client,
2246 WindowManager.LayoutParams attrs, int viewVisibility,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002247 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002248 int res = mPolicy.checkAddPermission(attrs);
2249 if (res != WindowManagerImpl.ADD_OKAY) {
2250 return res;
2251 }
Romain Guy06882f82009-06-10 13:36:04 -07002252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002253 boolean reportNewConfig = false;
2254 WindowState attachedWindow = null;
2255 WindowState win = null;
Dianne Hackborn5132b372010-07-29 12:51:35 -07002256 long origId;
Romain Guy06882f82009-06-10 13:36:04 -07002257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002258 synchronized(mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002259 if (mDisplay == null) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07002260 throw new IllegalStateException("Display has not been initialialized");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002261 }
Romain Guy06882f82009-06-10 13:36:04 -07002262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002263 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002264 Slog.w(TAG, "Window " + client + " is already added");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002265 return WindowManagerImpl.ADD_DUPLICATE_ADD;
2266 }
2267
2268 if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002269 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002270 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002271 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002272 + attrs.token + ". Aborting.");
2273 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2274 }
2275 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
2276 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002277 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002278 + attrs.token + ". Aborting.");
2279 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2280 }
2281 }
2282
2283 boolean addToken = false;
2284 WindowToken token = mTokenMap.get(attrs.token);
2285 if (token == null) {
2286 if (attrs.type >= FIRST_APPLICATION_WINDOW
2287 && attrs.type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002288 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002289 + attrs.token + ". Aborting.");
2290 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2291 }
2292 if (attrs.type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002293 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002294 + attrs.token + ". Aborting.");
2295 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2296 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002297 if (attrs.type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002298 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002299 + attrs.token + ". Aborting.");
2300 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2301 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002302 token = new WindowToken(attrs.token, -1, false);
2303 addToken = true;
2304 } else if (attrs.type >= FIRST_APPLICATION_WINDOW
2305 && attrs.type <= LAST_APPLICATION_WINDOW) {
2306 AppWindowToken atoken = token.appWindowToken;
2307 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002308 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002309 + token + ". Aborting.");
2310 return WindowManagerImpl.ADD_NOT_APP_TOKEN;
2311 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002312 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002313 + token + ". Aborting.");
2314 return WindowManagerImpl.ADD_APP_EXITING;
2315 }
2316 if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
2317 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002318 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002319 TAG, "**** NO NEED TO START: " + attrs.getTitle());
2320 return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
2321 }
2322 } else if (attrs.type == TYPE_INPUT_METHOD) {
2323 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002324 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002325 + attrs.token + ". Aborting.");
2326 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2327 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002328 } else if (attrs.type == TYPE_WALLPAPER) {
2329 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002330 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002331 + attrs.token + ". Aborting.");
2332 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2333 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002334 }
2335
2336 win = new WindowState(session, client, token,
2337 attachedWindow, attrs, viewVisibility);
2338 if (win.mDeathRecipient == null) {
2339 // Client has apparently died, so there is no reason to
2340 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002341 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002342 + " that is dead, aborting.");
2343 return WindowManagerImpl.ADD_APP_EXITING;
2344 }
2345
2346 mPolicy.adjustWindowParamsLw(win.mAttrs);
Romain Guy06882f82009-06-10 13:36:04 -07002347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002348 res = mPolicy.prepareAddWindowLw(win, attrs);
2349 if (res != WindowManagerImpl.ADD_OKAY) {
2350 return res;
2351 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002352
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002353 if (outInputChannel != null) {
2354 String name = win.makeInputChannelName();
2355 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
2356 win.mInputChannel = inputChannels[0];
2357 inputChannels[1].transferToBinderOutParameter(outInputChannel);
2358
Jeff Brown928e0542011-01-10 11:17:36 -08002359 mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002360 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002361
2362 // From now on, no exceptions or errors allowed!
2363
2364 res = WindowManagerImpl.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002365
Dianne Hackborn5132b372010-07-29 12:51:35 -07002366 origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002367
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002368 if (addToken) {
2369 mTokenMap.put(attrs.token, token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002370 }
2371 win.attach();
2372 mWindowMap.put(client.asBinder(), win);
2373
2374 if (attrs.type == TYPE_APPLICATION_STARTING &&
2375 token.appWindowToken != null) {
2376 token.appWindowToken.startingWindow = win;
2377 }
2378
2379 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002380
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002381 if (attrs.type == TYPE_INPUT_METHOD) {
2382 mInputMethodWindow = win;
2383 addInputMethodWindowToListLocked(win);
2384 imMayMove = false;
2385 } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
2386 mInputMethodDialogs.add(win);
2387 addWindowToListInOrderLocked(win, true);
2388 adjustInputMethodDialogsLocked();
2389 imMayMove = false;
2390 } else {
2391 addWindowToListInOrderLocked(win, true);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002392 if (attrs.type == TYPE_WALLPAPER) {
2393 mLastWallpaperTimeoutTime = 0;
2394 adjustWallpaperWindowsLocked();
2395 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002396 adjustWallpaperWindowsLocked();
2397 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002398 }
Romain Guy06882f82009-06-10 13:36:04 -07002399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002400 win.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002402 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
Romain Guy06882f82009-06-10 13:36:04 -07002403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002404 if (mInTouchMode) {
2405 res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
2406 }
2407 if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
2408 res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
2409 }
Romain Guy06882f82009-06-10 13:36:04 -07002410
Jeff Brown2e44b072011-01-24 15:21:56 -08002411 mInputMonitor.setUpdateInputWindowsNeededLw();
2412
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002413 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002414 if (win.canReceiveKeys()) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002415 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
2416 false /*updateInputWindows*/);
Jeff Brown349703e2010-06-22 01:27:15 -07002417 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002418 imMayMove = false;
2419 }
2420 }
Romain Guy06882f82009-06-10 13:36:04 -07002421
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002422 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002423 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002424 }
Romain Guy06882f82009-06-10 13:36:04 -07002425
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002426 assignLayersLocked();
2427 // Don't do layout here, the window must call
2428 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002429
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002430 //dump();
2431
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002432 if (focusChanged) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002433 finishUpdateFocusedWindowAfterAssignLayersLocked(false /*updateInputWindows*/);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002434 }
Jeff Brown2e44b072011-01-24 15:21:56 -08002435 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08002436
Joe Onorato8a9b2202010-02-26 18:56:32 -08002437 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002438 TAG, "New client " + client.asBinder()
2439 + ": window=" + win);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002440
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002441 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002442 reportNewConfig = true;
2443 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002444 }
2445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002446 if (reportNewConfig) {
2447 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002448 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07002449
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002450 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002451
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002452 return res;
2453 }
Romain Guy06882f82009-06-10 13:36:04 -07002454
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002455 public void removeWindow(Session session, IWindow client) {
2456 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002457 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002458 if (win == null) {
2459 return;
2460 }
2461 removeWindowLocked(session, win);
2462 }
2463 }
Romain Guy06882f82009-06-10 13:36:04 -07002464
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002465 public void removeWindowLocked(Session session, WindowState win) {
2466
Joe Onorato8a9b2202010-02-26 18:56:32 -08002467 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002468 TAG, "Remove " + win + " client="
2469 + Integer.toHexString(System.identityHashCode(
2470 win.mClient.asBinder()))
2471 + ", surface=" + win.mSurface);
2472
2473 final long origId = Binder.clearCallingIdentity();
Jeff Brownc5ed5912010-07-14 18:48:53 -07002474
2475 win.disposeInputChannel();
Romain Guy06882f82009-06-10 13:36:04 -07002476
Joe Onorato8a9b2202010-02-26 18:56:32 -08002477 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002478 TAG, "Remove " + win + ": mSurface=" + win.mSurface
2479 + " mExiting=" + win.mExiting
2480 + " isAnimating=" + win.isAnimating()
2481 + " app-animation="
2482 + (win.mAppToken != null ? win.mAppToken.animation : null)
2483 + " inPendingTransaction="
2484 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2485 + " mDisplayFrozen=" + mDisplayFrozen);
2486 // Visibility of the removed window. Will be used later to update orientation later on.
2487 boolean wasVisible = false;
2488 // First, see if we need to run an animation. If we do, we have
2489 // to hold off on removing the window until the animation is done.
2490 // If the display is frozen, just remove immediately, since the
2491 // animation wouldn't be seen.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002492 if (win.mSurface != null && !mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002493 // If we are not currently running the exit animation, we
2494 // need to see about starting one.
2495 if (wasVisible=win.isWinVisibleLw()) {
Romain Guy06882f82009-06-10 13:36:04 -07002496
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002497 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2498 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2499 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2500 }
2501 // Try starting an animation.
2502 if (applyAnimationLocked(win, transit, false)) {
2503 win.mExiting = true;
2504 }
2505 }
2506 if (win.mExiting || win.isAnimating()) {
2507 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002508 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002509 win.mExiting = true;
2510 win.mRemoveOnExit = true;
2511 mLayoutNeeded = true;
Jeff Brown3a22cd92011-01-21 13:59:04 -08002512 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2513 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002514 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08002515 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002516 if (win.mAppToken != null) {
2517 win.mAppToken.updateReportedVisibilityLocked();
2518 }
2519 //dump();
2520 Binder.restoreCallingIdentity(origId);
2521 return;
2522 }
2523 }
2524
2525 removeWindowInnerLocked(session, win);
2526 // Removing a visible window will effect the computed orientation
2527 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002528 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002529 != mForcedAppOrientation
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002530 && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002531 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002532 }
Jeff Brown3a22cd92011-01-21 13:59:04 -08002533 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002534 Binder.restoreCallingIdentity(origId);
2535 }
Romain Guy06882f82009-06-10 13:36:04 -07002536
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002537 private void removeWindowInnerLocked(Session session, WindowState win) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002538 if (win.mRemoved) {
2539 // Nothing to do.
2540 return;
2541 }
2542
2543 for (int i=win.mChildWindows.size()-1; i>=0; i--) {
2544 WindowState cwin = win.mChildWindows.get(i);
2545 Slog.w(TAG, "Force-removing child win " + cwin + " from container "
2546 + win);
2547 removeWindowInnerLocked(cwin.mSession, cwin);
2548 }
2549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002550 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002551
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002552 if (mInputMethodTarget == win) {
2553 moveInputMethodWindowsIfNeededLocked(false);
2554 }
Romain Guy06882f82009-06-10 13:36:04 -07002555
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002556 if (false) {
2557 RuntimeException e = new RuntimeException("here");
2558 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002559 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002560 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002561
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002562 mPolicy.removeWindowLw(win);
2563 win.removeLocked();
2564
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002565 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002566 mWindowMap.remove(win.mClient.asBinder());
2567 mWindows.remove(win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002568 mPendingRemove.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002569 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002570 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002571
2572 if (mInputMethodWindow == win) {
2573 mInputMethodWindow = null;
2574 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2575 mInputMethodDialogs.remove(win);
2576 }
Romain Guy06882f82009-06-10 13:36:04 -07002577
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002578 final WindowToken token = win.mToken;
2579 final AppWindowToken atoken = win.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002580 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + win + " from " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002581 token.windows.remove(win);
2582 if (atoken != null) {
2583 atoken.allAppWindows.remove(win);
2584 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002585 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002586 TAG, "**** Removing window " + win + ": count="
2587 + token.windows.size());
2588 if (token.windows.size() == 0) {
2589 if (!token.explicit) {
2590 mTokenMap.remove(token.token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002591 } else if (atoken != null) {
2592 atoken.firstWindowDrawn = false;
2593 }
2594 }
2595
2596 if (atoken != null) {
2597 if (atoken.startingWindow == win) {
2598 atoken.startingWindow = null;
2599 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2600 // If this is the last window and we had requested a starting
2601 // transition window, well there is no point now.
2602 atoken.startingData = null;
2603 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2604 // If this is the last window except for a starting transition
2605 // window, we need to get rid of the starting transition.
2606 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002607 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002608 + ": no more real windows");
2609 }
2610 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2611 mH.sendMessage(m);
2612 }
2613 }
Romain Guy06882f82009-06-10 13:36:04 -07002614
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002615 if (win.mAttrs.type == TYPE_WALLPAPER) {
2616 mLastWallpaperTimeoutTime = 0;
2617 adjustWallpaperWindowsLocked();
2618 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002619 adjustWallpaperWindowsLocked();
2620 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002621
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002622 if (!mInLayout) {
2623 assignLayersLocked();
2624 mLayoutNeeded = true;
2625 performLayoutAndPlaceSurfacesLocked();
2626 if (win.mAppToken != null) {
2627 win.mAppToken.updateReportedVisibilityLocked();
2628 }
2629 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07002630
Jeff Brown2e44b072011-01-24 15:21:56 -08002631 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002632 }
2633
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002634 private static void logSurface(WindowState w, String msg, RuntimeException where) {
2635 String str = " SURFACE " + Integer.toHexString(w.hashCode())
2636 + ": " + msg + " / " + w.mAttrs.getTitle();
2637 if (where != null) {
2638 Slog.i(TAG, str, where);
2639 } else {
2640 Slog.i(TAG, str);
2641 }
2642 }
2643
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002644 private void setTransparentRegionWindow(Session session, IWindow client, Region region) {
2645 long origId = Binder.clearCallingIdentity();
2646 try {
2647 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002648 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002649 if ((w != null) && (w.mSurface != null)) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002650 if (SHOW_TRANSACTIONS) Slog.i(TAG,
2651 ">>> OPEN TRANSACTION setTransparentRegion");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002652 Surface.openTransaction();
2653 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002654 if (SHOW_TRANSACTIONS) logSurface(w,
2655 "transparentRegionHint=" + region, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002656 w.mSurface.setTransparentRegionHint(region);
2657 } finally {
2658 Surface.closeTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002659 if (SHOW_TRANSACTIONS) Slog.i(TAG,
2660 "<<< CLOSE TRANSACTION setTransparentRegion");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002661 }
2662 }
2663 }
2664 } finally {
2665 Binder.restoreCallingIdentity(origId);
2666 }
2667 }
2668
2669 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002670 int touchableInsets, Rect contentInsets,
Jeff Brownfbf09772011-01-16 14:06:57 -08002671 Rect visibleInsets, Region touchableRegion) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002672 long origId = Binder.clearCallingIdentity();
2673 try {
2674 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002675 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002676 if (w != null) {
2677 w.mGivenInsetsPending = false;
2678 w.mGivenContentInsets.set(contentInsets);
2679 w.mGivenVisibleInsets.set(visibleInsets);
Jeff Brownfbf09772011-01-16 14:06:57 -08002680 w.mGivenTouchableRegion.set(touchableRegion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002681 w.mTouchableInsets = touchableInsets;
2682 mLayoutNeeded = true;
2683 performLayoutAndPlaceSurfacesLocked();
2684 }
2685 }
2686 } finally {
2687 Binder.restoreCallingIdentity(origId);
2688 }
2689 }
Romain Guy06882f82009-06-10 13:36:04 -07002690
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002691 public void getWindowDisplayFrame(Session session, IWindow client,
2692 Rect outDisplayFrame) {
2693 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002694 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002695 if (win == null) {
2696 outDisplayFrame.setEmpty();
2697 return;
2698 }
2699 outDisplayFrame.set(win.mDisplayFrame);
2700 }
2701 }
2702
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002703 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2704 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002705 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2706 window.mWallpaperX = x;
2707 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002708 window.mWallpaperXStep = xStep;
2709 window.mWallpaperYStep = yStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002710 if (updateWallpaperOffsetLocked(window, true)) {
2711 performLayoutAndPlaceSurfacesLocked();
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002712 }
2713 }
2714 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002715
Dianne Hackborn75804932009-10-20 20:15:20 -07002716 void wallpaperCommandComplete(IBinder window, Bundle result) {
2717 synchronized (mWindowMap) {
2718 if (mWaitingOnWallpaper != null &&
2719 mWaitingOnWallpaper.mClient.asBinder() == window) {
2720 mWaitingOnWallpaper = null;
2721 mWindowMap.notifyAll();
2722 }
2723 }
2724 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002725
Dianne Hackborn75804932009-10-20 20:15:20 -07002726 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2727 String action, int x, int y, int z, Bundle extras, boolean sync) {
2728 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2729 || window == mUpperWallpaperTarget) {
2730 boolean doWait = sync;
2731 int curTokenIndex = mWallpaperTokens.size();
2732 while (curTokenIndex > 0) {
2733 curTokenIndex--;
2734 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2735 int curWallpaperIndex = token.windows.size();
2736 while (curWallpaperIndex > 0) {
2737 curWallpaperIndex--;
2738 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2739 try {
2740 wallpaper.mClient.dispatchWallpaperCommand(action,
2741 x, y, z, extras, sync);
2742 // We only want to be synchronous with one wallpaper.
2743 sync = false;
2744 } catch (RemoteException e) {
2745 }
2746 }
2747 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002748
Dianne Hackborn75804932009-10-20 20:15:20 -07002749 if (doWait) {
2750 // XXX Need to wait for result.
2751 }
2752 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002753
Dianne Hackborn75804932009-10-20 20:15:20 -07002754 return null;
2755 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002756
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002757 public int relayoutWindow(Session session, IWindow client,
2758 WindowManager.LayoutParams attrs, int requestedWidth,
2759 int requestedHeight, int viewVisibility, boolean insetsPending,
2760 Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002761 Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002762 boolean displayed = false;
2763 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002764 boolean configChanged;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002765
2766 // if they don't have this permission, mask out the status bar bits
2767 if (attrs != null) {
2768 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
2769 != PackageManager.PERMISSION_GRANTED) {
2770 attrs.systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
2771 attrs.subtreeSystemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
2772 }
2773 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002774 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002775
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002776 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002777 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002778 if (win == null) {
2779 return 0;
2780 }
2781 win.mRequestedWidth = requestedWidth;
2782 win.mRequestedHeight = requestedHeight;
2783
2784 if (attrs != null) {
2785 mPolicy.adjustWindowParamsLw(attrs);
2786 }
Romain Guy06882f82009-06-10 13:36:04 -07002787
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002788 int attrChanges = 0;
2789 int flagChanges = 0;
2790 if (attrs != null) {
2791 flagChanges = win.mAttrs.flags ^= attrs.flags;
2792 attrChanges = win.mAttrs.copyFrom(attrs);
2793 }
2794
Joe Onorato8a9b2202010-02-26 18:56:32 -08002795 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002796
2797 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
2798 win.mAlpha = attrs.alpha;
2799 }
2800
2801 final boolean scaledWindow =
2802 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2803
2804 if (scaledWindow) {
2805 // requested{Width|Height} Surface's physical size
2806 // attrs.{width|height} Size on screen
2807 win.mHScale = (attrs.width != requestedWidth) ?
2808 (attrs.width / (float)requestedWidth) : 1.0f;
2809 win.mVScale = (attrs.height != requestedHeight) ?
2810 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002811 } else {
2812 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002813 }
2814
2815 boolean imMayMove = (flagChanges&(
2816 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
2817 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002818
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002819 boolean focusMayChange = win.mViewVisibility != viewVisibility
2820 || ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
2821 || (!win.mRelayoutCalled);
Romain Guy06882f82009-06-10 13:36:04 -07002822
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002823 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2824 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002825
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002826 win.mRelayoutCalled = true;
2827 final int oldVisibility = win.mViewVisibility;
2828 win.mViewVisibility = viewVisibility;
2829 if (viewVisibility == View.VISIBLE &&
2830 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
2831 displayed = !win.isVisibleLw();
2832 if (win.mExiting) {
2833 win.mExiting = false;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07002834 if (win.mAnimation != null) {
2835 win.mAnimation.cancel();
2836 win.mAnimation = null;
2837 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002838 }
2839 if (win.mDestroying) {
2840 win.mDestroying = false;
2841 mDestroySurface.remove(win);
2842 }
2843 if (oldVisibility == View.GONE) {
2844 win.mEnterAnimationPending = true;
2845 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002846 if (displayed) {
2847 if (win.mSurface != null && !win.mDrawPending
2848 && !win.mCommitDrawPending && !mDisplayFrozen
2849 && mPolicy.isScreenOn()) {
2850 applyEnterAnimationLocked(win);
2851 }
2852 if ((win.mAttrs.flags
2853 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2854 if (DEBUG_VISIBILITY) Slog.v(TAG,
2855 "Relayout window turning screen on: " + win);
2856 win.mTurnOnScreen = true;
2857 }
2858 int diff = 0;
2859 if (win.mConfiguration != mCurConfiguration
2860 && (win.mConfiguration == null
2861 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2862 win.mConfiguration = mCurConfiguration;
2863 if (DEBUG_CONFIGURATION) {
2864 Slog.i(TAG, "Window " + win + " visible with new config: "
2865 + win.mConfiguration + " / 0x"
2866 + Integer.toHexString(diff));
2867 }
2868 outConfig.setTo(mCurConfiguration);
2869 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002870 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002871 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2872 // To change the format, we need to re-build the surface.
2873 win.destroySurfaceLocked();
2874 displayed = true;
2875 }
2876 try {
2877 Surface surface = win.createSurfaceLocked();
2878 if (surface != null) {
2879 outSurface.copyFrom(surface);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002880 win.mReportDestroySurface = false;
2881 win.mSurfacePendingDestroy = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002882 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002883 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002884 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002885 // For some reason there isn't a surface. Clear the
2886 // caller's object so they see the same state.
2887 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002888 }
2889 } catch (Exception e) {
Jeff Brown2e44b072011-01-24 15:21:56 -08002890 mInputMonitor.updateInputWindowsLw(true /*force*/);
Jeff Browne33348b2010-07-15 23:54:05 -07002891
Joe Onorato8a9b2202010-02-26 18:56:32 -08002892 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002893 + client + " (" + win.mAttrs.getTitle() + ")",
2894 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002895 Binder.restoreCallingIdentity(origId);
2896 return 0;
2897 }
2898 if (displayed) {
2899 focusMayChange = true;
2900 }
2901 if (win.mAttrs.type == TYPE_INPUT_METHOD
2902 && mInputMethodWindow == null) {
2903 mInputMethodWindow = win;
2904 imMayMove = true;
2905 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002906 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2907 && win.mAppToken != null
2908 && win.mAppToken.startingWindow != null) {
2909 // Special handling of starting window over the base
2910 // window of the app: propagate lock screen flags to it,
2911 // to provide the correct semantics while starting.
2912 final int mask =
2913 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002914 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2915 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002916 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2917 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2918 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002919 } else {
2920 win.mEnterAnimationPending = false;
2921 if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002922 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002923 + ": mExiting=" + win.mExiting
2924 + " mSurfacePendingDestroy=" + win.mSurfacePendingDestroy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002925 // If we are not currently running the exit animation, we
2926 // need to see about starting one.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002927 if (!win.mExiting || win.mSurfacePendingDestroy) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002928 // Try starting an animation; if there isn't one, we
2929 // can destroy the surface right away.
2930 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2931 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2932 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2933 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002934 if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002935 applyAnimationLocked(win, transit, false)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002936 focusMayChange = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002937 win.mExiting = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002938 } else if (win.isAnimating()) {
2939 // Currently in a hide animation... turn this into
2940 // an exit.
2941 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002942 } else if (win == mWallpaperTarget) {
2943 // If the wallpaper is currently behind this
2944 // window, we need to change both of them inside
2945 // of a transaction to avoid artifacts.
2946 win.mExiting = true;
2947 win.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002948 } else {
2949 if (mInputMethodWindow == win) {
2950 mInputMethodWindow = null;
2951 }
2952 win.destroySurfaceLocked();
2953 }
2954 }
2955 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002956
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002957 if (win.mSurface == null || (win.getAttrs().flags
2958 & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
2959 || win.mSurfacePendingDestroy) {
2960 // We are being called from a local process, which
2961 // means outSurface holds its current surface. Ensure the
2962 // surface object is cleared, but we don't want it actually
2963 // destroyed at this point.
2964 win.mSurfacePendingDestroy = false;
2965 outSurface.release();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002966 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002967 } else if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002968 if (DEBUG_VISIBILITY) Slog.i(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002969 "Keeping surface, will report destroy: " + win);
2970 win.mReportDestroySurface = true;
2971 outSurface.copyFrom(win.mSurface);
2972 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002973 }
2974
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002975 if (focusMayChange) {
2976 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
Jeff Brown3a22cd92011-01-21 13:59:04 -08002977 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2978 false /*updateInputWindows*/)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002979 imMayMove = false;
2980 }
2981 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2982 }
Romain Guy06882f82009-06-10 13:36:04 -07002983
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002984 // updateFocusedWindowLocked() already assigned layers so we only need to
2985 // reassign them at this point if the IM window state gets shuffled
2986 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002987
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002988 if (imMayMove) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002989 if (moveInputMethodWindowsIfNeededLocked(false) || displayed) {
2990 // Little hack here -- we -should- be able to rely on the
2991 // function to return true if the IME has moved and needs
2992 // its layer recomputed. However, if the IME was hidden
2993 // and isn't actually moved in the list, its layer may be
2994 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002995 assignLayers = true;
2996 }
2997 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002998 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002999 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003000 assignLayers = true;
3001 }
3002 }
Romain Guy06882f82009-06-10 13:36:04 -07003003
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003004 mLayoutNeeded = true;
3005 win.mGivenInsetsPending = insetsPending;
3006 if (assignLayers) {
3007 assignLayersLocked();
3008 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003009 configChanged = updateOrientationFromAppTokensLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003010 performLayoutAndPlaceSurfacesLocked();
Dianne Hackborn284ac932009-08-28 10:34:25 -07003011 if (displayed && win.mIsWallpaper) {
3012 updateWallpaperOffsetLocked(win, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07003013 mDisplay.getHeight(), false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07003014 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003015 if (win.mAppToken != null) {
3016 win.mAppToken.updateReportedVisibilityLocked();
3017 }
3018 outFrame.set(win.mFrame);
3019 outContentInsets.set(win.mContentInsets);
3020 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003021 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003022 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07003023 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003024 + ", requestedHeight=" + requestedHeight
3025 + ", viewVisibility=" + viewVisibility
3026 + "\nRelayout returning frame=" + outFrame
3027 + ", surface=" + outSurface);
3028
Joe Onorato8a9b2202010-02-26 18:56:32 -08003029 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003030 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
3031
3032 inTouchMode = mInTouchMode;
Jeff Browne33348b2010-07-15 23:54:05 -07003033
Jeff Brown2e44b072011-01-24 15:21:56 -08003034 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003035 }
3036
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003037 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003038 sendNewConfiguration();
3039 }
Romain Guy06882f82009-06-10 13:36:04 -07003040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003041 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07003042
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003043 return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
3044 | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
3045 }
3046
3047 public void finishDrawingWindow(Session session, IWindow client) {
3048 final long origId = Binder.clearCallingIdentity();
3049 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003050 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003051 if (win != null && win.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07003052 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
3053 adjustWallpaperWindowsLocked();
3054 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003055 mLayoutNeeded = true;
3056 performLayoutAndPlaceSurfacesLocked();
3057 }
3058 }
3059 Binder.restoreCallingIdentity(origId);
3060 }
3061
3062 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Dianne Hackborn08121bc2011-01-17 17:54:31 -08003063 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: layout params pkg="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003064 + (lp != null ? lp.packageName : null)
3065 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
3066 if (lp != null && lp.windowAnimations != 0) {
3067 // If this is a system resource, don't try to load it from the
3068 // application resources. It is nice to avoid loading application
3069 // resources if we can.
3070 String packageName = lp.packageName != null ? lp.packageName : "android";
3071 int resId = lp.windowAnimations;
3072 if ((resId&0xFF000000) == 0x01000000) {
3073 packageName = "android";
3074 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003075 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003076 + packageName);
3077 return AttributeCache.instance().get(packageName, resId,
3078 com.android.internal.R.styleable.WindowAnimation);
3079 }
3080 return null;
3081 }
Romain Guy06882f82009-06-10 13:36:04 -07003082
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003083 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Dianne Hackborn08121bc2011-01-17 17:54:31 -08003084 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003085 + packageName + " resId=0x" + Integer.toHexString(resId));
3086 if (packageName != null) {
3087 if ((resId&0xFF000000) == 0x01000000) {
3088 packageName = "android";
3089 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003090 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003091 + packageName);
3092 return AttributeCache.instance().get(packageName, resId,
3093 com.android.internal.R.styleable.WindowAnimation);
3094 }
3095 return null;
3096 }
3097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003098 private void applyEnterAnimationLocked(WindowState win) {
3099 int transit = WindowManagerPolicy.TRANSIT_SHOW;
3100 if (win.mEnterAnimationPending) {
3101 win.mEnterAnimationPending = false;
3102 transit = WindowManagerPolicy.TRANSIT_ENTER;
3103 }
3104
3105 applyAnimationLocked(win, transit, true);
3106 }
3107
3108 private boolean applyAnimationLocked(WindowState win,
3109 int transit, boolean isEntrance) {
3110 if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
3111 // If we are trying to apply an animation, but already running
3112 // an animation of the same type, then just leave that one alone.
3113 return true;
3114 }
Romain Guy06882f82009-06-10 13:36:04 -07003115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003116 // Only apply an animation if the display isn't frozen. If it is
3117 // frozen, there is no reason to animate and it can cause strange
3118 // artifacts when we unfreeze the display if some different animation
3119 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003120 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003121 int anim = mPolicy.selectAnimationLw(win, transit);
3122 int attr = -1;
3123 Animation a = null;
3124 if (anim != 0) {
3125 a = AnimationUtils.loadAnimation(mContext, anim);
3126 } else {
3127 switch (transit) {
3128 case WindowManagerPolicy.TRANSIT_ENTER:
3129 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
3130 break;
3131 case WindowManagerPolicy.TRANSIT_EXIT:
3132 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
3133 break;
3134 case WindowManagerPolicy.TRANSIT_SHOW:
3135 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
3136 break;
3137 case WindowManagerPolicy.TRANSIT_HIDE:
3138 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
3139 break;
3140 }
3141 if (attr >= 0) {
3142 a = loadAnimation(win.mAttrs, attr);
3143 }
3144 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003145 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: win=" + win
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003146 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
3147 + " mAnimation=" + win.mAnimation
3148 + " isEntrance=" + isEntrance);
3149 if (a != null) {
3150 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003151 RuntimeException e = null;
3152 if (!HIDE_STACK_CRAWLS) {
3153 e = new RuntimeException();
3154 e.fillInStackTrace();
3155 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003156 Slog.v(TAG, "Loaded animation " + a + " for " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003157 }
3158 win.setAnimation(a);
3159 win.mAnimationIsEntrance = isEntrance;
3160 }
3161 } else {
3162 win.clearAnimation();
3163 }
3164
3165 return win.mAnimation != null;
3166 }
3167
3168 private Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
3169 int anim = 0;
3170 Context context = mContext;
3171 if (animAttr >= 0) {
3172 AttributeCache.Entry ent = getCachedAnimations(lp);
3173 if (ent != null) {
3174 context = ent.context;
3175 anim = ent.array.getResourceId(animAttr, 0);
3176 }
3177 }
3178 if (anim != 0) {
3179 return AnimationUtils.loadAnimation(context, anim);
3180 }
3181 return null;
3182 }
Romain Guy06882f82009-06-10 13:36:04 -07003183
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003184 private Animation loadAnimation(String packageName, int resId) {
3185 int anim = 0;
3186 Context context = mContext;
3187 if (resId >= 0) {
3188 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
3189 if (ent != null) {
3190 context = ent.context;
3191 anim = resId;
3192 }
3193 }
3194 if (anim != 0) {
3195 return AnimationUtils.loadAnimation(context, anim);
3196 }
3197 return null;
3198 }
3199
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003200 private boolean applyAnimationLocked(AppWindowToken wtoken,
3201 WindowManager.LayoutParams lp, int transit, boolean enter) {
3202 // Only apply an animation if the display isn't frozen. If it is
3203 // frozen, there is no reason to animate and it can cause strange
3204 // artifacts when we unfreeze the display if some different animation
3205 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003206 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003207 Animation a;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07003208 if (lp != null && (lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003209 a = new FadeInOutAnimation(enter);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003210 if (DEBUG_ANIM) Slog.v(TAG,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003211 "applying FadeInOutAnimation for a window in compatibility mode");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003212 } else if (mNextAppTransitionPackage != null) {
3213 a = loadAnimation(mNextAppTransitionPackage, enter ?
3214 mNextAppTransitionEnter : mNextAppTransitionExit);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003215 } else {
3216 int animAttr = 0;
3217 switch (transit) {
3218 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3219 animAttr = enter
3220 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
3221 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
3222 break;
3223 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3224 animAttr = enter
3225 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
3226 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
3227 break;
3228 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
3229 animAttr = enter
3230 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
3231 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
3232 break;
3233 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
3234 animAttr = enter
3235 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
3236 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
3237 break;
3238 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
3239 animAttr = enter
3240 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
3241 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
3242 break;
3243 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
3244 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07003245 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003246 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
3247 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003248 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003249 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003250 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
3251 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003252 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003253 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003254 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003255 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
3256 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
3257 break;
3258 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
3259 animAttr = enter
3260 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
3261 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
3262 break;
3263 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
3264 animAttr = enter
3265 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
3266 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003267 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003268 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003269 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003270 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003271 + " anim=" + a
3272 + " animAttr=0x" + Integer.toHexString(animAttr)
3273 + " transit=" + transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003274 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003275 if (a != null) {
3276 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003277 RuntimeException e = null;
3278 if (!HIDE_STACK_CRAWLS) {
3279 e = new RuntimeException();
3280 e.fillInStackTrace();
3281 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003282 Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003283 }
3284 wtoken.setAnimation(a);
3285 }
3286 } else {
3287 wtoken.clearAnimation();
3288 }
3289
3290 return wtoken.animation != null;
3291 }
3292
3293 // -------------------------------------------------------------
3294 // Application Window Tokens
3295 // -------------------------------------------------------------
3296
3297 public void validateAppTokens(List tokens) {
3298 int v = tokens.size()-1;
3299 int m = mAppTokens.size()-1;
3300 while (v >= 0 && m >= 0) {
3301 AppWindowToken wtoken = mAppTokens.get(m);
3302 if (wtoken.removed) {
3303 m--;
3304 continue;
3305 }
3306 if (tokens.get(v) != wtoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003307 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003308 + " @ " + v + ", internal is " + wtoken.token + " @ " + m);
3309 }
3310 v--;
3311 m--;
3312 }
3313 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003314 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003315 v--;
3316 }
3317 while (m >= 0) {
3318 AppWindowToken wtoken = mAppTokens.get(m);
3319 if (!wtoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003320 Slog.w(TAG, "Invalid internal token: " + wtoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003321 }
3322 m--;
3323 }
3324 }
3325
3326 boolean checkCallingPermission(String permission, String func) {
3327 // Quick check: if the calling permission is me, it's all okay.
3328 if (Binder.getCallingPid() == Process.myPid()) {
3329 return true;
3330 }
Romain Guy06882f82009-06-10 13:36:04 -07003331
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003332 if (mContext.checkCallingPermission(permission)
3333 == PackageManager.PERMISSION_GRANTED) {
3334 return true;
3335 }
3336 String msg = "Permission Denial: " + func + " from pid="
3337 + Binder.getCallingPid()
3338 + ", uid=" + Binder.getCallingUid()
3339 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003340 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003341 return false;
3342 }
Romain Guy06882f82009-06-10 13:36:04 -07003343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003344 AppWindowToken findAppWindowToken(IBinder token) {
3345 WindowToken wtoken = mTokenMap.get(token);
3346 if (wtoken == null) {
3347 return null;
3348 }
3349 return wtoken.appWindowToken;
3350 }
Romain Guy06882f82009-06-10 13:36:04 -07003351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003352 public void addWindowToken(IBinder token, int type) {
3353 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3354 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003355 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003356 }
Romain Guy06882f82009-06-10 13:36:04 -07003357
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003358 synchronized(mWindowMap) {
3359 WindowToken wtoken = mTokenMap.get(token);
3360 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003361 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003362 return;
3363 }
3364 wtoken = new WindowToken(token, type, true);
3365 mTokenMap.put(token, wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003366 if (type == TYPE_WALLPAPER) {
3367 mWallpaperTokens.add(wtoken);
3368 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003369 }
3370 }
Romain Guy06882f82009-06-10 13:36:04 -07003371
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003372 public void removeWindowToken(IBinder token) {
3373 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3374 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003375 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003376 }
3377
3378 final long origId = Binder.clearCallingIdentity();
3379 synchronized(mWindowMap) {
3380 WindowToken wtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003381 if (wtoken != null) {
3382 boolean delayed = false;
3383 if (!wtoken.hidden) {
3384 wtoken.hidden = true;
Romain Guy06882f82009-06-10 13:36:04 -07003385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003386 final int N = wtoken.windows.size();
3387 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003389 for (int i=0; i<N; i++) {
3390 WindowState win = wtoken.windows.get(i);
3391
3392 if (win.isAnimating()) {
3393 delayed = true;
3394 }
Romain Guy06882f82009-06-10 13:36:04 -07003395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003396 if (win.isVisibleNow()) {
3397 applyAnimationLocked(win,
3398 WindowManagerPolicy.TRANSIT_EXIT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003399 changed = true;
3400 }
3401 }
3402
3403 if (changed) {
3404 mLayoutNeeded = true;
3405 performLayoutAndPlaceSurfacesLocked();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003406 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
3407 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003408 }
Romain Guy06882f82009-06-10 13:36:04 -07003409
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003410 if (delayed) {
3411 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003412 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3413 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003414 }
3415 }
Romain Guy06882f82009-06-10 13:36:04 -07003416
Jeff Brown2e44b072011-01-24 15:21:56 -08003417 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003418 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003419 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003420 }
3421 }
3422 Binder.restoreCallingIdentity(origId);
3423 }
3424
3425 public void addAppToken(int addPos, IApplicationToken token,
3426 int groupId, int requestedOrientation, boolean fullscreen) {
3427 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3428 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003429 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003430 }
Jeff Brown349703e2010-06-22 01:27:15 -07003431
3432 // Get the dispatching timeout here while we are not holding any locks so that it
3433 // can be cached by the AppWindowToken. The timeout value is used later by the
3434 // input dispatcher in code that does hold locks. If we did not cache the value
3435 // here we would run the chance of introducing a deadlock between the window manager
3436 // (which holds locks while updating the input dispatcher state) and the activity manager
3437 // (which holds locks while querying the application token).
3438 long inputDispatchingTimeoutNanos;
3439 try {
3440 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3441 } catch (RemoteException ex) {
3442 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3443 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3444 }
Romain Guy06882f82009-06-10 13:36:04 -07003445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003446 synchronized(mWindowMap) {
3447 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3448 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003449 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003450 return;
3451 }
3452 wtoken = new AppWindowToken(token);
Jeff Brown349703e2010-06-22 01:27:15 -07003453 wtoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003454 wtoken.groupId = groupId;
3455 wtoken.appFullscreen = fullscreen;
3456 wtoken.requestedOrientation = requestedOrientation;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003457 if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003458 mAppTokens.add(addPos, wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003459 mTokenMap.put(token.asBinder(), wtoken);
Romain Guy06882f82009-06-10 13:36:04 -07003460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003461 // Application tokens start out hidden.
3462 wtoken.hidden = true;
3463 wtoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003464
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003465 //dump();
3466 }
3467 }
Romain Guy06882f82009-06-10 13:36:04 -07003468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003469 public void setAppGroupId(IBinder token, int groupId) {
3470 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3471 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003472 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003473 }
3474
3475 synchronized(mWindowMap) {
3476 AppWindowToken wtoken = findAppWindowToken(token);
3477 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003478 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003479 return;
3480 }
3481 wtoken.groupId = groupId;
3482 }
3483 }
Romain Guy06882f82009-06-10 13:36:04 -07003484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003485 public int getOrientationFromWindowsLocked() {
3486 int pos = mWindows.size() - 1;
3487 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07003488 WindowState wtoken = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003489 pos--;
3490 if (wtoken.mAppToken != null) {
3491 // We hit an application window. so the orientation will be determined by the
3492 // app window. No point in continuing further.
3493 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3494 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003495 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003496 continue;
3497 }
3498 int req = wtoken.mAttrs.screenOrientation;
3499 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3500 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3501 continue;
3502 } else {
3503 return req;
3504 }
3505 }
3506 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3507 }
Romain Guy06882f82009-06-10 13:36:04 -07003508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003509 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003510 int pos = mAppTokens.size() - 1;
3511 int curGroup = 0;
3512 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3513 boolean findingBehind = false;
3514 boolean haveGroup = false;
3515 boolean lastFullscreen = false;
3516 while (pos >= 0) {
3517 AppWindowToken wtoken = mAppTokens.get(pos);
3518 pos--;
3519 // if we're about to tear down this window and not seek for
3520 // the behind activity, don't use it for orientation
3521 if (!findingBehind
3522 && (!wtoken.hidden && wtoken.hiddenRequested)) {
3523 continue;
3524 }
3525
3526 if (!haveGroup) {
3527 // We ignore any hidden applications on the top.
3528 if (wtoken.hiddenRequested || wtoken.willBeHidden) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003529 continue;
3530 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003531 haveGroup = true;
3532 curGroup = wtoken.groupId;
3533 lastOrientation = wtoken.requestedOrientation;
3534 } else if (curGroup != wtoken.groupId) {
3535 // If we have hit a new application group, and the bottom
3536 // of the previous group didn't explicitly say to use
3537 // the orientation behind it, and the last app was
3538 // full screen, then we'll stick with the
3539 // user's orientation.
3540 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3541 && lastFullscreen) {
3542 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003543 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003544 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003545 int or = wtoken.requestedOrientation;
3546 // If this application is fullscreen, and didn't explicitly say
3547 // to use the orientation behind it, then just take whatever
3548 // orientation it has and ignores whatever is under it.
3549 lastFullscreen = wtoken.appFullscreen;
3550 if (lastFullscreen
3551 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3552 return or;
3553 }
3554 // If this application has requested an explicit orientation,
3555 // then use it.
Dianne Hackborne5439f22010-10-02 16:53:50 -07003556 if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
3557 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003558 return or;
3559 }
3560 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3561 }
3562 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003563 }
Romain Guy06882f82009-06-10 13:36:04 -07003564
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003565 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003566 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003567 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3568 "updateOrientationFromAppTokens()")) {
3569 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3570 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003571
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003572 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003573 long ident = Binder.clearCallingIdentity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003574
3575 synchronized(mWindowMap) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003576 if (updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003577 if (freezeThisOneIfNeeded != null) {
3578 AppWindowToken wtoken = findAppWindowToken(
3579 freezeThisOneIfNeeded);
3580 if (wtoken != null) {
3581 startAppFreezingScreenLocked(wtoken,
3582 ActivityInfo.CONFIG_ORIENTATION);
3583 }
3584 }
3585 config = computeNewConfigurationLocked();
3586
3587 } else if (currentConfig != null) {
3588 // No obvious action we need to take, but if our current
Casey Burkhardt0920ba52010-08-03 12:04:19 -07003589 // state mismatches the activity manager's, update it,
3590 // disregarding font scale, which should remain set to
3591 // the value of the previous configuration.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003592 mTempConfiguration.setToDefaults();
Casey Burkhardt0920ba52010-08-03 12:04:19 -07003593 mTempConfiguration.fontScale = currentConfig.fontScale;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003594 if (computeNewConfigurationLocked(mTempConfiguration)) {
3595 if (currentConfig.diff(mTempConfiguration) != 0) {
3596 mWaitingForConfig = true;
3597 mLayoutNeeded = true;
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003598 startFreezingDisplayLocked(false);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003599 config = new Configuration(mTempConfiguration);
3600 }
3601 }
3602 }
3603 }
3604
Dianne Hackborncfaef692009-06-15 14:24:44 -07003605 Binder.restoreCallingIdentity(ident);
3606 return config;
3607 }
3608
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003609 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003610 * Determine the new desired orientation of the display, returning
3611 * a non-null new Configuration if it has changed from the current
3612 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3613 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3614 * SCREEN. This will typically be done for you if you call
3615 * sendNewConfiguration().
3616 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003617 * The orientation is computed from non-application windows first. If none of
3618 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003619 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003620 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3621 * android.os.IBinder)
3622 */
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003623 boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
3624 if (mDisplayFrozen || mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
Christopher Tateb696aee2010-04-02 19:08:30 -07003625 // If the display is frozen, some activities may be in the middle
3626 // of restarting, and thus have removed their old window. If the
3627 // window has the flag to hide the lock screen, then the lock screen
3628 // can re-appear and inflict its own orientation on us. Keep the
3629 // orientation stable until this all settles down.
3630 return false;
3631 }
3632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003633 boolean changed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003634 long ident = Binder.clearCallingIdentity();
3635 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003636 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003637
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003638 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003639 mForcedAppOrientation = req;
3640 //send a message to Policy indicating orientation change to take
3641 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003642 mPolicy.setCurrentOrientationLw(req);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003643 if (setRotationUncheckedLocked(WindowManagerPolicy.USE_LAST_ROTATION,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003644 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE,
3645 inTransaction)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003646 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003647 }
3648 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003649
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003650 return changed;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003651 } finally {
3652 Binder.restoreCallingIdentity(ident);
3653 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003654 }
Romain Guy06882f82009-06-10 13:36:04 -07003655
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003656 int computeForcedAppOrientationLocked() {
3657 int req = getOrientationFromWindowsLocked();
3658 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3659 req = getOrientationFromAppTokensLocked();
3660 }
3661 return req;
3662 }
Romain Guy06882f82009-06-10 13:36:04 -07003663
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003664 public void setNewConfiguration(Configuration config) {
3665 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3666 "setNewConfiguration()")) {
3667 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3668 }
3669
3670 synchronized(mWindowMap) {
3671 mCurConfiguration = new Configuration(config);
3672 mWaitingForConfig = false;
3673 performLayoutAndPlaceSurfacesLocked();
3674 }
3675 }
3676
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003677 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3678 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3679 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003680 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003681 }
Romain Guy06882f82009-06-10 13:36:04 -07003682
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003683 synchronized(mWindowMap) {
3684 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3685 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003686 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003687 return;
3688 }
Romain Guy06882f82009-06-10 13:36:04 -07003689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003690 wtoken.requestedOrientation = requestedOrientation;
3691 }
3692 }
Romain Guy06882f82009-06-10 13:36:04 -07003693
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003694 public int getAppOrientation(IApplicationToken token) {
3695 synchronized(mWindowMap) {
3696 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3697 if (wtoken == null) {
3698 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3699 }
Romain Guy06882f82009-06-10 13:36:04 -07003700
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003701 return wtoken.requestedOrientation;
3702 }
3703 }
Romain Guy06882f82009-06-10 13:36:04 -07003704
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003705 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3706 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3707 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003708 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003709 }
3710
3711 synchronized(mWindowMap) {
3712 boolean changed = false;
3713 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003714 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003715 changed = mFocusedApp != null;
3716 mFocusedApp = null;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003717 if (changed) {
3718 mInputMonitor.setFocusedAppLw(null);
Jeff Brown349703e2010-06-22 01:27:15 -07003719 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003720 } else {
3721 AppWindowToken newFocus = findAppWindowToken(token);
3722 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003723 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003724 return;
3725 }
3726 changed = mFocusedApp != newFocus;
3727 mFocusedApp = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003728 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003729 if (changed) {
3730 mInputMonitor.setFocusedAppLw(newFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07003731 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003732 }
3733
3734 if (moveFocusNow && changed) {
3735 final long origId = Binder.clearCallingIdentity();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003736 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003737 Binder.restoreCallingIdentity(origId);
3738 }
3739 }
3740 }
3741
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003742 public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003743 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3744 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003745 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003746 }
Romain Guy06882f82009-06-10 13:36:04 -07003747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003748 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003749 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003750 TAG, "Prepare app transition: transit=" + transit
3751 + " mNextAppTransition=" + mNextAppTransition);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003752 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003753 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
3754 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003755 mNextAppTransition = transit;
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003756 } else if (!alwaysKeepCurrent) {
3757 if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
3758 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
3759 // Opening a new task always supersedes a close for the anim.
3760 mNextAppTransition = transit;
3761 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
3762 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
3763 // Opening a new activity always supersedes a close for the anim.
3764 mNextAppTransition = transit;
3765 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003766 }
3767 mAppTransitionReady = false;
3768 mAppTransitionTimeout = false;
3769 mStartingIconInTransition = false;
3770 mSkipAppTransitionAnimation = false;
3771 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
3772 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
3773 5000);
3774 }
3775 }
3776 }
3777
3778 public int getPendingAppTransition() {
3779 return mNextAppTransition;
3780 }
Romain Guy06882f82009-06-10 13:36:04 -07003781
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003782 public void overridePendingAppTransition(String packageName,
3783 int enterAnim, int exitAnim) {
Dianne Hackborn8b571a82009-09-25 16:09:43 -07003784 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003785 mNextAppTransitionPackage = packageName;
3786 mNextAppTransitionEnter = enterAnim;
3787 mNextAppTransitionExit = exitAnim;
3788 }
3789 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003790
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003791 public void executeAppTransition() {
3792 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3793 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003794 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003795 }
Romain Guy06882f82009-06-10 13:36:04 -07003796
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003797 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003798 if (DEBUG_APP_TRANSITIONS) {
3799 RuntimeException e = new RuntimeException("here");
3800 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003801 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003802 + mNextAppTransition, e);
3803 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003804 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003805 mAppTransitionReady = true;
3806 final long origId = Binder.clearCallingIdentity();
3807 performLayoutAndPlaceSurfacesLocked();
3808 Binder.restoreCallingIdentity(origId);
3809 }
3810 }
3811 }
3812
3813 public void setAppStartingWindow(IBinder token, String pkg,
3814 int theme, CharSequence nonLocalizedLabel, int labelRes, int icon,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003815 int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003816 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3817 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003818 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003819 }
3820
3821 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003822 if (DEBUG_STARTING_WINDOW) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003823 TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
3824 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003825
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003826 AppWindowToken wtoken = findAppWindowToken(token);
3827 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003828 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003829 return;
3830 }
3831
3832 // If the display is frozen, we won't do anything until the
3833 // actual window is displayed so there is no reason to put in
3834 // the starting window.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003835 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003836 return;
3837 }
Romain Guy06882f82009-06-10 13:36:04 -07003838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003839 if (wtoken.startingData != null) {
3840 return;
3841 }
Romain Guy06882f82009-06-10 13:36:04 -07003842
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003843 if (transferFrom != null) {
3844 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3845 if (ttoken != null) {
3846 WindowState startingWindow = ttoken.startingWindow;
3847 if (startingWindow != null) {
3848 if (mStartingIconInTransition) {
3849 // In this case, the starting icon has already
3850 // been displayed, so start letting windows get
3851 // shown immediately without any more transitions.
3852 mSkipAppTransitionAnimation = true;
3853 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003854 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003855 "Moving existing starting from " + ttoken
3856 + " to " + wtoken);
3857 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003858
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003859 // Transfer the starting window over to the new
3860 // token.
3861 wtoken.startingData = ttoken.startingData;
3862 wtoken.startingView = ttoken.startingView;
3863 wtoken.startingWindow = startingWindow;
3864 ttoken.startingData = null;
3865 ttoken.startingView = null;
3866 ttoken.startingWindow = null;
3867 ttoken.startingMoved = true;
3868 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003869 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003870 startingWindow.mAppToken = wtoken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003871 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003872 "Removing starting window: " + startingWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003873 mWindows.remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07003874 mWindowsChanged = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003875 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing starting " + startingWindow
3876 + " from " + ttoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003877 ttoken.windows.remove(startingWindow);
3878 ttoken.allAppWindows.remove(startingWindow);
3879 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003880
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003881 // Propagate other interesting state between the
3882 // tokens. If the old token is displayed, we should
3883 // immediately force the new one to be displayed. If
3884 // it is animating, we need to move that animation to
3885 // the new one.
3886 if (ttoken.allDrawn) {
3887 wtoken.allDrawn = true;
3888 }
3889 if (ttoken.firstWindowDrawn) {
3890 wtoken.firstWindowDrawn = true;
3891 }
3892 if (!ttoken.hidden) {
3893 wtoken.hidden = false;
3894 wtoken.hiddenRequested = false;
3895 wtoken.willBeHidden = false;
3896 }
3897 if (wtoken.clientHidden != ttoken.clientHidden) {
3898 wtoken.clientHidden = ttoken.clientHidden;
3899 wtoken.sendAppVisibilityToClients();
3900 }
3901 if (ttoken.animation != null) {
3902 wtoken.animation = ttoken.animation;
3903 wtoken.animating = ttoken.animating;
3904 wtoken.animLayerAdjustment = ttoken.animLayerAdjustment;
3905 ttoken.animation = null;
3906 ttoken.animLayerAdjustment = 0;
3907 wtoken.updateLayers();
3908 ttoken.updateLayers();
3909 }
Romain Guy06882f82009-06-10 13:36:04 -07003910
Jeff Brown3a22cd92011-01-21 13:59:04 -08003911 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
3912 true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003913 mLayoutNeeded = true;
3914 performLayoutAndPlaceSurfacesLocked();
3915 Binder.restoreCallingIdentity(origId);
3916 return;
3917 } else if (ttoken.startingData != null) {
3918 // The previous app was getting ready to show a
3919 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08003920 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003921 "Moving pending starting from " + ttoken
3922 + " to " + wtoken);
3923 wtoken.startingData = ttoken.startingData;
3924 ttoken.startingData = null;
3925 ttoken.startingMoved = true;
3926 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3927 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3928 // want to process the message ASAP, before any other queued
3929 // messages.
3930 mH.sendMessageAtFrontOfQueue(m);
3931 return;
3932 }
3933 }
3934 }
3935
3936 // There is no existing starting window, and the caller doesn't
3937 // want us to create one, so that's it!
3938 if (!createIfNeeded) {
3939 return;
3940 }
Romain Guy06882f82009-06-10 13:36:04 -07003941
Dianne Hackborn284ac932009-08-28 10:34:25 -07003942 // If this is a translucent or wallpaper window, then don't
3943 // show a starting window -- the current effect (a full-screen
3944 // opaque starting window that fades away to the real contents
3945 // when it is ready) does not work for this.
3946 if (theme != 0) {
3947 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
3948 com.android.internal.R.styleable.Window);
3949 if (ent.array.getBoolean(
3950 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
3951 return;
3952 }
3953 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07003954 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
3955 return;
3956 }
3957 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07003958 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
3959 return;
3960 }
3961 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003962
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003963 mStartingIconInTransition = true;
3964 wtoken.startingData = new StartingData(
3965 pkg, theme, nonLocalizedLabel,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003966 labelRes, icon, windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003967 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3968 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3969 // want to process the message ASAP, before any other queued
3970 // messages.
3971 mH.sendMessageAtFrontOfQueue(m);
3972 }
3973 }
3974
3975 public void setAppWillBeHidden(IBinder token) {
3976 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3977 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003978 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003979 }
3980
3981 AppWindowToken wtoken;
3982
3983 synchronized(mWindowMap) {
3984 wtoken = findAppWindowToken(token);
3985 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003986 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 -08003987 return;
3988 }
3989 wtoken.willBeHidden = true;
3990 }
3991 }
Romain Guy06882f82009-06-10 13:36:04 -07003992
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003993 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
3994 boolean visible, int transit, boolean performLayout) {
3995 boolean delayed = false;
3996
3997 if (wtoken.clientHidden == visible) {
3998 wtoken.clientHidden = !visible;
3999 wtoken.sendAppVisibilityToClients();
4000 }
Romain Guy06882f82009-06-10 13:36:04 -07004001
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004002 wtoken.willBeHidden = false;
4003 if (wtoken.hidden == visible) {
4004 final int N = wtoken.allAppWindows.size();
4005 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004006 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004007 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
4008 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07004009
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004010 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07004011
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004012 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004013 if (wtoken.animation == sDummyAnimation) {
4014 wtoken.animation = null;
4015 }
4016 applyAnimationLocked(wtoken, lp, transit, visible);
4017 changed = true;
4018 if (wtoken.animation != null) {
4019 delayed = runningAppAnimation = true;
4020 }
4021 }
Romain Guy06882f82009-06-10 13:36:04 -07004022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004023 for (int i=0; i<N; i++) {
4024 WindowState win = wtoken.allAppWindows.get(i);
4025 if (win == wtoken.startingWindow) {
4026 continue;
4027 }
4028
4029 if (win.isAnimating()) {
4030 delayed = true;
4031 }
Romain Guy06882f82009-06-10 13:36:04 -07004032
Joe Onorato8a9b2202010-02-26 18:56:32 -08004033 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004034 //win.dump(" ");
4035 if (visible) {
4036 if (!win.isVisibleNow()) {
4037 if (!runningAppAnimation) {
4038 applyAnimationLocked(win,
4039 WindowManagerPolicy.TRANSIT_ENTER, true);
4040 }
4041 changed = true;
4042 }
4043 } else if (win.isVisibleNow()) {
4044 if (!runningAppAnimation) {
4045 applyAnimationLocked(win,
4046 WindowManagerPolicy.TRANSIT_EXIT, false);
4047 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004048 changed = true;
4049 }
4050 }
4051
4052 wtoken.hidden = wtoken.hiddenRequested = !visible;
4053 if (!visible) {
4054 unsetAppFreezingScreenLocked(wtoken, true, true);
4055 } else {
4056 // If we are being set visible, and the starting window is
4057 // not yet displayed, then make sure it doesn't get displayed.
4058 WindowState swin = wtoken.startingWindow;
4059 if (swin != null && (swin.mDrawPending
4060 || swin.mCommitDrawPending)) {
4061 swin.mPolicyVisibility = false;
4062 swin.mPolicyVisibilityAfterAnim = false;
4063 }
4064 }
Romain Guy06882f82009-06-10 13:36:04 -07004065
Joe Onorato8a9b2202010-02-26 18:56:32 -08004066 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004067 + ": hidden=" + wtoken.hidden + " hiddenRequested="
4068 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07004069
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004070 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004071 mLayoutNeeded = true;
Jeff Brown3a22cd92011-01-21 13:59:04 -08004072 mInputMonitor.setUpdateInputWindowsNeededLw();
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004073 if (performLayout) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08004074 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4075 false /*updateInputWindows*/);
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004076 performLayoutAndPlaceSurfacesLocked();
4077 }
Jeff Brown2e44b072011-01-24 15:21:56 -08004078 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004079 }
4080 }
4081
4082 if (wtoken.animation != null) {
4083 delayed = true;
4084 }
Romain Guy06882f82009-06-10 13:36:04 -07004085
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004086 return delayed;
4087 }
4088
4089 public void setAppVisibility(IBinder token, boolean visible) {
4090 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4091 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004092 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004093 }
4094
4095 AppWindowToken wtoken;
4096
4097 synchronized(mWindowMap) {
4098 wtoken = findAppWindowToken(token);
4099 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004100 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004101 return;
4102 }
4103
4104 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004105 RuntimeException e = null;
4106 if (!HIDE_STACK_CRAWLS) {
4107 e = new RuntimeException();
4108 e.fillInStackTrace();
4109 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004110 Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004111 + "): mNextAppTransition=" + mNextAppTransition
4112 + " hidden=" + wtoken.hidden
4113 + " hiddenRequested=" + wtoken.hiddenRequested, e);
4114 }
Romain Guy06882f82009-06-10 13:36:04 -07004115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004116 // If we are preparing an app transition, then delay changing
4117 // the visibility of this token until we execute that transition.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08004118 if (!mDisplayFrozen && mPolicy.isScreenOn()
4119 && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004120 // Already in requested state, don't do anything more.
4121 if (wtoken.hiddenRequested != visible) {
4122 return;
4123 }
4124 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07004125
Joe Onorato8a9b2202010-02-26 18:56:32 -08004126 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004127 TAG, "Setting dummy animation on: " + wtoken);
4128 wtoken.setDummyAnimation();
4129 mOpeningApps.remove(wtoken);
4130 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004131 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004132 wtoken.inPendingTransaction = true;
4133 if (visible) {
4134 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004135 wtoken.startingDisplayed = false;
4136 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004137
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004138 // If the token is currently hidden (should be the
4139 // common case), then we need to set up to wait for
4140 // its windows to be ready.
4141 if (wtoken.hidden) {
4142 wtoken.allDrawn = false;
4143 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004144
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004145 if (wtoken.clientHidden) {
4146 // In the case where we are making an app visible
4147 // but holding off for a transition, we still need
4148 // to tell the client to make its windows visible so
4149 // they get drawn. Otherwise, we will wait on
4150 // performing the transition until all windows have
4151 // been drawn, they never will be, and we are sad.
4152 wtoken.clientHidden = false;
4153 wtoken.sendAppVisibilityToClients();
4154 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004155 }
4156 } else {
4157 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004158
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004159 // If the token is currently visible (should be the
4160 // common case), then set up to wait for it to be hidden.
4161 if (!wtoken.hidden) {
4162 wtoken.waitingToHide = true;
4163 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004164 }
4165 return;
4166 }
Romain Guy06882f82009-06-10 13:36:04 -07004167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004168 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004169 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004170 wtoken.updateReportedVisibilityLocked();
4171 Binder.restoreCallingIdentity(origId);
4172 }
4173 }
4174
4175 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
4176 boolean unfreezeSurfaceNow, boolean force) {
4177 if (wtoken.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004178 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004179 + " force=" + force);
4180 final int N = wtoken.allAppWindows.size();
4181 boolean unfrozeWindows = false;
4182 for (int i=0; i<N; i++) {
4183 WindowState w = wtoken.allAppWindows.get(i);
4184 if (w.mAppFreezing) {
4185 w.mAppFreezing = false;
4186 if (w.mSurface != null && !w.mOrientationChanging) {
4187 w.mOrientationChanging = true;
4188 }
4189 unfrozeWindows = true;
4190 }
4191 }
4192 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004193 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004194 wtoken.freezingScreen = false;
4195 mAppsFreezingScreen--;
4196 }
4197 if (unfreezeSurfaceNow) {
4198 if (unfrozeWindows) {
4199 mLayoutNeeded = true;
4200 performLayoutAndPlaceSurfacesLocked();
4201 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004202 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004203 }
4204 }
4205 }
Romain Guy06882f82009-06-10 13:36:04 -07004206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004207 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
4208 int configChanges) {
4209 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004210 RuntimeException e = null;
4211 if (!HIDE_STACK_CRAWLS) {
4212 e = new RuntimeException();
4213 e.fillInStackTrace();
4214 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004215 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004216 + ": hidden=" + wtoken.hidden + " freezing="
4217 + wtoken.freezingScreen, e);
4218 }
4219 if (!wtoken.hiddenRequested) {
4220 if (!wtoken.freezingScreen) {
4221 wtoken.freezingScreen = true;
4222 mAppsFreezingScreen++;
4223 if (mAppsFreezingScreen == 1) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08004224 startFreezingDisplayLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004225 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
4226 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
4227 5000);
4228 }
4229 }
4230 final int N = wtoken.allAppWindows.size();
4231 for (int i=0; i<N; i++) {
4232 WindowState w = wtoken.allAppWindows.get(i);
4233 w.mAppFreezing = true;
4234 }
4235 }
4236 }
Romain Guy06882f82009-06-10 13:36:04 -07004237
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004238 public void startAppFreezingScreen(IBinder token, int configChanges) {
4239 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4240 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004241 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004242 }
4243
4244 synchronized(mWindowMap) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08004245 if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOn()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004246 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004247 return;
4248 }
Romain Guy06882f82009-06-10 13:36:04 -07004249
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004250 AppWindowToken wtoken = findAppWindowToken(token);
4251 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004252 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004253 return;
4254 }
4255 final long origId = Binder.clearCallingIdentity();
4256 startAppFreezingScreenLocked(wtoken, configChanges);
4257 Binder.restoreCallingIdentity(origId);
4258 }
4259 }
Romain Guy06882f82009-06-10 13:36:04 -07004260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004261 public void stopAppFreezingScreen(IBinder token, boolean force) {
4262 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4263 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004264 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004265 }
4266
4267 synchronized(mWindowMap) {
4268 AppWindowToken wtoken = findAppWindowToken(token);
4269 if (wtoken == null || wtoken.appToken == null) {
4270 return;
4271 }
4272 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004273 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004274 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.freezingScreen);
4275 unsetAppFreezingScreenLocked(wtoken, true, force);
4276 Binder.restoreCallingIdentity(origId);
4277 }
4278 }
Romain Guy06882f82009-06-10 13:36:04 -07004279
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004280 public void removeAppToken(IBinder token) {
4281 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4282 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004283 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004284 }
4285
4286 AppWindowToken wtoken = null;
4287 AppWindowToken startingToken = null;
4288 boolean delayed = false;
4289
4290 final long origId = Binder.clearCallingIdentity();
4291 synchronized(mWindowMap) {
4292 WindowToken basewtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004293 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004294 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004295 delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004296 wtoken.inPendingTransaction = false;
4297 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004298 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004299 if (mClosingApps.contains(wtoken)) {
4300 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004301 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004302 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004303 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004304 delayed = true;
4305 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004306 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004307 TAG, "Removing app " + wtoken + " delayed=" + delayed
4308 + " animation=" + wtoken.animation
4309 + " animating=" + wtoken.animating);
4310 if (delayed) {
4311 // set the token aside because it has an active animation to be finished
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004312 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4313 "removeAppToken make exiting: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004314 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004315 } else {
4316 // Make sure there is no animation running on this token,
4317 // so any windows associated with it will be removed as
4318 // soon as their animations are complete
4319 wtoken.animation = null;
4320 wtoken.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004321 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004322 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4323 "removeAppToken: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004324 mAppTokens.remove(wtoken);
4325 wtoken.removed = true;
4326 if (wtoken.startingData != null) {
4327 startingToken = wtoken;
4328 }
4329 unsetAppFreezingScreenLocked(wtoken, true, true);
4330 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004331 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004332 mFocusedApp = null;
Jeff Brown3a22cd92011-01-21 13:59:04 -08004333 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004334 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004335 }
4336 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004337 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004338 }
Romain Guy06882f82009-06-10 13:36:04 -07004339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004340 if (!delayed && wtoken != null) {
4341 wtoken.updateReportedVisibilityLocked();
4342 }
4343 }
4344 Binder.restoreCallingIdentity(origId);
4345
4346 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004347 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004348 + startingToken + ": app token removed");
4349 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
4350 mH.sendMessage(m);
4351 }
4352 }
4353
4354 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
4355 final int NW = token.windows.size();
4356 for (int i=0; i<NW; i++) {
4357 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004358 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004359 mWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004360 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004361 int j = win.mChildWindows.size();
4362 while (j > 0) {
4363 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004364 WindowState cwin = win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004365 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004366 "Tmp removing child window " + cwin);
4367 mWindows.remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004368 }
4369 }
4370 return NW > 0;
4371 }
4372
4373 void dumpAppTokensLocked() {
4374 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004375 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004376 }
4377 }
Romain Guy06882f82009-06-10 13:36:04 -07004378
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004379 void dumpWindowsLocked() {
4380 for (int i=mWindows.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004381 Slog.v(TAG, " #" + i + ": " + mWindows.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004382 }
4383 }
Romain Guy06882f82009-06-10 13:36:04 -07004384
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004385 private int findWindowOffsetLocked(int tokenPos) {
4386 final int NW = mWindows.size();
4387
4388 if (tokenPos >= mAppTokens.size()) {
4389 int i = NW;
4390 while (i > 0) {
4391 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07004392 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004393 if (win.getAppToken() != null) {
4394 return i+1;
4395 }
4396 }
4397 }
4398
4399 while (tokenPos > 0) {
4400 // Find the first app token below the new position that has
4401 // a window displayed.
4402 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004403 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004404 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004405 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004406 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07004407 "Skipping token -- currently sending to bottom");
4408 tokenPos--;
4409 continue;
4410 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004411 int i = wtoken.windows.size();
4412 while (i > 0) {
4413 i--;
4414 WindowState win = wtoken.windows.get(i);
4415 int j = win.mChildWindows.size();
4416 while (j > 0) {
4417 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004418 WindowState cwin = win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004419 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004420 for (int pos=NW-1; pos>=0; pos--) {
4421 if (mWindows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004422 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004423 "Found child win @" + (pos+1));
4424 return pos+1;
4425 }
4426 }
4427 }
4428 }
4429 for (int pos=NW-1; pos>=0; pos--) {
4430 if (mWindows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004431 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004432 return pos+1;
4433 }
4434 }
4435 }
4436 tokenPos--;
4437 }
4438
4439 return 0;
4440 }
4441
4442 private final int reAddWindowLocked(int index, WindowState win) {
4443 final int NCW = win.mChildWindows.size();
4444 boolean added = false;
4445 for (int j=0; j<NCW; j++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004446 WindowState cwin = win.mChildWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004447 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004448 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004449 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004450 win.mRebuilding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004451 mWindows.add(index, win);
4452 index++;
4453 added = true;
4454 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004455 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004456 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004457 cwin.mRebuilding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004458 mWindows.add(index, cwin);
4459 index++;
4460 }
4461 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004462 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004463 + index + ": " + win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004464 win.mRebuilding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004465 mWindows.add(index, win);
4466 index++;
4467 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004468 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004469 return index;
4470 }
Romain Guy06882f82009-06-10 13:36:04 -07004471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004472 private final int reAddAppWindowsLocked(int index, WindowToken token) {
4473 final int NW = token.windows.size();
4474 for (int i=0; i<NW; i++) {
4475 index = reAddWindowLocked(index, token.windows.get(i));
4476 }
4477 return index;
4478 }
4479
4480 public void moveAppToken(int index, IBinder token) {
4481 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4482 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004483 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004484 }
4485
4486 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004487 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004488 if (DEBUG_REORDER) dumpAppTokensLocked();
4489 final AppWindowToken wtoken = findAppWindowToken(token);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004490 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
4491 "Start moving token " + wtoken + " initially at "
4492 + mAppTokens.indexOf(wtoken));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004493 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004494 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004495 + token + " (" + wtoken + ")");
4496 return;
4497 }
4498 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004499 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004500 else if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "Moved " + token + " to " + index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004501 if (DEBUG_REORDER) dumpAppTokensLocked();
Romain Guy06882f82009-06-10 13:36:04 -07004502
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004503 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004504 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004505 if (DEBUG_REORDER) dumpWindowsLocked();
4506 if (tmpRemoveAppWindowsLocked(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004507 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004508 if (DEBUG_REORDER) dumpWindowsLocked();
4509 reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004510 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004511 if (DEBUG_REORDER) dumpWindowsLocked();
Jeff Brown3a22cd92011-01-21 13:59:04 -08004512 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4513 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004514 mLayoutNeeded = true;
Jeff Brown2e44b072011-01-24 15:21:56 -08004515 mInputMonitor.setUpdateInputWindowsNeededLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004516 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08004517 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004518 }
4519 Binder.restoreCallingIdentity(origId);
4520 }
4521 }
4522
4523 private void removeAppTokensLocked(List<IBinder> tokens) {
4524 // XXX This should be done more efficiently!
4525 // (take advantage of the fact that both lists should be
4526 // ordered in the same way.)
4527 int N = tokens.size();
4528 for (int i=0; i<N; i++) {
4529 IBinder token = tokens.get(i);
4530 final AppWindowToken wtoken = findAppWindowToken(token);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004531 if (DEBUG_REORDER || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4532 "Temporarily removing " + wtoken + " from " + mAppTokens.indexOf(wtoken));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004533 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004534 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004535 + token + " (" + wtoken + ")");
4536 i--;
4537 N--;
4538 }
4539 }
4540 }
4541
Dianne Hackborna8f60182009-09-01 19:01:50 -07004542 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
4543 boolean updateFocusAndLayout) {
4544 // First remove all of the windows from the list.
4545 tmpRemoveAppWindowsLocked(wtoken);
4546
4547 // Where to start adding?
4548 int pos = findWindowOffsetLocked(tokenPos);
4549
4550 // And now add them back at the correct place.
4551 pos = reAddAppWindowsLocked(pos, wtoken);
4552
4553 if (updateFocusAndLayout) {
Jeff Brown2e44b072011-01-24 15:21:56 -08004554 mInputMonitor.setUpdateInputWindowsNeededLw();
Jeff Brown3a22cd92011-01-21 13:59:04 -08004555 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4556 false /*updateInputWindows*/)) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004557 assignLayersLocked();
4558 }
4559 mLayoutNeeded = true;
4560 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08004561 mInputMonitor.updateInputWindowsLw(false /*force*/);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004562 }
4563 }
4564
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004565 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
4566 // First remove all of the windows from the list.
4567 final int N = tokens.size();
4568 int i;
4569 for (i=0; i<N; i++) {
4570 WindowToken token = mTokenMap.get(tokens.get(i));
4571 if (token != null) {
4572 tmpRemoveAppWindowsLocked(token);
4573 }
4574 }
4575
4576 // Where to start adding?
4577 int pos = findWindowOffsetLocked(tokenPos);
4578
4579 // And now add them back at the correct place.
4580 for (i=0; i<N; i++) {
4581 WindowToken token = mTokenMap.get(tokens.get(i));
4582 if (token != null) {
4583 pos = reAddAppWindowsLocked(pos, token);
4584 }
4585 }
4586
Jeff Brown2e44b072011-01-24 15:21:56 -08004587 mInputMonitor.setUpdateInputWindowsNeededLw();
Jeff Brown3a22cd92011-01-21 13:59:04 -08004588 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4589 false /*updateInputWindows*/)) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004590 assignLayersLocked();
4591 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004592 mLayoutNeeded = true;
4593 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08004594 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004595
4596 //dump();
4597 }
4598
4599 public void moveAppTokensToTop(List<IBinder> tokens) {
4600 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4601 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004602 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004603 }
4604
4605 final long origId = Binder.clearCallingIdentity();
4606 synchronized(mWindowMap) {
4607 removeAppTokensLocked(tokens);
4608 final int N = tokens.size();
4609 for (int i=0; i<N; i++) {
4610 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4611 if (wt != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004612 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
4613 "Adding next to top: " + wt);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004614 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004615 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004616 mToTopApps.remove(wt);
4617 mToBottomApps.remove(wt);
4618 mToTopApps.add(wt);
4619 wt.sendingToBottom = false;
4620 wt.sendingToTop = true;
4621 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004622 }
4623 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004624
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004625 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004626 moveAppWindowsLocked(tokens, mAppTokens.size());
4627 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004628 }
4629 Binder.restoreCallingIdentity(origId);
4630 }
4631
4632 public void moveAppTokensToBottom(List<IBinder> tokens) {
4633 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4634 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004635 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004636 }
4637
4638 final long origId = Binder.clearCallingIdentity();
4639 synchronized(mWindowMap) {
4640 removeAppTokensLocked(tokens);
4641 final int N = tokens.size();
4642 int pos = 0;
4643 for (int i=0; i<N; i++) {
4644 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4645 if (wt != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004646 if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4647 "Adding next to bottom: " + wt + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004648 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004649 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004650 mToTopApps.remove(wt);
4651 mToBottomApps.remove(wt);
4652 mToBottomApps.add(i, wt);
4653 wt.sendingToTop = false;
4654 wt.sendingToBottom = true;
4655 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004656 pos++;
4657 }
4658 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004659
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004660 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004661 moveAppWindowsLocked(tokens, 0);
4662 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004663 }
4664 Binder.restoreCallingIdentity(origId);
4665 }
4666
4667 // -------------------------------------------------------------
4668 // Misc IWindowSession methods
4669 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004670
Jim Miller284b62e2010-06-08 14:27:42 -07004671 private boolean shouldAllowDisableKeyguard()
Jim Millerd6b57052010-06-07 17:52:42 -07004672 {
Jim Miller284b62e2010-06-08 14:27:42 -07004673 // We fail safe and prevent disabling keyguard in the unlikely event this gets
4674 // called before DevicePolicyManagerService has started.
4675 if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
4676 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
4677 Context.DEVICE_POLICY_SERVICE);
4678 if (dpm != null) {
4679 mAllowDisableKeyguard = dpm.getPasswordQuality(null)
4680 == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
4681 ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
4682 }
Jim Millerd6b57052010-06-07 17:52:42 -07004683 }
Jim Miller284b62e2010-06-08 14:27:42 -07004684 return mAllowDisableKeyguard == ALLOW_DISABLE_YES;
Jim Millerd6b57052010-06-07 17:52:42 -07004685 }
4686
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004687 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004688 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004689 != PackageManager.PERMISSION_GRANTED) {
4690 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4691 }
Jim Millerd6b57052010-06-07 17:52:42 -07004692
Jim Miller284b62e2010-06-08 14:27:42 -07004693 synchronized (mKeyguardTokenWatcher) {
4694 mKeyguardTokenWatcher.acquire(token, tag);
Mike Lockwooddd884682009-10-11 16:57:08 -04004695 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004696 }
4697
4698 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004699 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004700 != PackageManager.PERMISSION_GRANTED) {
4701 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4702 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004703
Jim Miller284b62e2010-06-08 14:27:42 -07004704 synchronized (mKeyguardTokenWatcher) {
4705 mKeyguardTokenWatcher.release(token);
Jim Millerd6b57052010-06-07 17:52:42 -07004706
Jim Miller284b62e2010-06-08 14:27:42 -07004707 if (!mKeyguardTokenWatcher.isAcquired()) {
4708 // If we are the last one to reenable the keyguard wait until
4709 // we have actually finished reenabling until returning.
4710 // It is possible that reenableKeyguard() can be called before
4711 // the previous disableKeyguard() is handled, in which case
4712 // neither mKeyguardTokenWatcher.acquired() or released() would
4713 // be called. In that case mKeyguardDisabled will be false here
4714 // and we have nothing to wait for.
4715 while (mKeyguardDisabled) {
4716 try {
4717 mKeyguardTokenWatcher.wait();
4718 } catch (InterruptedException e) {
4719 Thread.currentThread().interrupt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004720 }
4721 }
4722 }
4723 }
4724 }
4725
4726 /**
4727 * @see android.app.KeyguardManager#exitKeyguardSecurely
4728 */
4729 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004730 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004731 != PackageManager.PERMISSION_GRANTED) {
4732 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4733 }
4734 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
4735 public void onKeyguardExitResult(boolean success) {
4736 try {
4737 callback.onKeyguardExitResult(success);
4738 } catch (RemoteException e) {
4739 // Client has died, we don't care.
4740 }
4741 }
4742 });
4743 }
4744
4745 public boolean inKeyguardRestrictedInputMode() {
4746 return mPolicy.inKeyguardRestrictedKeyInputMode();
4747 }
Romain Guy06882f82009-06-10 13:36:04 -07004748
Dianne Hackbornffa42482009-09-23 22:20:11 -07004749 public void closeSystemDialogs(String reason) {
4750 synchronized(mWindowMap) {
4751 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07004752 WindowState w = mWindows.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07004753 if (w.mSurface != null) {
4754 try {
4755 w.mClient.closeSystemDialogs(reason);
4756 } catch (RemoteException e) {
4757 }
4758 }
4759 }
4760 }
4761 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004762
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004763 static float fixScale(float scale) {
4764 if (scale < 0) scale = 0;
4765 else if (scale > 20) scale = 20;
4766 return Math.abs(scale);
4767 }
Romain Guy06882f82009-06-10 13:36:04 -07004768
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004769 public void setAnimationScale(int which, float scale) {
4770 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4771 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004772 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004773 }
4774
4775 if (scale < 0) scale = 0;
4776 else if (scale > 20) scale = 20;
4777 scale = Math.abs(scale);
4778 switch (which) {
4779 case 0: mWindowAnimationScale = fixScale(scale); break;
4780 case 1: mTransitionAnimationScale = fixScale(scale); break;
4781 }
Romain Guy06882f82009-06-10 13:36:04 -07004782
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004783 // Persist setting
4784 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4785 }
Romain Guy06882f82009-06-10 13:36:04 -07004786
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004787 public void setAnimationScales(float[] scales) {
4788 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4789 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004790 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004791 }
4792
4793 if (scales != null) {
4794 if (scales.length >= 1) {
4795 mWindowAnimationScale = fixScale(scales[0]);
4796 }
4797 if (scales.length >= 2) {
4798 mTransitionAnimationScale = fixScale(scales[1]);
4799 }
4800 }
Romain Guy06882f82009-06-10 13:36:04 -07004801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004802 // Persist setting
4803 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4804 }
Romain Guy06882f82009-06-10 13:36:04 -07004805
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004806 public float getAnimationScale(int which) {
4807 switch (which) {
4808 case 0: return mWindowAnimationScale;
4809 case 1: return mTransitionAnimationScale;
4810 }
4811 return 0;
4812 }
Romain Guy06882f82009-06-10 13:36:04 -07004813
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004814 public float[] getAnimationScales() {
4815 return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
4816 }
Romain Guy06882f82009-06-10 13:36:04 -07004817
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004818 public int getSwitchState(int sw) {
4819 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4820 "getSwitchState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004821 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004822 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004823 return mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004824 }
Romain Guy06882f82009-06-10 13:36:04 -07004825
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004826 public int getSwitchStateForDevice(int devid, int sw) {
4827 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4828 "getSwitchStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004829 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004830 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004831 return mInputManager.getSwitchState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004832 }
Romain Guy06882f82009-06-10 13:36:04 -07004833
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004834 public int getScancodeState(int sw) {
4835 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4836 "getScancodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004837 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004838 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004839 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004840 }
Romain Guy06882f82009-06-10 13:36:04 -07004841
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004842 public int getScancodeStateForDevice(int devid, int sw) {
4843 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4844 "getScancodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004845 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004846 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004847 return mInputManager.getScanCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004848 }
Romain Guy06882f82009-06-10 13:36:04 -07004849
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004850 public int getTrackballScancodeState(int sw) {
4851 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4852 "getTrackballScancodeState()")) {
4853 throw new SecurityException("Requires READ_INPUT_STATE permission");
4854 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004855 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004856 }
4857
4858 public int getDPadScancodeState(int sw) {
4859 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4860 "getDPadScancodeState()")) {
4861 throw new SecurityException("Requires READ_INPUT_STATE permission");
4862 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004863 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004864 }
4865
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004866 public int getKeycodeState(int sw) {
4867 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4868 "getKeycodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004869 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004870 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004871 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004872 }
Romain Guy06882f82009-06-10 13:36:04 -07004873
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004874 public int getKeycodeStateForDevice(int devid, int sw) {
4875 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4876 "getKeycodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004877 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004878 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004879 return mInputManager.getKeyCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004880 }
Romain Guy06882f82009-06-10 13:36:04 -07004881
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004882 public int getTrackballKeycodeState(int sw) {
4883 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4884 "getTrackballKeycodeState()")) {
4885 throw new SecurityException("Requires READ_INPUT_STATE permission");
4886 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004887 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004888 }
4889
4890 public int getDPadKeycodeState(int sw) {
4891 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4892 "getDPadKeycodeState()")) {
4893 throw new SecurityException("Requires READ_INPUT_STATE permission");
4894 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004895 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004896 }
Jeff Browna41ca772010-08-11 14:46:32 -07004897
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004898 public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
Jeff Brown6d0fec22010-07-23 21:28:06 -07004899 return mInputManager.hasKeys(-1, InputDevice.SOURCE_ANY, keycodes, keyExists);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004900 }
Romain Guy06882f82009-06-10 13:36:04 -07004901
Jeff Browna41ca772010-08-11 14:46:32 -07004902 public InputChannel monitorInput(String inputChannelName) {
4903 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4904 "monitorInput()")) {
4905 throw new SecurityException("Requires READ_INPUT_STATE permission");
4906 }
4907 return mInputManager.monitorInput(inputChannelName);
4908 }
4909
Jeff Brown8d608662010-08-30 03:02:23 -07004910 public InputDevice getInputDevice(int deviceId) {
4911 return mInputManager.getInputDevice(deviceId);
4912 }
4913
4914 public int[] getInputDeviceIds() {
4915 return mInputManager.getInputDeviceIds();
4916 }
4917
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004918 public void enableScreenAfterBoot() {
4919 synchronized(mWindowMap) {
4920 if (mSystemBooted) {
4921 return;
4922 }
4923 mSystemBooted = true;
4924 }
Romain Guy06882f82009-06-10 13:36:04 -07004925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004926 performEnableScreen();
4927 }
Romain Guy06882f82009-06-10 13:36:04 -07004928
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004929 public void enableScreenIfNeededLocked() {
4930 if (mDisplayEnabled) {
4931 return;
4932 }
4933 if (!mSystemBooted) {
4934 return;
4935 }
4936 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
4937 }
Romain Guy06882f82009-06-10 13:36:04 -07004938
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004939 public void performEnableScreen() {
4940 synchronized(mWindowMap) {
4941 if (mDisplayEnabled) {
4942 return;
4943 }
4944 if (!mSystemBooted) {
4945 return;
4946 }
Romain Guy06882f82009-06-10 13:36:04 -07004947
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004948 // Don't enable the screen until all existing windows
4949 // have been drawn.
4950 final int N = mWindows.size();
4951 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004952 WindowState w = mWindows.get(i);
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08004953 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004954 return;
4955 }
4956 }
Romain Guy06882f82009-06-10 13:36:04 -07004957
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004958 mDisplayEnabled = true;
4959 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004960 Slog.i(TAG, "ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004961 StringWriter sw = new StringWriter();
4962 PrintWriter pw = new PrintWriter(sw);
4963 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004964 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004965 }
4966 try {
4967 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
4968 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004969 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004970 Parcel data = Parcel.obtain();
4971 data.writeInterfaceToken("android.ui.ISurfaceComposer");
4972 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
4973 data, null, 0);
4974 data.recycle();
4975 }
4976 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004977 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004978 }
4979 }
Romain Guy06882f82009-06-10 13:36:04 -07004980
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004981 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07004982
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004983 // Make sure the last requested orientation has been applied.
Dianne Hackborn321ae682009-03-27 16:16:03 -07004984 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
4985 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004986 }
Romain Guy06882f82009-06-10 13:36:04 -07004987
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004988 public void setInTouchMode(boolean mode) {
4989 synchronized(mWindowMap) {
4990 mInTouchMode = mode;
4991 }
4992 }
4993
Brad Fitzpatrick68044332010-11-22 18:19:48 -08004994 // TODO: more accounting of which pid(s) turned it on, keep count,
4995 // only allow disables from pids which have count on, etc.
4996 public void showStrictModeViolation(boolean on) {
4997 int pid = Binder.getCallingPid();
4998 synchronized(mWindowMap) {
4999 // Ignoring requests to enable the red border from clients
5000 // which aren't on screen. (e.g. Broadcast Receivers in
5001 // the background..)
5002 if (on) {
5003 boolean isVisible = false;
5004 for (WindowState ws : mWindows) {
5005 if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
5006 isVisible = true;
5007 break;
5008 }
5009 }
5010 if (!isVisible) {
5011 return;
5012 }
5013 }
5014
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005015 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005016 Surface.openTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005017 try {
5018 if (mStrictModeFlash == null) {
5019 mStrictModeFlash = new StrictModeFlash(mDisplay, mFxSession);
5020 }
5021 mStrictModeFlash.setVisibility(on);
5022 } finally {
5023 Surface.closeTransaction();
5024 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005025 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005026 }
5027 }
5028
Brad Fitzpatrickc1a968a2010-11-24 08:56:40 -08005029 public void setStrictModeVisualIndicatorPreference(String value) {
5030 SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
5031 }
5032
Dianne Hackbornd2835932010-12-13 16:28:46 -08005033 public Bitmap screenshotApplications(IBinder appToken, int maxWidth, int maxHeight) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005034 if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5035 "screenshotApplications()")) {
5036 throw new SecurityException("Requires READ_FRAME_BUFFER permission");
5037 }
5038
5039 Bitmap rawss;
5040
Dianne Hackbornd2835932010-12-13 16:28:46 -08005041 int maxLayer = 0;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005042 final Rect frame = new Rect();
5043
5044 float scale;
5045 int sw, sh, dw, dh;
5046 int rot;
5047
5048 synchronized(mWindowMap) {
5049 long ident = Binder.clearCallingIdentity();
5050
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005051 dw = mDisplay.getWidth();
5052 dh = mDisplay.getHeight();
5053
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005054 int aboveAppLayer = mPolicy.windowTypeToLayerLw(
5055 WindowManager.LayoutParams.TYPE_APPLICATION) * TYPE_LAYER_MULTIPLIER
5056 + TYPE_LAYER_OFFSET;
5057 aboveAppLayer += TYPE_LAYER_MULTIPLIER;
5058
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005059 boolean isImeTarget = mInputMethodTarget != null
5060 && mInputMethodTarget.mAppToken != null
5061 && mInputMethodTarget.mAppToken.appToken != null
5062 && mInputMethodTarget.mAppToken.appToken.asBinder() == appToken;
5063
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005064 // Figure out the part of the screen that is actually the app.
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005065 boolean including = false;
5066 for (int i=mWindows.size()-1; i>=0; i--) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005067 WindowState ws = mWindows.get(i);
5068 if (ws.mSurface == null) {
5069 continue;
5070 }
5071 if (ws.mLayer >= aboveAppLayer) {
Dianne Hackbornd2835932010-12-13 16:28:46 -08005072 continue;
5073 }
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005074 // When we will skip windows: when we are not including
5075 // ones behind a window we didn't skip, and we are actually
5076 // taking a screenshot of a specific app.
5077 if (!including && appToken != null) {
5078 // Also, we can possibly skip this window if it is not
5079 // an IME target or the application for the screenshot
5080 // is not the current IME target.
5081 if (!ws.mIsImWindow || !isImeTarget) {
5082 // And finally, this window is of no interest if it
5083 // is not associated with the screenshot app.
5084 if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
5085 continue;
5086 }
5087 }
5088 }
5089
5090 // We keep on including windows until we go past a full-screen
5091 // window.
5092 including = !ws.mIsImWindow && !ws.isFullscreen(dw, dh);
5093
Dianne Hackbornd2835932010-12-13 16:28:46 -08005094 if (maxLayer < ws.mAnimLayer) {
5095 maxLayer = ws.mAnimLayer;
5096 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005097 final Rect wf = ws.mFrame;
5098 final Rect cr = ws.mContentInsets;
5099 int left = wf.left + cr.left;
5100 int top = wf.top + cr.top;
5101 int right = wf.right - cr.right;
5102 int bottom = wf.bottom - cr.bottom;
5103 frame.union(left, top, right, bottom);
5104 }
5105 Binder.restoreCallingIdentity(ident);
5106
Dianne Hackborndd962ee2011-02-02 11:11:50 -08005107 // Constrain frame to the screen size.
5108 frame.intersect(0, 0, dw, dh);
5109
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005110 if (frame.isEmpty() || maxLayer == 0) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005111 return null;
5112 }
5113
5114 // The screenshot API does not apply the current screen rotation.
5115 rot = mDisplay.getRotation();
5116 int fw = frame.width();
5117 int fh = frame.height();
5118
5119 // First try reducing to fit in x dimension.
5120 scale = maxWidth/(float)fw;
5121 sw = maxWidth;
5122 sh = (int)(fh*scale);
5123 if (sh > maxHeight) {
5124 // y dimension became too long; constrain by that.
5125 scale = maxHeight/(float)fh;
5126 sw = (int)(fw*scale);
5127 sh = maxHeight;
5128 }
5129
5130 // The screen shot will contain the entire screen.
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005131 dw = (int)(dw*scale);
5132 dh = (int)(dh*scale);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005133 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
5134 int tmp = dw;
5135 dw = dh;
5136 dh = tmp;
5137 rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
5138 }
Dianne Hackbornd2835932010-12-13 16:28:46 -08005139 rawss = Surface.screenshot(dw, dh, 0, maxLayer);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005140 }
5141
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005142 if (rawss == null) {
Dianne Hackborn88b03bd2010-12-16 11:15:18 -08005143 Log.w(TAG, "Failure taking screenshot for (" + dw + "x" + dh
5144 + ") to layer " + maxLayer);
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005145 return null;
5146 }
5147
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005148 Bitmap bm = Bitmap.createBitmap(sw, sh, rawss.getConfig());
5149 Matrix matrix = new Matrix();
5150 ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
5151 matrix.postTranslate(-(int)(frame.left*scale), -(int)(frame.top*scale));
5152 Canvas canvas = new Canvas(bm);
5153 canvas.drawBitmap(rawss, matrix, null);
5154
5155 rawss.recycle();
5156 return bm;
5157 }
5158
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005159 public void freezeRotation() {
5160 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
5161 "setRotation()")) {
5162 throw new SecurityException("Requires SET_ORIENTATION permission");
5163 }
5164
5165 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED, mRotation);
5166 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
5167 }
5168
5169 public void thawRotation() {
5170 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
5171 "setRotation()")) {
5172 throw new SecurityException("Requires SET_ORIENTATION permission");
5173 }
5174
5175 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 0);
5176 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
5177 }
5178
Romain Guy06882f82009-06-10 13:36:04 -07005179 public void setRotation(int rotation,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005180 boolean alwaysSendConfiguration, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005181 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005182 "setRotation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005183 throw new SecurityException("Requires SET_ORIENTATION permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005184 }
5185
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005186 setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005187 }
Romain Guy06882f82009-06-10 13:36:04 -07005188
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005189 public void setRotationUnchecked(int rotation,
5190 boolean alwaysSendConfiguration, int animFlags) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005191 if(DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005192 "alwaysSendConfiguration set to "+alwaysSendConfiguration);
Romain Guy06882f82009-06-10 13:36:04 -07005193
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005194 long origId = Binder.clearCallingIdentity();
5195 boolean changed;
5196 synchronized(mWindowMap) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005197 changed = setRotationUncheckedLocked(rotation, animFlags, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005198 }
Romain Guy06882f82009-06-10 13:36:04 -07005199
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005200 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005201 sendNewConfiguration();
5202 }
Romain Guy06882f82009-06-10 13:36:04 -07005203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005204 Binder.restoreCallingIdentity(origId);
5205 }
Romain Guy06882f82009-06-10 13:36:04 -07005206
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005207 /**
5208 * Apply a new rotation to the screen, respecting the requests of
5209 * applications. Use WindowManagerPolicy.USE_LAST_ROTATION to simply
5210 * re-evaluate the desired rotation.
5211 *
5212 * Returns null if the rotation has been changed. In this case YOU
5213 * MUST CALL setNewConfiguration() TO UNFREEZE THE SCREEN.
5214 */
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005215 public boolean setRotationUncheckedLocked(int rotation, int animFlags, boolean inTransaction) {
Dianne Hackborn89ba6752011-01-23 16:51:16 -08005216 if (mDragState != null || mScreenRotationAnimation != null) {
Christopher Tateccd24de2011-01-12 15:02:55 -08005217 // Potential rotation during a drag. Don't do the rotation now, but make
5218 // a note to perform the rotation later.
Dianne Hackborn89ba6752011-01-23 16:51:16 -08005219 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation.");
5220 if (rotation != WindowManagerPolicy.USE_LAST_ROTATION) {
5221 mDeferredRotation = rotation;
5222 mDeferredRotationAnimFlags = animFlags;
5223 }
Christopher Tateccd24de2011-01-12 15:02:55 -08005224 return false;
5225 }
5226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005227 boolean changed;
5228 if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
Dianne Hackborn89ba6752011-01-23 16:51:16 -08005229 if (mDeferredRotation != WindowManagerPolicy.USE_LAST_ROTATION) {
5230 rotation = mDeferredRotation;
5231 mRequestedRotation = rotation;
5232 mLastRotationFlags = mDeferredRotationAnimFlags;
5233 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005234 rotation = mRequestedRotation;
5235 } else {
5236 mRequestedRotation = rotation;
Dianne Hackborn321ae682009-03-27 16:16:03 -07005237 mLastRotationFlags = animFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005238 }
Dianne Hackborn89ba6752011-01-23 16:51:16 -08005239 mDeferredRotation = WindowManagerPolicy.USE_LAST_ROTATION;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005240 if (DEBUG_ORIENTATION) Slog.v(TAG, "Overwriting rotation value from " + rotation);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07005241 rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005242 mRotation, mDisplayEnabled);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005243 if (DEBUG_ORIENTATION) Slog.v(TAG, "new rotation is set to " + rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005244 changed = mDisplayEnabled && mRotation != rotation;
Romain Guy06882f82009-06-10 13:36:04 -07005245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005246 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005247 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005248 "Rotation changed to " + rotation
5249 + " from " + mRotation
5250 + " (forceApp=" + mForcedAppOrientation
5251 + ", req=" + mRequestedRotation + ")");
5252 mRotation = rotation;
5253 mWindowsFreezingScreen = true;
5254 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
5255 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
5256 2000);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005257 mWaitingForConfig = true;
5258 mLayoutNeeded = true;
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005259 startFreezingDisplayLocked(inTransaction);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005260 Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005261 mInputManager.setDisplayOrientation(0, rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005262 if (mDisplayEnabled) {
Dianne Hackborna1111872010-11-23 20:55:11 -08005263 if (CUSTOM_SCREEN_ROTATION) {
5264 Surface.freezeDisplay(0);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005265 if (!inTransaction) {
5266 if (SHOW_TRANSACTIONS) Slog.i(TAG,
5267 ">>> OPEN TRANSACTION setRotationUnchecked");
5268 Surface.openTransaction();
Dianne Hackborna1111872010-11-23 20:55:11 -08005269 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005270 try {
5271 if (mScreenRotationAnimation != null) {
5272 mScreenRotationAnimation.setRotation(rotation);
5273 }
5274 } finally {
5275 if (!inTransaction) {
5276 Surface.closeTransaction();
5277 if (SHOW_TRANSACTIONS) Slog.i(TAG,
5278 "<<< CLOSE TRANSACTION setRotationUnchecked");
5279 }
5280 }
Dianne Hackborna1111872010-11-23 20:55:11 -08005281 Surface.setOrientation(0, rotation, animFlags);
5282 Surface.unfreezeDisplay(0);
5283 } else {
5284 Surface.setOrientation(0, rotation, animFlags);
5285 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005286 }
5287 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07005288 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005289 if (w.mSurface != null) {
5290 w.mOrientationChanging = true;
5291 }
5292 }
5293 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
5294 try {
5295 mRotationWatchers.get(i).onRotationChanged(rotation);
5296 } catch (RemoteException e) {
5297 }
5298 }
5299 } //end if changed
Romain Guy06882f82009-06-10 13:36:04 -07005300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005301 return changed;
5302 }
Romain Guy06882f82009-06-10 13:36:04 -07005303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005304 public int getRotation() {
5305 return mRotation;
5306 }
5307
5308 public int watchRotation(IRotationWatcher watcher) {
5309 final IBinder watcherBinder = watcher.asBinder();
5310 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
5311 public void binderDied() {
5312 synchronized (mWindowMap) {
5313 for (int i=0; i<mRotationWatchers.size(); i++) {
5314 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07005315 IRotationWatcher removed = mRotationWatchers.remove(i);
5316 if (removed != null) {
5317 removed.asBinder().unlinkToDeath(this, 0);
5318 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005319 i--;
5320 }
5321 }
5322 }
5323 }
5324 };
Romain Guy06882f82009-06-10 13:36:04 -07005325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005326 synchronized (mWindowMap) {
5327 try {
5328 watcher.asBinder().linkToDeath(dr, 0);
5329 mRotationWatchers.add(watcher);
5330 } catch (RemoteException e) {
5331 // Client died, no cleanup needed.
5332 }
Romain Guy06882f82009-06-10 13:36:04 -07005333
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005334 return mRotation;
5335 }
5336 }
5337
5338 /**
5339 * Starts the view server on the specified port.
5340 *
5341 * @param port The port to listener to.
5342 *
5343 * @return True if the server was successfully started, false otherwise.
5344 *
5345 * @see com.android.server.ViewServer
5346 * @see com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT
5347 */
5348 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07005349 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005350 return false;
5351 }
5352
5353 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
5354 return false;
5355 }
5356
5357 if (port < 1024) {
5358 return false;
5359 }
5360
5361 if (mViewServer != null) {
5362 if (!mViewServer.isRunning()) {
5363 try {
5364 return mViewServer.start();
5365 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005366 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005367 }
5368 }
5369 return false;
5370 }
5371
5372 try {
5373 mViewServer = new ViewServer(this, port);
5374 return mViewServer.start();
5375 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005376 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005377 }
5378 return false;
5379 }
5380
Romain Guy06882f82009-06-10 13:36:04 -07005381 private boolean isSystemSecure() {
5382 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
5383 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5384 }
5385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005386 /**
5387 * Stops the view server if it exists.
5388 *
5389 * @return True if the server stopped, false if it wasn't started or
5390 * couldn't be stopped.
5391 *
5392 * @see com.android.server.ViewServer
5393 */
5394 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07005395 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005396 return false;
5397 }
5398
5399 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
5400 return false;
5401 }
5402
5403 if (mViewServer != null) {
5404 return mViewServer.stop();
5405 }
5406 return false;
5407 }
5408
5409 /**
5410 * Indicates whether the view server is running.
5411 *
5412 * @return True if the server is running, false otherwise.
5413 *
5414 * @see com.android.server.ViewServer
5415 */
5416 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07005417 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005418 return false;
5419 }
5420
5421 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
5422 return false;
5423 }
5424
5425 return mViewServer != null && mViewServer.isRunning();
5426 }
5427
5428 /**
5429 * Lists all availble windows in the system. The listing is written in the
5430 * specified Socket's output stream with the following syntax:
5431 * windowHashCodeInHexadecimal windowName
5432 * Each line of the ouput represents a different window.
5433 *
5434 * @param client The remote client to send the listing to.
5435 * @return False if an error occured, true otherwise.
5436 */
5437 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07005438 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005439 return false;
5440 }
5441
5442 boolean result = true;
5443
Jeff Browne33348b2010-07-15 23:54:05 -07005444 WindowState[] windows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005445 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005446 //noinspection unchecked
Jeff Browne33348b2010-07-15 23:54:05 -07005447 windows = mWindows.toArray(new WindowState[mWindows.size()]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005448 }
5449
5450 BufferedWriter out = null;
5451
5452 // Any uncaught exception will crash the system process
5453 try {
5454 OutputStream clientStream = client.getOutputStream();
5455 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5456
5457 final int count = windows.length;
5458 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005459 final WindowState w = windows[i];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005460 out.write(Integer.toHexString(System.identityHashCode(w)));
5461 out.write(' ');
5462 out.append(w.mAttrs.getTitle());
5463 out.write('\n');
5464 }
5465
5466 out.write("DONE.\n");
5467 out.flush();
5468 } catch (Exception e) {
5469 result = false;
5470 } finally {
5471 if (out != null) {
5472 try {
5473 out.close();
5474 } catch (IOException e) {
5475 result = false;
5476 }
5477 }
5478 }
5479
5480 return result;
5481 }
5482
5483 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07005484 * Returns the focused window in the following format:
5485 * windowHashCodeInHexadecimal windowName
5486 *
5487 * @param client The remote client to send the listing to.
5488 * @return False if an error occurred, true otherwise.
5489 */
5490 boolean viewServerGetFocusedWindow(Socket client) {
5491 if (isSystemSecure()) {
5492 return false;
5493 }
5494
5495 boolean result = true;
5496
5497 WindowState focusedWindow = getFocusedWindow();
5498
5499 BufferedWriter out = null;
5500
5501 // Any uncaught exception will crash the system process
5502 try {
5503 OutputStream clientStream = client.getOutputStream();
5504 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5505
5506 if(focusedWindow != null) {
5507 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
5508 out.write(' ');
5509 out.append(focusedWindow.mAttrs.getTitle());
5510 }
5511 out.write('\n');
5512 out.flush();
5513 } catch (Exception e) {
5514 result = false;
5515 } finally {
5516 if (out != null) {
5517 try {
5518 out.close();
5519 } catch (IOException e) {
5520 result = false;
5521 }
5522 }
5523 }
5524
5525 return result;
5526 }
5527
5528 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005529 * Sends a command to a target window. The result of the command, if any, will be
5530 * written in the output stream of the specified socket.
5531 *
5532 * The parameters must follow this syntax:
5533 * windowHashcode extra
5534 *
5535 * Where XX is the length in characeters of the windowTitle.
5536 *
5537 * The first parameter is the target window. The window with the specified hashcode
5538 * will be the target. If no target can be found, nothing happens. The extra parameters
5539 * will be delivered to the target window and as parameters to the command itself.
5540 *
5541 * @param client The remote client to sent the result, if any, to.
5542 * @param command The command to execute.
5543 * @param parameters The command parameters.
5544 *
5545 * @return True if the command was successfully delivered, false otherwise. This does
5546 * not indicate whether the command itself was successful.
5547 */
5548 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07005549 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005550 return false;
5551 }
5552
5553 boolean success = true;
5554 Parcel data = null;
5555 Parcel reply = null;
5556
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005557 BufferedWriter out = null;
5558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005559 // Any uncaught exception will crash the system process
5560 try {
5561 // Find the hashcode of the window
5562 int index = parameters.indexOf(' ');
5563 if (index == -1) {
5564 index = parameters.length();
5565 }
5566 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08005567 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005568
5569 // Extract the command's parameter after the window description
5570 if (index < parameters.length()) {
5571 parameters = parameters.substring(index + 1);
5572 } else {
5573 parameters = "";
5574 }
5575
5576 final WindowManagerService.WindowState window = findWindow(hashCode);
5577 if (window == null) {
5578 return false;
5579 }
5580
5581 data = Parcel.obtain();
5582 data.writeInterfaceToken("android.view.IWindow");
5583 data.writeString(command);
5584 data.writeString(parameters);
5585 data.writeInt(1);
5586 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
5587
5588 reply = Parcel.obtain();
5589
5590 final IBinder binder = window.mClient.asBinder();
5591 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
5592 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
5593
5594 reply.readException();
5595
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005596 if (!client.isOutputShutdown()) {
5597 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
5598 out.write("DONE\n");
5599 out.flush();
5600 }
5601
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005602 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005603 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005604 success = false;
5605 } finally {
5606 if (data != null) {
5607 data.recycle();
5608 }
5609 if (reply != null) {
5610 reply.recycle();
5611 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005612 if (out != null) {
5613 try {
5614 out.close();
5615 } catch (IOException e) {
5616
5617 }
5618 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005619 }
5620
5621 return success;
5622 }
5623
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07005624 public void addWindowChangeListener(WindowChangeListener listener) {
5625 synchronized(mWindowMap) {
5626 mWindowChangeListeners.add(listener);
5627 }
5628 }
5629
5630 public void removeWindowChangeListener(WindowChangeListener listener) {
5631 synchronized(mWindowMap) {
5632 mWindowChangeListeners.remove(listener);
5633 }
5634 }
5635
5636 private void notifyWindowsChanged() {
5637 WindowChangeListener[] windowChangeListeners;
5638 synchronized(mWindowMap) {
5639 if(mWindowChangeListeners.isEmpty()) {
5640 return;
5641 }
5642 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5643 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5644 }
5645 int N = windowChangeListeners.length;
5646 for(int i = 0; i < N; i++) {
5647 windowChangeListeners[i].windowsChanged();
5648 }
5649 }
5650
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07005651 private void notifyFocusChanged() {
5652 WindowChangeListener[] windowChangeListeners;
5653 synchronized(mWindowMap) {
5654 if(mWindowChangeListeners.isEmpty()) {
5655 return;
5656 }
5657 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5658 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5659 }
5660 int N = windowChangeListeners.length;
5661 for(int i = 0; i < N; i++) {
5662 windowChangeListeners[i].focusChanged();
5663 }
5664 }
5665
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005666 private WindowState findWindow(int hashCode) {
5667 if (hashCode == -1) {
5668 return getFocusedWindow();
5669 }
5670
5671 synchronized (mWindowMap) {
Jeff Browne33348b2010-07-15 23:54:05 -07005672 final ArrayList<WindowState> windows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005673 final int count = windows.size();
5674
5675 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005676 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005677 if (System.identityHashCode(w) == hashCode) {
5678 return w;
5679 }
5680 }
5681 }
5682
5683 return null;
5684 }
5685
5686 /*
5687 * Instruct the Activity Manager to fetch the current configuration and broadcast
5688 * that to config-changed listeners if appropriate.
5689 */
5690 void sendNewConfiguration() {
5691 try {
5692 mActivityManager.updateConfiguration(null);
5693 } catch (RemoteException e) {
5694 }
5695 }
Romain Guy06882f82009-06-10 13:36:04 -07005696
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005697 public Configuration computeNewConfiguration() {
5698 synchronized (mWindowMap) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005699 Configuration config = computeNewConfigurationLocked();
5700 if (config == null && mWaitingForConfig) {
5701 // Nothing changed but we are waiting for something... stop that!
5702 mWaitingForConfig = false;
5703 performLayoutAndPlaceSurfacesLocked();
5704 }
5705 return config;
Dianne Hackbornc485a602009-03-24 22:39:49 -07005706 }
5707 }
Romain Guy06882f82009-06-10 13:36:04 -07005708
Dianne Hackbornc485a602009-03-24 22:39:49 -07005709 Configuration computeNewConfigurationLocked() {
5710 Configuration config = new Configuration();
5711 if (!computeNewConfigurationLocked(config)) {
5712 return null;
5713 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07005714 return config;
5715 }
Romain Guy06882f82009-06-10 13:36:04 -07005716
Dianne Hackbornc485a602009-03-24 22:39:49 -07005717 boolean computeNewConfigurationLocked(Configuration config) {
5718 if (mDisplay == null) {
5719 return false;
5720 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005721
5722 mInputManager.getInputConfiguration(config);
Christopher Tateb696aee2010-04-02 19:08:30 -07005723
5724 // Use the effective "visual" dimensions based on current rotation
5725 final boolean rotated = (mRotation == Surface.ROTATION_90
5726 || mRotation == Surface.ROTATION_270);
5727 final int dw = rotated ? mInitialDisplayHeight : mInitialDisplayWidth;
5728 final int dh = rotated ? mInitialDisplayWidth : mInitialDisplayHeight;
5729
Dianne Hackbornc485a602009-03-24 22:39:49 -07005730 int orientation = Configuration.ORIENTATION_SQUARE;
5731 if (dw < dh) {
5732 orientation = Configuration.ORIENTATION_PORTRAIT;
5733 } else if (dw > dh) {
5734 orientation = Configuration.ORIENTATION_LANDSCAPE;
5735 }
5736 config.orientation = orientation;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005737
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005738 DisplayMetrics dm = new DisplayMetrics();
5739 mDisplay.getMetrics(dm);
5740 CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame);
5741
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005742 if (mScreenLayout == Configuration.SCREENLAYOUT_SIZE_UNDEFINED) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07005743 // Note we only do this once because at this point we don't
5744 // expect the screen to change in this way at runtime, and want
5745 // to avoid all of this computation for every config change.
Dianne Hackborn723738c2009-06-25 19:48:04 -07005746 int longSize = dw;
5747 int shortSize = dh;
5748 if (longSize < shortSize) {
5749 int tmp = longSize;
5750 longSize = shortSize;
5751 shortSize = tmp;
5752 }
5753 longSize = (int)(longSize/dm.density);
5754 shortSize = (int)(shortSize/dm.density);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005755
Dianne Hackborn723738c2009-06-25 19:48:04 -07005756 // These semi-magic numbers define our compatibility modes for
5757 // applications with different screens. Don't change unless you
5758 // make sure to test lots and lots of apps!
5759 if (longSize < 470) {
5760 // This is shorter than an HVGA normal density screen (which
5761 // is 480 pixels on its long side).
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005762 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL
5763 | Configuration.SCREENLAYOUT_LONG_NO;
Dianne Hackborn723738c2009-06-25 19:48:04 -07005764 } else {
Dianne Hackborn14cee9f2010-04-23 17:51:26 -07005765 // What size is this screen screen?
5766 if (longSize >= 800 && shortSize >= 600) {
5767 // SVGA or larger screens at medium density are the point
5768 // at which we consider it to be an extra large screen.
5769 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE;
Dianne Hackbornb51dc0f2010-10-21 15:34:47 -07005770 } else if (longSize >= 530 && shortSize >= 400) {
5771 // SVGA or larger screens at high density are the point
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005772 // at which we consider it to be a large screen.
5773 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
5774 } else {
5775 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL;
Dianne Hackborne97a12e2011-01-29 13:22:02 -08005776 }
5777
5778 // If this screen is wider than normal HVGA, or taller
5779 // than FWVGA, then for old apps we want to run in size
5780 // compatibility mode.
5781 if (shortSize > 321 || longSize > 570) {
5782 mScreenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005783 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005784
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005785 // Is this a long screen?
5786 if (((longSize*3)/5) >= (shortSize-1)) {
5787 // Anything wider than WVGA (5:3) is considering to be long.
5788 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_YES;
5789 } else {
5790 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_NO;
5791 }
Dianne Hackborn723738c2009-06-25 19:48:04 -07005792 }
5793 }
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005794 config.screenLayout = mScreenLayout;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005795
Jeff Brown597eec82011-01-31 17:12:25 -08005796 // Determine whether a hard keyboard is available and enabled.
Jeff Brown2992ea72011-01-28 22:04:14 -08005797 boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
5798 if (hardKeyboardAvailable != mHardKeyboardAvailable) {
5799 mHardKeyboardAvailable = hardKeyboardAvailable;
5800 mHardKeyboardEnabled = hardKeyboardAvailable;
5801
5802 mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
5803 mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
5804 }
5805 if (!mHardKeyboardEnabled) {
5806 config.keyboard = Configuration.KEYBOARD_NOKEYS;
Jeff Brown2992ea72011-01-28 22:04:14 -08005807 }
Jeff Brown597eec82011-01-31 17:12:25 -08005808
5809 // Update value of keyboardHidden, hardKeyboardHidden and navigationHidden
5810 // based on whether a hard or soft keyboard is present, whether navigation keys
5811 // are present and the lid switch state.
5812 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
5813 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
5814 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO;
5815 mPolicy.adjustConfigurationLw(config);
Dianne Hackbornc485a602009-03-24 22:39:49 -07005816 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005817 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005818
Jeff Brown2992ea72011-01-28 22:04:14 -08005819 public boolean isHardKeyboardAvailable() {
5820 synchronized (mWindowMap) {
5821 return mHardKeyboardAvailable;
5822 }
5823 }
5824
5825 public boolean isHardKeyboardEnabled() {
5826 synchronized (mWindowMap) {
5827 return mHardKeyboardEnabled;
5828 }
5829 }
5830
5831 public void setHardKeyboardEnabled(boolean enabled) {
5832 synchronized (mWindowMap) {
5833 if (mHardKeyboardEnabled != enabled) {
5834 mHardKeyboardEnabled = enabled;
5835 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
5836 }
5837 }
5838 }
5839
5840 public void setOnHardKeyboardStatusChangeListener(
5841 OnHardKeyboardStatusChangeListener listener) {
5842 synchronized (mWindowMap) {
5843 mHardKeyboardStatusChangeListener = listener;
5844 }
5845 }
5846
5847 void notifyHardKeyboardStatusChange() {
5848 final boolean available, enabled;
5849 final OnHardKeyboardStatusChangeListener listener;
5850 synchronized (mWindowMap) {
5851 listener = mHardKeyboardStatusChangeListener;
5852 available = mHardKeyboardAvailable;
5853 enabled = mHardKeyboardEnabled;
5854 }
5855 if (listener != null) {
5856 listener.onHardKeyboardStatusChange(available, enabled);
5857 }
5858 }
5859
Christopher Tatea53146c2010-09-07 11:57:52 -07005860 // -------------------------------------------------------------
5861 // Drag and drop
5862 // -------------------------------------------------------------
5863
5864 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
Christopher Tate02d2b3b2011-01-10 20:43:53 -08005865 int flags, int width, int height, Surface outSurface) {
Christopher Tatea53146c2010-09-07 11:57:52 -07005866 if (DEBUG_DRAG) {
5867 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
Christopher Tate02d2b3b2011-01-10 20:43:53 -08005868 + " flags=" + Integer.toHexString(flags) + " win=" + window
Christopher Tatea53146c2010-09-07 11:57:52 -07005869 + " asbinder=" + window.asBinder());
5870 }
5871
5872 final int callerPid = Binder.getCallingPid();
5873 final long origId = Binder.clearCallingIdentity();
5874 IBinder token = null;
5875
5876 try {
5877 synchronized (mWindowMap) {
5878 try {
Christopher Tatea53146c2010-09-07 11:57:52 -07005879 if (mDragState == null) {
5880 Surface surface = new Surface(session, callerPid, "drag surface", 0,
5881 width, height, PixelFormat.TRANSLUCENT, Surface.HIDDEN);
Dianne Hackbornac1471a2011-02-03 13:46:06 -08005882 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DRAG "
5883 + surface + ": CREATE");
Christopher Tatea53146c2010-09-07 11:57:52 -07005884 outSurface.copyFrom(surface);
Chris Tate7b362e42010-11-04 16:02:52 -07005885 final IBinder winBinder = window.asBinder();
Christopher Tatea53146c2010-09-07 11:57:52 -07005886 token = new Binder();
Christopher Tate02d2b3b2011-01-10 20:43:53 -08005887 // TODO: preserve flags param in DragState
5888 mDragState = new DragState(token, surface, 0, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07005889 mDragState.mSurface = surface;
Christopher Tatea53146c2010-09-07 11:57:52 -07005890 token = mDragState.mToken = new Binder();
5891
5892 // 5 second timeout for this window to actually begin the drag
Chris Tate7b362e42010-11-04 16:02:52 -07005893 mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
5894 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07005895 mH.sendMessageDelayed(msg, 5000);
5896 } else {
5897 Slog.w(TAG, "Drag already in progress");
5898 }
5899 } catch (Surface.OutOfResourcesException e) {
5900 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
5901 if (mDragState != null) {
5902 mDragState.reset();
5903 mDragState = null;
5904 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005905 }
5906 }
5907 } finally {
5908 Binder.restoreCallingIdentity(origId);
5909 }
5910
5911 return token;
5912 }
5913
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005914 // -------------------------------------------------------------
5915 // Input Events and Focus Management
5916 // -------------------------------------------------------------
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005917
Jeff Brown349703e2010-06-22 01:27:15 -07005918 InputMonitor mInputMonitor = new InputMonitor();
5919
5920 /* Tracks the progress of input dispatch and ensures that input dispatch state
5921 * is kept in sync with changes in window focus, visibility, registration, and
5922 * other relevant Window Manager state transitions. */
5923 final class InputMonitor {
5924 // Current window with input focus for keys and other non-touch events. May be null.
5925 private WindowState mInputFocus;
5926
5927 // When true, prevents input dispatch from proceeding until set to false again.
5928 private boolean mInputDispatchFrozen;
5929
5930 // When true, input dispatch proceeds normally. Otherwise all events are dropped.
5931 private boolean mInputDispatchEnabled = true;
5932
Jeff Brown3a22cd92011-01-21 13:59:04 -08005933 // When true, need to call updateInputWindowsLw().
5934 private boolean mUpdateInputWindowsNeeded = true;
5935
Jeff Brown349703e2010-06-22 01:27:15 -07005936 // Temporary list of windows information to provide to the input dispatcher.
5937 private InputWindowList mTempInputWindows = new InputWindowList();
5938
5939 // Temporary input application object to provide to the input dispatcher.
5940 private InputApplication mTempInputApplication = new InputApplication();
5941
Jeff Brownb09abc12011-01-13 21:08:27 -08005942 // Set to true when the first input device configuration change notification
5943 // is received to indicate that the input devices are ready.
5944 private final Object mInputDevicesReadyMonitor = new Object();
5945 private boolean mInputDevicesReady;
5946
Jeff Brown349703e2010-06-22 01:27:15 -07005947 /* Notifies the window manager about a broken input channel.
5948 *
5949 * Called by the InputManager.
5950 */
Jeff Brown928e0542011-01-10 11:17:36 -08005951 public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle) {
5952 if (inputWindowHandle == null) {
5953 return;
5954 }
5955
Jeff Brown349703e2010-06-22 01:27:15 -07005956 synchronized (mWindowMap) {
Jeff Brown928e0542011-01-10 11:17:36 -08005957 WindowState windowState = (WindowState) inputWindowHandle.windowState;
Jeff Brown349703e2010-06-22 01:27:15 -07005958 Slog.i(TAG, "WINDOW DIED " + windowState);
5959 removeWindowLocked(windowState.mSession, windowState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005960 }
5961 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005962
Jeff Brown519e0242010-09-15 15:18:56 -07005963 /* Notifies the window manager about an application that is not responding.
Jeff Brownb88102f2010-09-08 11:49:43 -07005964 * Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch.
Jeff Brown349703e2010-06-22 01:27:15 -07005965 *
5966 * Called by the InputManager.
5967 */
Jeff Brown928e0542011-01-10 11:17:36 -08005968 public long notifyANR(InputApplicationHandle inputApplicationHandle,
5969 InputWindowHandle inputWindowHandle) {
Jeff Brown519e0242010-09-15 15:18:56 -07005970 AppWindowToken appWindowToken = null;
Jeff Brown928e0542011-01-10 11:17:36 -08005971 if (inputWindowHandle != null) {
Jeff Brown519e0242010-09-15 15:18:56 -07005972 synchronized (mWindowMap) {
Jeff Brown928e0542011-01-10 11:17:36 -08005973 WindowState windowState = (WindowState) inputWindowHandle.windowState;
Jeff Brown519e0242010-09-15 15:18:56 -07005974 if (windowState != null) {
5975 Slog.i(TAG, "Input event dispatching timed out sending to "
5976 + windowState.mAttrs.getTitle());
5977 appWindowToken = windowState.mAppToken;
5978 }
Jeff Brown349703e2010-06-22 01:27:15 -07005979 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005980 }
5981
Jeff Brown928e0542011-01-10 11:17:36 -08005982 if (appWindowToken == null && inputApplicationHandle != null) {
5983 appWindowToken = inputApplicationHandle.appWindowToken;
Jeff Brown519e0242010-09-15 15:18:56 -07005984 Slog.i(TAG, "Input event dispatching timed out sending to application "
5985 + appWindowToken.stringName);
5986 }
Jeff Brown349703e2010-06-22 01:27:15 -07005987
Jeff Brown519e0242010-09-15 15:18:56 -07005988 if (appWindowToken != null && appWindowToken.appToken != null) {
Jeff Brown349703e2010-06-22 01:27:15 -07005989 try {
5990 // Notify the activity manager about the timeout and let it decide whether
5991 // to abort dispatching or keep waiting.
Jeff Brown519e0242010-09-15 15:18:56 -07005992 boolean abort = appWindowToken.appToken.keyDispatchingTimedOut();
Jeff Brown349703e2010-06-22 01:27:15 -07005993 if (! abort) {
5994 // The activity manager declined to abort dispatching.
5995 // Wait a bit longer and timeout again later.
Jeff Brown519e0242010-09-15 15:18:56 -07005996 return appWindowToken.inputDispatchingTimeoutNanos;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005997 }
Jeff Brown349703e2010-06-22 01:27:15 -07005998 } catch (RemoteException ex) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07005999 }
6000 }
Jeff Brownb88102f2010-09-08 11:49:43 -07006001 return 0; // abort dispatching
Jeff Brown7fbdc842010-06-17 20:52:56 -07006002 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006003
Chris Tatea32dcf72010-10-14 12:13:50 -07006004 private void addDragInputWindowLw(InputWindowList windowList) {
Christopher Tatea53146c2010-09-07 11:57:52 -07006005 final InputWindow inputWindow = windowList.add();
6006 inputWindow.inputChannel = mDragState.mServerChannel;
6007 inputWindow.name = "drag";
Christopher Tatea1595792011-01-19 17:26:50 -08006008 inputWindow.layoutParamsFlags = 0;
Christopher Tatea53146c2010-09-07 11:57:52 -07006009 inputWindow.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
6010 inputWindow.dispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
6011 inputWindow.visible = true;
6012 inputWindow.canReceiveKeys = false;
6013 inputWindow.hasFocus = true;
6014 inputWindow.hasWallpaper = false;
6015 inputWindow.paused = false;
Chris Tatea32dcf72010-10-14 12:13:50 -07006016 inputWindow.layer = mDragState.getDragLayerLw();
Christopher Tatea53146c2010-09-07 11:57:52 -07006017 inputWindow.ownerPid = Process.myPid();
6018 inputWindow.ownerUid = Process.myUid();
6019
6020 // The drag window covers the entire display
6021 inputWindow.frameLeft = 0;
6022 inputWindow.frameTop = 0;
6023 inputWindow.frameRight = mDisplay.getWidth();
6024 inputWindow.frameBottom = mDisplay.getHeight();
Christopher Tate2c095f32010-10-04 14:13:40 -07006025
Jeff Brownfbf09772011-01-16 14:06:57 -08006026 // The drag window cannot receive new touches.
6027 inputWindow.touchableRegion.setEmpty();
Christopher Tatea53146c2010-09-07 11:57:52 -07006028 }
6029
Jeff Brown3a22cd92011-01-21 13:59:04 -08006030 public void setUpdateInputWindowsNeededLw() {
6031 mUpdateInputWindowsNeeded = true;
6032 }
6033
Jeff Brown349703e2010-06-22 01:27:15 -07006034 /* Updates the cached window information provided to the input dispatcher. */
Jeff Brown2e44b072011-01-24 15:21:56 -08006035 public void updateInputWindowsLw(boolean force) {
6036 if (!force && !mUpdateInputWindowsNeeded) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08006037 return;
6038 }
6039 mUpdateInputWindowsNeeded = false;
6040
Jeff Brown349703e2010-06-22 01:27:15 -07006041 // Populate the input window list with information about all of the windows that
6042 // could potentially receive input.
6043 // As an optimization, we could try to prune the list of windows but this turns
6044 // out to be difficult because only the native code knows for sure which window
6045 // currently has touch focus.
Jeff Browne33348b2010-07-15 23:54:05 -07006046 final ArrayList<WindowState> windows = mWindows;
Christopher Tatea53146c2010-09-07 11:57:52 -07006047
6048 // If there's a drag in flight, provide a pseudowindow to catch drag input
6049 final boolean inDrag = (mDragState != null);
6050 if (inDrag) {
6051 if (DEBUG_DRAG) {
6052 Log.d(TAG, "Inserting drag window");
6053 }
Chris Tatea32dcf72010-10-14 12:13:50 -07006054 addDragInputWindowLw(mTempInputWindows);
Christopher Tatea53146c2010-09-07 11:57:52 -07006055 }
6056
Jeff Brown7fbdc842010-06-17 20:52:56 -07006057 final int N = windows.size();
Jeff Brown349703e2010-06-22 01:27:15 -07006058 for (int i = N - 1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07006059 final WindowState child = windows.get(i);
Jeff Brownc5ed5912010-07-14 18:48:53 -07006060 if (child.mInputChannel == null || child.mRemoved) {
Jeff Brown349703e2010-06-22 01:27:15 -07006061 // Skip this window because it cannot possibly receive input.
Jeff Brown7fbdc842010-06-17 20:52:56 -07006062 continue;
6063 }
6064
Jeff Brown349703e2010-06-22 01:27:15 -07006065 final int flags = child.mAttrs.flags;
6066 final int type = child.mAttrs.type;
6067
6068 final boolean hasFocus = (child == mInputFocus);
6069 final boolean isVisible = child.isVisibleLw();
6070 final boolean hasWallpaper = (child == mWallpaperTarget)
6071 && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);
Christopher Tatea53146c2010-09-07 11:57:52 -07006072
6073 // If there's a drag in progress and 'child' is a potential drop target,
6074 // make sure it's been told about the drag
6075 if (inDrag && isVisible) {
6076 mDragState.sendDragStartedIfNeededLw(child);
6077 }
6078
Jeff Brown349703e2010-06-22 01:27:15 -07006079 // Add a window to our list of input windows.
6080 final InputWindow inputWindow = mTempInputWindows.add();
Jeff Brown928e0542011-01-10 11:17:36 -08006081 inputWindow.inputWindowHandle = child.mInputWindowHandle;
Jeff Brown349703e2010-06-22 01:27:15 -07006082 inputWindow.inputChannel = child.mInputChannel;
Jeff Brown519e0242010-09-15 15:18:56 -07006083 inputWindow.name = child.toString();
Jeff Brown349703e2010-06-22 01:27:15 -07006084 inputWindow.layoutParamsFlags = flags;
6085 inputWindow.layoutParamsType = type;
6086 inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
6087 inputWindow.visible = isVisible;
Jeff Brown519e0242010-09-15 15:18:56 -07006088 inputWindow.canReceiveKeys = child.canReceiveKeys();
Jeff Brown349703e2010-06-22 01:27:15 -07006089 inputWindow.hasFocus = hasFocus;
6090 inputWindow.hasWallpaper = hasWallpaper;
6091 inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;
Jeff Brown519e0242010-09-15 15:18:56 -07006092 inputWindow.layer = child.mLayer;
Jeff Brown349703e2010-06-22 01:27:15 -07006093 inputWindow.ownerPid = child.mSession.mPid;
6094 inputWindow.ownerUid = child.mSession.mUid;
6095
6096 final Rect frame = child.mFrame;
6097 inputWindow.frameLeft = frame.left;
6098 inputWindow.frameTop = frame.top;
Jeff Brown85a31762010-09-01 17:01:00 -07006099 inputWindow.frameRight = frame.right;
6100 inputWindow.frameBottom = frame.bottom;
Jeff Brownfbf09772011-01-16 14:06:57 -08006101
6102 child.getTouchableRegion(inputWindow.touchableRegion);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006103 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07006104
Jeff Brown349703e2010-06-22 01:27:15 -07006105 // Send windows to native code.
6106 mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006107
Jeff Brown349703e2010-06-22 01:27:15 -07006108 // Clear the list in preparation for the next round.
6109 // Also avoids keeping InputChannel objects referenced unnecessarily.
6110 mTempInputWindows.clear();
6111 }
Jeff Brownb09abc12011-01-13 21:08:27 -08006112
6113 /* Notifies that the input device configuration has changed. */
6114 public void notifyConfigurationChanged() {
6115 sendNewConfiguration();
6116
6117 synchronized (mInputDevicesReadyMonitor) {
6118 if (!mInputDevicesReady) {
6119 mInputDevicesReady = true;
6120 mInputDevicesReadyMonitor.notifyAll();
6121 }
6122 }
6123 }
6124
6125 /* Waits until the built-in input devices have been configured. */
6126 public boolean waitForInputDevicesReady(long timeoutMillis) {
6127 synchronized (mInputDevicesReadyMonitor) {
6128 if (!mInputDevicesReady) {
6129 try {
6130 mInputDevicesReadyMonitor.wait(timeoutMillis);
6131 } catch (InterruptedException ex) {
6132 }
6133 }
6134 return mInputDevicesReady;
6135 }
6136 }
6137
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006138 /* Notifies that the lid switch changed state. */
6139 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
6140 mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
6141 }
6142
Jeff Brown349703e2010-06-22 01:27:15 -07006143 /* Provides an opportunity for the window manager policy to intercept early key
6144 * processing as soon as the key has been read from the device. */
Jeff Brown1f245102010-11-18 20:53:46 -08006145 public int interceptKeyBeforeQueueing(
6146 KeyEvent event, int policyFlags, boolean isScreenOn) {
6147 return mPolicy.interceptKeyBeforeQueueing(event, policyFlags, isScreenOn);
Jeff Brown349703e2010-06-22 01:27:15 -07006148 }
6149
6150 /* Provides an opportunity for the window manager policy to process a key before
6151 * ordinary dispatch. */
Jeff Brown1f245102010-11-18 20:53:46 -08006152 public boolean interceptKeyBeforeDispatching(
Jeff Brown928e0542011-01-10 11:17:36 -08006153 InputWindowHandle focus, KeyEvent event, int policyFlags) {
Jeff Brown00ae87d2011-01-13 19:58:24 -08006154 WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
Jeff Brown1f245102010-11-18 20:53:46 -08006155 return mPolicy.interceptKeyBeforeDispatching(windowState, event, policyFlags);
Jeff Brown349703e2010-06-22 01:27:15 -07006156 }
6157
Jeff Brown3915bb82010-11-05 15:02:16 -07006158 /* Provides an opportunity for the window manager policy to process a key that
6159 * the application did not handle. */
Jeff Brown49ed71d2010-12-06 17:13:33 -08006160 public KeyEvent dispatchUnhandledKey(
Jeff Brown928e0542011-01-10 11:17:36 -08006161 InputWindowHandle focus, KeyEvent event, int policyFlags) {
Jeff Brown00ae87d2011-01-13 19:58:24 -08006162 WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
Jeff Brown1f245102010-11-18 20:53:46 -08006163 return mPolicy.dispatchUnhandledKey(windowState, event, policyFlags);
Jeff Brown3915bb82010-11-05 15:02:16 -07006164 }
6165
Jeff Brown349703e2010-06-22 01:27:15 -07006166 /* Called when the current input focus changes.
6167 * Layer assignment is assumed to be complete by the time this is called.
6168 */
Jeff Brown3a22cd92011-01-21 13:59:04 -08006169 public void setInputFocusLw(WindowState newWindow, boolean updateInputWindows) {
Jeff Brown349703e2010-06-22 01:27:15 -07006170 if (DEBUG_INPUT) {
6171 Slog.d(TAG, "Input focus has changed to " + newWindow);
6172 }
6173
6174 if (newWindow != mInputFocus) {
6175 if (newWindow != null && newWindow.canReceiveKeys()) {
Jeff Brown349703e2010-06-22 01:27:15 -07006176 // Displaying a window implicitly causes dispatching to be unpaused.
6177 // This is to protect against bugs if someone pauses dispatching but
6178 // forgets to resume.
6179 newWindow.mToken.paused = false;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006180 }
Jeff Brown3a22cd92011-01-21 13:59:04 -08006181
Jeff Brown349703e2010-06-22 01:27:15 -07006182 mInputFocus = newWindow;
Jeff Brown3a22cd92011-01-21 13:59:04 -08006183 setUpdateInputWindowsNeededLw();
6184
6185 if (updateInputWindows) {
Jeff Brown2e44b072011-01-24 15:21:56 -08006186 updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08006187 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006188 }
6189 }
6190
Jeff Brown349703e2010-06-22 01:27:15 -07006191 public void setFocusedAppLw(AppWindowToken newApp) {
6192 // Focused app has changed.
6193 if (newApp == null) {
6194 mInputManager.setFocusedApplication(null);
6195 } else {
Jeff Brown928e0542011-01-10 11:17:36 -08006196 mTempInputApplication.inputApplicationHandle = newApp.mInputApplicationHandle;
Jeff Brown349703e2010-06-22 01:27:15 -07006197 mTempInputApplication.name = newApp.toString();
6198 mTempInputApplication.dispatchingTimeoutNanos =
6199 newApp.inputDispatchingTimeoutNanos;
Jeff Brown928e0542011-01-10 11:17:36 -08006200
Jeff Brown349703e2010-06-22 01:27:15 -07006201 mInputManager.setFocusedApplication(mTempInputApplication);
Jeff Brown928e0542011-01-10 11:17:36 -08006202
6203 mTempInputApplication.recycle();
Jeff Brown349703e2010-06-22 01:27:15 -07006204 }
6205 }
6206
Jeff Brown349703e2010-06-22 01:27:15 -07006207 public void pauseDispatchingLw(WindowToken window) {
6208 if (! window.paused) {
6209 if (DEBUG_INPUT) {
6210 Slog.v(TAG, "Pausing WindowToken " + window);
6211 }
6212
6213 window.paused = true;
Jeff Brown2e44b072011-01-24 15:21:56 -08006214 updateInputWindowsLw(true /*force*/);
Jeff Brown349703e2010-06-22 01:27:15 -07006215 }
6216 }
6217
6218 public void resumeDispatchingLw(WindowToken window) {
6219 if (window.paused) {
6220 if (DEBUG_INPUT) {
6221 Slog.v(TAG, "Resuming WindowToken " + window);
6222 }
6223
6224 window.paused = false;
Jeff Brown2e44b072011-01-24 15:21:56 -08006225 updateInputWindowsLw(true /*force*/);
Jeff Brown349703e2010-06-22 01:27:15 -07006226 }
6227 }
6228
6229 public void freezeInputDispatchingLw() {
6230 if (! mInputDispatchFrozen) {
6231 if (DEBUG_INPUT) {
6232 Slog.v(TAG, "Freezing input dispatching");
6233 }
6234
6235 mInputDispatchFrozen = true;
6236 updateInputDispatchModeLw();
6237 }
6238 }
6239
6240 public void thawInputDispatchingLw() {
6241 if (mInputDispatchFrozen) {
6242 if (DEBUG_INPUT) {
6243 Slog.v(TAG, "Thawing input dispatching");
6244 }
6245
6246 mInputDispatchFrozen = false;
6247 updateInputDispatchModeLw();
6248 }
6249 }
6250
6251 public void setEventDispatchingLw(boolean enabled) {
6252 if (mInputDispatchEnabled != enabled) {
6253 if (DEBUG_INPUT) {
6254 Slog.v(TAG, "Setting event dispatching to " + enabled);
6255 }
6256
6257 mInputDispatchEnabled = enabled;
6258 updateInputDispatchModeLw();
6259 }
6260 }
6261
6262 private void updateInputDispatchModeLw() {
6263 mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
6264 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006265 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006266
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006267 public void pauseKeyDispatching(IBinder _token) {
6268 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6269 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006270 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006271 }
6272
6273 synchronized (mWindowMap) {
6274 WindowToken token = mTokenMap.get(_token);
6275 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006276 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006277 }
6278 }
6279 }
6280
6281 public void resumeKeyDispatching(IBinder _token) {
6282 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6283 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006284 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006285 }
6286
6287 synchronized (mWindowMap) {
6288 WindowToken token = mTokenMap.get(_token);
6289 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006290 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006291 }
6292 }
6293 }
6294
6295 public void setEventDispatching(boolean enabled) {
6296 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6297 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006298 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006299 }
6300
6301 synchronized (mWindowMap) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006302 mInputMonitor.setEventDispatchingLw(enabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006303 }
6304 }
Romain Guy06882f82009-06-10 13:36:04 -07006305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006306 /**
6307 * Injects a keystroke event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07006308 * Even when sync is false, this method may block while waiting for current
6309 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07006310 *
6311 * @param ev A motion event describing the keystroke action. (Be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006312 * {@link SystemClock#uptimeMillis()} as the timebase.)
6313 * @param sync If true, wait for the event to be completed before returning to the caller.
6314 * @return Returns true if event was dispatched, false if it was dropped for any reason
6315 */
6316 public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
6317 long downTime = ev.getDownTime();
6318 long eventTime = ev.getEventTime();
6319
6320 int action = ev.getAction();
6321 int code = ev.getKeyCode();
6322 int repeatCount = ev.getRepeatCount();
6323 int metaState = ev.getMetaState();
6324 int deviceId = ev.getDeviceId();
6325 int scancode = ev.getScanCode();
Jeff Brownc5ed5912010-07-14 18:48:53 -07006326 int source = ev.getSource();
Mike Playlec6ded102010-11-29 16:01:03 +00006327 int flags = ev.getFlags();
Jeff Brownc5ed5912010-07-14 18:48:53 -07006328
6329 if (source == InputDevice.SOURCE_UNKNOWN) {
6330 source = InputDevice.SOURCE_KEYBOARD;
6331 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006332
6333 if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
6334 if (downTime == 0) downTime = eventTime;
6335
6336 KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
Jean-Baptiste Queru4a880132010-12-02 15:16:53 -08006337 deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006338
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006339 final int pid = Binder.getCallingPid();
6340 final int uid = Binder.getCallingUid();
6341 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006342
Jeff Brownbbda99d2010-07-28 15:48:59 -07006343 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
6344 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
6345 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
6346 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006347
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006348 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006349 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006350 }
6351
6352 /**
6353 * Inject a pointer (touch) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07006354 * Even when sync is false, this method may block while waiting for current
6355 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07006356 *
6357 * @param ev A motion event describing the pointer (touch) action. (As noted in
6358 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006359 * {@link SystemClock#uptimeMillis()} as the timebase.)
6360 * @param sync If true, wait for the event to be completed before returning to the caller.
6361 * @return Returns true if event was dispatched, false if it was dropped for any reason
6362 */
6363 public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006364 final int pid = Binder.getCallingPid();
6365 final int uid = Binder.getCallingUid();
6366 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006367
Jeff Brownc5ed5912010-07-14 18:48:53 -07006368 MotionEvent newEvent = MotionEvent.obtain(ev);
6369 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
6370 newEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
6371 }
6372
Jeff Brownbbda99d2010-07-28 15:48:59 -07006373 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
6374 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
6375 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
6376 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006377
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006378 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006379 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006380 }
Romain Guy06882f82009-06-10 13:36:04 -07006381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006382 /**
6383 * Inject a trackball (navigation device) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07006384 * Even when sync is false, this method may block while waiting for current
6385 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07006386 *
6387 * @param ev A motion event describing the trackball action. (As noted in
6388 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006389 * {@link SystemClock#uptimeMillis()} as the timebase.)
6390 * @param sync If true, wait for the event to be completed before returning to the caller.
6391 * @return Returns true if event was dispatched, false if it was dropped for any reason
6392 */
6393 public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006394 final int pid = Binder.getCallingPid();
6395 final int uid = Binder.getCallingUid();
6396 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006397
Jeff Brownc5ed5912010-07-14 18:48:53 -07006398 MotionEvent newEvent = MotionEvent.obtain(ev);
6399 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
6400 newEvent.setSource(InputDevice.SOURCE_TRACKBALL);
6401 }
6402
Jeff Brownbbda99d2010-07-28 15:48:59 -07006403 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
6404 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
6405 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
6406 INJECTION_TIMEOUT_MILLIS);
6407
6408 Binder.restoreCallingIdentity(ident);
6409 return reportInjectionResult(result);
6410 }
6411
6412 /**
6413 * Inject an input event into the UI without waiting for dispatch to commence.
6414 * This variant is useful for fire-and-forget input event injection. It does not
6415 * block any longer than it takes to enqueue the input event.
6416 *
6417 * @param ev An input event. (Be sure to set the input source correctly.)
6418 * @return Returns true if event was dispatched, false if it was dropped for any reason
6419 */
6420 public boolean injectInputEventNoWait(InputEvent ev) {
6421 final int pid = Binder.getCallingPid();
6422 final int uid = Binder.getCallingUid();
6423 final long ident = Binder.clearCallingIdentity();
6424
6425 final int result = mInputManager.injectInputEvent(ev, pid, uid,
6426 InputManager.INPUT_EVENT_INJECTION_SYNC_NONE,
6427 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006428
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006429 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006430 return reportInjectionResult(result);
6431 }
6432
6433 private boolean reportInjectionResult(int result) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006434 switch (result) {
6435 case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
6436 Slog.w(TAG, "Input event injection permission denied.");
6437 throw new SecurityException(
6438 "Injecting to another application requires INJECT_EVENTS permission");
6439 case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
Christopher Tate09e85dc2010-08-02 11:54:41 -07006440 //Slog.v(TAG, "Input event injection succeeded.");
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006441 return true;
6442 case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
6443 Slog.w(TAG, "Input event injection timed out.");
6444 return false;
6445 case InputManager.INPUT_EVENT_INJECTION_FAILED:
6446 default:
6447 Slog.w(TAG, "Input event injection failed.");
6448 return false;
Dianne Hackborncfaef692009-06-15 14:24:44 -07006449 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006450 }
Romain Guy06882f82009-06-10 13:36:04 -07006451
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006452 private WindowState getFocusedWindow() {
6453 synchronized (mWindowMap) {
6454 return getFocusedWindowLocked();
6455 }
6456 }
6457
6458 private WindowState getFocusedWindowLocked() {
6459 return mCurrentFocus;
6460 }
Romain Guy06882f82009-06-10 13:36:04 -07006461
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006462 public boolean detectSafeMode() {
Jeff Brownb09abc12011-01-13 21:08:27 -08006463 if (!mInputMonitor.waitForInputDevicesReady(
6464 INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
6465 Slog.w(TAG, "Devices still not ready after waiting "
6466 + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
6467 + " milliseconds before attempting to detect safe mode.");
6468 }
6469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006470 mSafeMode = mPolicy.detectSafeMode();
6471 return mSafeMode;
6472 }
Romain Guy06882f82009-06-10 13:36:04 -07006473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006474 public void systemReady() {
Dianne Hackborn5132b372010-07-29 12:51:35 -07006475 synchronized(mWindowMap) {
6476 if (mDisplay != null) {
6477 throw new IllegalStateException("Display already initialized");
6478 }
6479 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
6480 mDisplay = wm.getDefaultDisplay();
6481 mInitialDisplayWidth = mDisplay.getWidth();
6482 mInitialDisplayHeight = mDisplay.getHeight();
Dianne Hackborn4c7cc342010-12-16 16:37:39 -08006483 mInputManager.setDisplaySize(0, Display.unmapDisplaySize(mInitialDisplayWidth),
6484 Display.unmapDisplaySize(mInitialDisplayHeight));
Dianne Hackborn5132b372010-07-29 12:51:35 -07006485 }
6486
6487 try {
6488 mActivityManager.updateConfiguration(null);
6489 } catch (RemoteException e) {
6490 }
Dianne Hackborn154db5f2010-07-29 19:15:19 -07006491
6492 mPolicy.systemReady();
Dianne Hackborn5132b372010-07-29 12:51:35 -07006493 }
6494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006495 // -------------------------------------------------------------
6496 // Client Session State
6497 // -------------------------------------------------------------
6498
6499 private final class Session extends IWindowSession.Stub
6500 implements IBinder.DeathRecipient {
6501 final IInputMethodClient mClient;
6502 final IInputContext mInputContext;
6503 final int mUid;
6504 final int mPid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006505 final String mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006506 SurfaceSession mSurfaceSession;
6507 int mNumWindow = 0;
6508 boolean mClientDead = false;
Romain Guy06882f82009-06-10 13:36:04 -07006509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006510 public Session(IInputMethodClient client, IInputContext inputContext) {
6511 mClient = client;
6512 mInputContext = inputContext;
6513 mUid = Binder.getCallingUid();
6514 mPid = Binder.getCallingPid();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006515 StringBuilder sb = new StringBuilder();
6516 sb.append("Session{");
6517 sb.append(Integer.toHexString(System.identityHashCode(this)));
6518 sb.append(" uid ");
6519 sb.append(mUid);
6520 sb.append("}");
6521 mStringName = sb.toString();
Romain Guy06882f82009-06-10 13:36:04 -07006522
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006523 synchronized (mWindowMap) {
6524 if (mInputMethodManager == null && mHaveInputMethods) {
6525 IBinder b = ServiceManager.getService(
6526 Context.INPUT_METHOD_SERVICE);
6527 mInputMethodManager = IInputMethodManager.Stub.asInterface(b);
6528 }
6529 }
6530 long ident = Binder.clearCallingIdentity();
6531 try {
6532 // Note: it is safe to call in to the input method manager
6533 // here because we are not holding our lock.
6534 if (mInputMethodManager != null) {
6535 mInputMethodManager.addClient(client, inputContext,
6536 mUid, mPid);
6537 } else {
6538 client.setUsingInputMethod(false);
6539 }
6540 client.asBinder().linkToDeath(this, 0);
6541 } catch (RemoteException e) {
6542 // The caller has died, so we can just forget about this.
6543 try {
6544 if (mInputMethodManager != null) {
6545 mInputMethodManager.removeClient(client);
6546 }
6547 } catch (RemoteException ee) {
6548 }
6549 } finally {
6550 Binder.restoreCallingIdentity(ident);
6551 }
6552 }
Romain Guy06882f82009-06-10 13:36:04 -07006553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006554 @Override
6555 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
6556 throws RemoteException {
6557 try {
6558 return super.onTransact(code, data, reply, flags);
6559 } catch (RuntimeException e) {
6560 // Log all 'real' exceptions thrown to the caller
6561 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006562 Slog.e(TAG, "Window Session Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006563 }
6564 throw e;
6565 }
6566 }
6567
6568 public void binderDied() {
6569 // Note: it is safe to call in to the input method manager
6570 // here because we are not holding our lock.
6571 try {
6572 if (mInputMethodManager != null) {
6573 mInputMethodManager.removeClient(mClient);
6574 }
6575 } catch (RemoteException e) {
6576 }
6577 synchronized(mWindowMap) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07006578 mClient.asBinder().unlinkToDeath(this, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006579 mClientDead = true;
6580 killSessionLocked();
6581 }
6582 }
6583
6584 public int add(IWindow window, WindowManager.LayoutParams attrs,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006585 int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
6586 return addWindow(this, window, attrs, viewVisibility, outContentInsets,
6587 outInputChannel);
6588 }
6589
6590 public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006591 int viewVisibility, Rect outContentInsets) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006592 return addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006593 }
Romain Guy06882f82009-06-10 13:36:04 -07006594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006595 public void remove(IWindow window) {
6596 removeWindow(this, window);
6597 }
Romain Guy06882f82009-06-10 13:36:04 -07006598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006599 public int relayout(IWindow window, WindowManager.LayoutParams attrs,
6600 int requestedWidth, int requestedHeight, int viewFlags,
6601 boolean insetsPending, Rect outFrame, Rect outContentInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07006602 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
Dianne Hackbornf123e492010-09-24 11:16:23 -07006603 //Log.d(TAG, ">>>>>> ENTERED relayout from " + Binder.getCallingPid());
6604 int res = relayoutWindow(this, window, attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006605 requestedWidth, requestedHeight, viewFlags, insetsPending,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07006606 outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
Dianne Hackbornf123e492010-09-24 11:16:23 -07006607 //Log.d(TAG, "<<<<<< EXITING relayout to " + Binder.getCallingPid());
6608 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006609 }
Romain Guy06882f82009-06-10 13:36:04 -07006610
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006611 public void setTransparentRegion(IWindow window, Region region) {
6612 setTransparentRegionWindow(this, window, region);
6613 }
Romain Guy06882f82009-06-10 13:36:04 -07006614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006615 public void setInsets(IWindow window, int touchableInsets,
Jeff Brownfbf09772011-01-16 14:06:57 -08006616 Rect contentInsets, Rect visibleInsets, Region touchableArea) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006617 setInsetsWindow(this, window, touchableInsets, contentInsets,
Jeff Brownfbf09772011-01-16 14:06:57 -08006618 visibleInsets, touchableArea);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006619 }
Romain Guy06882f82009-06-10 13:36:04 -07006620
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006621 public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
6622 getWindowDisplayFrame(this, window, outDisplayFrame);
6623 }
Romain Guy06882f82009-06-10 13:36:04 -07006624
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006625 public void finishDrawing(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006626 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006627 TAG, "IWindow finishDrawing called for " + window);
6628 finishDrawingWindow(this, window);
6629 }
6630
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006631 public void setInTouchMode(boolean mode) {
6632 synchronized(mWindowMap) {
6633 mInTouchMode = mode;
6634 }
6635 }
6636
6637 public boolean getInTouchMode() {
6638 synchronized(mWindowMap) {
6639 return mInTouchMode;
6640 }
6641 }
6642
6643 public boolean performHapticFeedback(IWindow window, int effectId,
6644 boolean always) {
6645 synchronized(mWindowMap) {
6646 long ident = Binder.clearCallingIdentity();
6647 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07006648 return mPolicy.performHapticFeedbackLw(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006649 windowForClientLocked(this, window, true),
6650 effectId, always);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006651 } finally {
6652 Binder.restoreCallingIdentity(ident);
6653 }
6654 }
6655 }
Romain Guy06882f82009-06-10 13:36:04 -07006656
Christopher Tatea53146c2010-09-07 11:57:52 -07006657 /* Drag/drop */
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006658 public IBinder prepareDrag(IWindow window, int flags,
Christopher Tatea53146c2010-09-07 11:57:52 -07006659 int width, int height, Surface outSurface) {
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006660 return prepareDragSurface(window, mSurfaceSession, flags,
Christopher Tatea53146c2010-09-07 11:57:52 -07006661 width, height, outSurface);
6662 }
6663
6664 public boolean performDrag(IWindow window, IBinder dragToken,
6665 float touchX, float touchY, float thumbCenterX, float thumbCenterY,
6666 ClipData data) {
6667 if (DEBUG_DRAG) {
6668 Slog.d(TAG, "perform drag: win=" + window + " data=" + data);
6669 }
6670
6671 synchronized (mWindowMap) {
6672 if (mDragState == null) {
6673 Slog.w(TAG, "No drag prepared");
6674 throw new IllegalStateException("performDrag() without prepareDrag()");
6675 }
6676
6677 if (dragToken != mDragState.mToken) {
6678 Slog.w(TAG, "Performing mismatched drag");
6679 throw new IllegalStateException("performDrag() does not match prepareDrag()");
6680 }
6681
6682 WindowState callingWin = windowForClientLocked(null, window, false);
6683 if (callingWin == null) {
6684 Slog.w(TAG, "Bad requesting window " + window);
6685 return false; // !!! TODO: throw here?
6686 }
6687
6688 // !!! TODO: if input is not still focused on the initiating window, fail
6689 // the drag initiation (e.g. an alarm window popped up just as the application
6690 // called performDrag()
6691
6692 mH.removeMessages(H.DRAG_START_TIMEOUT, window.asBinder());
6693
Christopher Tate2c095f32010-10-04 14:13:40 -07006694 // !!! TODO: extract the current touch (x, y) in screen coordinates. That
6695 // will let us eliminate the (touchX,touchY) parameters from the API.
Christopher Tatea53146c2010-09-07 11:57:52 -07006696
Chris Tateb478f462010-10-15 16:02:26 -07006697 // !!! FIXME: put all this heavy stuff onto the mH looper, as well as
6698 // the actual drag event dispatch stuff in the dragstate
6699
Christopher Tatea53146c2010-09-07 11:57:52 -07006700 mDragState.register();
Jeff Brown2e44b072011-01-24 15:21:56 -08006701 mInputMonitor.updateInputWindowsLw(true /*force*/);
Chris Tateef70a072010-10-22 19:10:34 -07006702 if (!mInputManager.transferTouchFocus(callingWin.mInputChannel,
6703 mDragState.mServerChannel)) {
6704 Slog.e(TAG, "Unable to transfer touch focus");
6705 mDragState.unregister();
6706 mDragState = null;
Jeff Brown2e44b072011-01-24 15:21:56 -08006707 mInputMonitor.updateInputWindowsLw(true /*force*/);
Chris Tateef70a072010-10-22 19:10:34 -07006708 return false;
6709 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006710
6711 mDragState.mData = data;
Chris Tateb478f462010-10-15 16:02:26 -07006712 mDragState.mCurrentX = touchX;
6713 mDragState.mCurrentY = touchY;
Chris Tateb8203e92010-10-12 14:23:21 -07006714 mDragState.broadcastDragStartedLw(touchX, touchY);
Christopher Tatea53146c2010-09-07 11:57:52 -07006715
6716 // remember the thumb offsets for later
6717 mDragState.mThumbOffsetX = thumbCenterX;
6718 mDragState.mThumbOffsetY = thumbCenterY;
6719
6720 // Make the surface visible at the proper location
6721 final Surface surface = mDragState.mSurface;
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006722 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION performDrag");
Chris Tateb478f462010-10-15 16:02:26 -07006723 Surface.openTransaction();
Christopher Tatea53146c2010-09-07 11:57:52 -07006724 try {
6725 surface.setPosition((int)(touchX - thumbCenterX),
6726 (int)(touchY - thumbCenterY));
Chris Tateb478f462010-10-15 16:02:26 -07006727 surface.setAlpha(.7071f);
Chris Tatea32dcf72010-10-14 12:13:50 -07006728 surface.setLayer(mDragState.getDragLayerLw());
Christopher Tatea53146c2010-09-07 11:57:52 -07006729 surface.show();
6730 } finally {
Chris Tateb478f462010-10-15 16:02:26 -07006731 Surface.closeTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006732 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION performDrag");
Christopher Tatea53146c2010-09-07 11:57:52 -07006733 }
6734 }
6735
6736 return true; // success!
6737 }
6738
Chris Tated4533f142010-10-19 15:15:08 -07006739 public void reportDropResult(IWindow window, boolean consumed) {
6740 IBinder token = window.asBinder();
6741 if (DEBUG_DRAG) {
6742 Slog.d(TAG, "Drop result=" + consumed + " reported by " + token);
6743 }
6744
6745 synchronized (mWindowMap) {
Christopher Tateccd24de2011-01-12 15:02:55 -08006746 long ident = Binder.clearCallingIdentity();
6747 try {
Jeff Brownfbf09772011-01-16 14:06:57 -08006748 if (mDragState == null || mDragState.mToken != token) {
Christopher Tateccd24de2011-01-12 15:02:55 -08006749 Slog.w(TAG, "Invalid drop-result claim by " + window);
6750 throw new IllegalStateException("reportDropResult() by non-recipient");
6751 }
6752
6753 // The right window has responded, even if it's no longer around,
6754 // so be sure to halt the timeout even if the later WindowState
6755 // lookup fails.
6756 mH.removeMessages(H.DRAG_END_TIMEOUT, window.asBinder());
6757 WindowState callingWin = windowForClientLocked(null, window, false);
6758 if (callingWin == null) {
6759 Slog.w(TAG, "Bad result-reporting window " + window);
6760 return; // !!! TODO: throw here?
6761 }
6762
6763 mDragState.mDragResult = consumed;
6764 mDragState.endDragLw();
6765 } finally {
6766 Binder.restoreCallingIdentity(ident);
Chris Tated4533f142010-10-19 15:15:08 -07006767 }
Chris Tated4533f142010-10-19 15:15:08 -07006768 }
6769 }
6770
Christopher Tatea53146c2010-09-07 11:57:52 -07006771 public void dragRecipientEntered(IWindow window) {
6772 if (DEBUG_DRAG) {
Chris Tated4533f142010-10-19 15:15:08 -07006773 Slog.d(TAG, "Drag into new candidate view @ " + window.asBinder());
Christopher Tatea53146c2010-09-07 11:57:52 -07006774 }
6775 }
6776
6777 public void dragRecipientExited(IWindow window) {
6778 if (DEBUG_DRAG) {
Chris Tated4533f142010-10-19 15:15:08 -07006779 Slog.d(TAG, "Drag from old candidate view @ " + window.asBinder());
Christopher Tatea53146c2010-09-07 11:57:52 -07006780 }
6781 }
6782
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006783 public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006784 synchronized(mWindowMap) {
6785 long ident = Binder.clearCallingIdentity();
6786 try {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006787 setWindowWallpaperPositionLocked(
6788 windowForClientLocked(this, window, true),
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006789 x, y, xStep, yStep);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006790 } finally {
6791 Binder.restoreCallingIdentity(ident);
6792 }
6793 }
6794 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006795
Dianne Hackborn19382ac2009-09-11 21:13:37 -07006796 public void wallpaperOffsetsComplete(IBinder window) {
6797 WindowManagerService.this.wallpaperOffsetsComplete(window);
6798 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006799
Dianne Hackborn75804932009-10-20 20:15:20 -07006800 public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
6801 int z, Bundle extras, boolean sync) {
6802 synchronized(mWindowMap) {
6803 long ident = Binder.clearCallingIdentity();
6804 try {
6805 return sendWindowWallpaperCommandLocked(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006806 windowForClientLocked(this, window, true),
Dianne Hackborn75804932009-10-20 20:15:20 -07006807 action, x, y, z, extras, sync);
6808 } finally {
6809 Binder.restoreCallingIdentity(ident);
6810 }
6811 }
6812 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006813
Dianne Hackborn75804932009-10-20 20:15:20 -07006814 public void wallpaperCommandComplete(IBinder window, Bundle result) {
6815 WindowManagerService.this.wallpaperCommandComplete(window, result);
6816 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006817
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006818 void windowAddedLocked() {
6819 if (mSurfaceSession == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006820 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006821 TAG, "First window added to " + this + ", creating SurfaceSession");
6822 mSurfaceSession = new SurfaceSession();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006823 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006824 TAG, " NEW SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006825 mSessions.add(this);
6826 }
6827 mNumWindow++;
6828 }
6829
6830 void windowRemovedLocked() {
6831 mNumWindow--;
6832 killSessionLocked();
6833 }
Romain Guy06882f82009-06-10 13:36:04 -07006834
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006835 void killSessionLocked() {
6836 if (mNumWindow <= 0 && mClientDead) {
6837 mSessions.remove(this);
6838 if (mSurfaceSession != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006839 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006840 TAG, "Last window removed from " + this
6841 + ", destroying " + mSurfaceSession);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006842 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006843 TAG, " KILL SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006844 try {
6845 mSurfaceSession.kill();
6846 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006847 Slog.w(TAG, "Exception thrown when killing surface session "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006848 + mSurfaceSession + " in session " + this
6849 + ": " + e.toString());
6850 }
6851 mSurfaceSession = null;
6852 }
6853 }
6854 }
Romain Guy06882f82009-06-10 13:36:04 -07006855
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006856 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006857 pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
6858 pw.print(" mClientDead="); pw.print(mClientDead);
6859 pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006860 }
6861
6862 @Override
6863 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006864 return mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006865 }
6866 }
6867
6868 // -------------------------------------------------------------
6869 // Client Window State
6870 // -------------------------------------------------------------
6871
6872 private final class WindowState implements WindowManagerPolicy.WindowState {
6873 final Session mSession;
6874 final IWindow mClient;
6875 WindowToken mToken;
The Android Open Source Project10592532009-03-18 17:39:46 -07006876 WindowToken mRootToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006877 AppWindowToken mAppToken;
6878 AppWindowToken mTargetAppToken;
6879 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
6880 final DeathRecipient mDeathRecipient;
6881 final WindowState mAttachedWindow;
Jeff Browne33348b2010-07-15 23:54:05 -07006882 final ArrayList<WindowState> mChildWindows = new ArrayList<WindowState>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006883 final int mBaseLayer;
6884 final int mSubLayer;
6885 final boolean mLayoutAttached;
6886 final boolean mIsImWindow;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006887 final boolean mIsWallpaper;
6888 final boolean mIsFloatingLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006889 int mViewVisibility;
6890 boolean mPolicyVisibility = true;
6891 boolean mPolicyVisibilityAfterAnim = true;
6892 boolean mAppFreezing;
6893 Surface mSurface;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006894 boolean mReportDestroySurface;
6895 boolean mSurfacePendingDestroy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006896 boolean mAttachedHidden; // is our parent window hidden?
6897 boolean mLastHidden; // was this window last hidden?
Dianne Hackborn759a39e2009-08-09 17:20:27 -07006898 boolean mWallpaperVisible; // for wallpaper, what was last vis report?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006899 int mRequestedWidth;
6900 int mRequestedHeight;
6901 int mLastRequestedWidth;
6902 int mLastRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006903 int mLayer;
6904 int mAnimLayer;
6905 int mLastLayer;
6906 boolean mHaveFrame;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07006907 boolean mObscured;
Dianne Hackborn93e462b2009-09-15 22:50:40 -07006908 boolean mTurnOnScreen;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006909
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006910 int mLayoutSeq = -1;
6911
6912 Configuration mConfiguration = null;
6913
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006914 // Actual frame shown on-screen (may be modified by animation)
6915 final Rect mShownFrame = new Rect();
6916 final Rect mLastShownFrame = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006917
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006918 /**
Dianne Hackbornac3587d2010-03-11 11:12:11 -08006919 * Set when we have changed the size of the surface, to know that
6920 * we must tell them application to resize (and thus redraw itself).
6921 */
6922 boolean mSurfaceResized;
6923
6924 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006925 * Insets that determine the actually visible area
6926 */
6927 final Rect mVisibleInsets = new Rect();
6928 final Rect mLastVisibleInsets = new Rect();
6929 boolean mVisibleInsetsChanged;
6930
6931 /**
6932 * Insets that are covered by system windows
6933 */
6934 final Rect mContentInsets = new Rect();
6935 final Rect mLastContentInsets = new Rect();
6936 boolean mContentInsetsChanged;
6937
6938 /**
6939 * Set to true if we are waiting for this window to receive its
6940 * given internal insets before laying out other windows based on it.
6941 */
6942 boolean mGivenInsetsPending;
Romain Guy06882f82009-06-10 13:36:04 -07006943
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006944 /**
6945 * These are the content insets that were given during layout for
6946 * this window, to be applied to windows behind it.
6947 */
6948 final Rect mGivenContentInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006949
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006950 /**
6951 * These are the visible insets that were given during layout for
6952 * this window, to be applied to windows behind it.
6953 */
6954 final Rect mGivenVisibleInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006955
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006956 /**
Jeff Brownfbf09772011-01-16 14:06:57 -08006957 * This is the given touchable area relative to the window frame, or null if none.
6958 */
6959 final Region mGivenTouchableRegion = new Region();
6960
6961 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006962 * Flag indicating whether the touchable region should be adjusted by
6963 * the visible insets; if false the area outside the visible insets is
6964 * NOT touchable, so we must use those to adjust the frame during hit
6965 * tests.
6966 */
6967 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
Romain Guy06882f82009-06-10 13:36:04 -07006968
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006969 // Current transformation being applied.
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08006970 boolean mHaveMatrix;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006971 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
6972 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
6973 float mHScale=1, mVScale=1;
6974 float mLastHScale=1, mLastVScale=1;
6975 final Matrix mTmpMatrix = new Matrix();
6976
6977 // "Real" frame that the application sees.
6978 final Rect mFrame = new Rect();
6979 final Rect mLastFrame = new Rect();
6980
6981 final Rect mContainingFrame = new Rect();
6982 final Rect mDisplayFrame = new Rect();
6983 final Rect mContentFrame = new Rect();
Dianne Hackborn1c24e952010-11-23 00:34:30 -08006984 final Rect mParentFrame = new Rect();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006985 final Rect mVisibleFrame = new Rect();
6986
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08006987 boolean mContentChanged;
6988
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006989 float mShownAlpha = 1;
6990 float mAlpha = 1;
6991 float mLastAlpha = 1;
6992
6993 // Set to true if, when the window gets displayed, it should perform
6994 // an enter animation.
6995 boolean mEnterAnimationPending;
6996
6997 // Currently running animation.
6998 boolean mAnimating;
6999 boolean mLocalAnimating;
7000 Animation mAnimation;
7001 boolean mAnimationIsEntrance;
7002 boolean mHasTransformation;
7003 boolean mHasLocalTransformation;
7004 final Transformation mTransformation = new Transformation();
7005
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07007006 // If a window showing a wallpaper: the requested offset for the
7007 // wallpaper; if a wallpaper window: the currently applied offset.
7008 float mWallpaperX = -1;
7009 float mWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08007010
7011 // If a window showing a wallpaper: what fraction of the offset
7012 // range corresponds to a full virtual screen.
7013 float mWallpaperXStep = -1;
7014 float mWallpaperYStep = -1;
7015
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07007016 // Wallpaper windows: pixels offset based on above variables.
7017 int mXOffset;
7018 int mYOffset;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007019
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007020 // This is set after IWindowSession.relayout() has been called at
7021 // least once for the window. It allows us to detect the situation
7022 // where we don't yet have a surface, but should have one soon, so
7023 // we can give the window focus before waiting for the relayout.
7024 boolean mRelayoutCalled;
Romain Guy06882f82009-06-10 13:36:04 -07007025
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007026 // This is set after the Surface has been created but before the
7027 // window has been drawn. During this time the surface is hidden.
7028 boolean mDrawPending;
7029
7030 // This is set after the window has finished drawing for the first
7031 // time but before its surface is shown. The surface will be
7032 // displayed when the next layout is run.
7033 boolean mCommitDrawPending;
7034
7035 // This is set during the time after the window's drawing has been
7036 // committed, and before its surface is actually shown. It is used
7037 // to delay showing the surface until all windows in a token are ready
7038 // to be shown.
7039 boolean mReadyToShow;
Romain Guy06882f82009-06-10 13:36:04 -07007040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007041 // Set when the window has been shown in the screen the first time.
7042 boolean mHasDrawn;
7043
7044 // Currently running an exit animation?
7045 boolean mExiting;
7046
7047 // Currently on the mDestroySurface list?
7048 boolean mDestroying;
Romain Guy06882f82009-06-10 13:36:04 -07007049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007050 // Completely remove from window manager after exit animation?
7051 boolean mRemoveOnExit;
7052
7053 // Set when the orientation is changing and this window has not yet
7054 // been updated for the new orientation.
7055 boolean mOrientationChanging;
Romain Guy06882f82009-06-10 13:36:04 -07007056
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007057 // Is this window now (or just being) removed?
7058 boolean mRemoved;
Romain Guy06882f82009-06-10 13:36:04 -07007059
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007060 // Temp for keeping track of windows that have been removed when
7061 // rebuilding window list.
7062 boolean mRebuilding;
7063
Dianne Hackborn16064f92010-03-25 00:47:24 -07007064 // For debugging, this is the last information given to the surface flinger.
7065 boolean mSurfaceShown;
7066 int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
7067 int mSurfaceLayer;
7068 float mSurfaceAlpha;
7069
Jeff Brown928e0542011-01-10 11:17:36 -08007070 // Input channel and input window handle used by the input dispatcher.
7071 InputWindowHandle mInputWindowHandle;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007072 InputChannel mInputChannel;
7073
Mattias Petersson1622eee2010-12-21 10:15:11 +01007074 // Used to improve performance of toString()
7075 String mStringNameCache;
7076 CharSequence mLastTitle;
7077 boolean mWasPaused;
7078
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007079 WindowState(Session s, IWindow c, WindowToken token,
7080 WindowState attachedWindow, WindowManager.LayoutParams a,
7081 int viewVisibility) {
7082 mSession = s;
7083 mClient = c;
7084 mToken = token;
7085 mAttrs.copyFrom(a);
7086 mViewVisibility = viewVisibility;
7087 DeathRecipient deathRecipient = new DeathRecipient();
7088 mAlpha = a.alpha;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007089 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007090 TAG, "Window " + this + " client=" + c.asBinder()
7091 + " token=" + token + " (" + mAttrs.token + ")");
7092 try {
7093 c.asBinder().linkToDeath(deathRecipient, 0);
7094 } catch (RemoteException e) {
7095 mDeathRecipient = null;
7096 mAttachedWindow = null;
7097 mLayoutAttached = false;
7098 mIsImWindow = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007099 mIsWallpaper = false;
7100 mIsFloatingLayer = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007101 mBaseLayer = 0;
7102 mSubLayer = 0;
7103 return;
7104 }
7105 mDeathRecipient = deathRecipient;
Romain Guy06882f82009-06-10 13:36:04 -07007106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007107 if ((mAttrs.type >= FIRST_SUB_WINDOW &&
7108 mAttrs.type <= LAST_SUB_WINDOW)) {
7109 // The multiplier here is to reserve space for multiple
7110 // windows in the same type layer.
7111 mBaseLayer = mPolicy.windowTypeToLayerLw(
7112 attachedWindow.mAttrs.type) * TYPE_LAYER_MULTIPLIER
7113 + TYPE_LAYER_OFFSET;
7114 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
7115 mAttachedWindow = attachedWindow;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007116 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + mAttachedWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007117 mAttachedWindow.mChildWindows.add(this);
7118 mLayoutAttached = mAttrs.type !=
7119 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
7120 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
7121 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007122 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
7123 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007124 } else {
7125 // The multiplier here is to reserve space for multiple
7126 // windows in the same type layer.
7127 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
7128 * TYPE_LAYER_MULTIPLIER
7129 + TYPE_LAYER_OFFSET;
7130 mSubLayer = 0;
7131 mAttachedWindow = null;
7132 mLayoutAttached = false;
7133 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
7134 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007135 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
7136 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007137 }
7138
7139 WindowState appWin = this;
7140 while (appWin.mAttachedWindow != null) {
7141 appWin = mAttachedWindow;
7142 }
7143 WindowToken appToken = appWin.mToken;
7144 while (appToken.appWindowToken == null) {
7145 WindowToken parent = mTokenMap.get(appToken.token);
7146 if (parent == null || appToken == parent) {
7147 break;
7148 }
7149 appToken = parent;
7150 }
The Android Open Source Project10592532009-03-18 17:39:46 -07007151 mRootToken = appToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007152 mAppToken = appToken.appWindowToken;
7153
7154 mSurface = null;
7155 mRequestedWidth = 0;
7156 mRequestedHeight = 0;
7157 mLastRequestedWidth = 0;
7158 mLastRequestedHeight = 0;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007159 mXOffset = 0;
7160 mYOffset = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007161 mLayer = 0;
7162 mAnimLayer = 0;
7163 mLastLayer = 0;
Jeff Brown928e0542011-01-10 11:17:36 -08007164 mInputWindowHandle = new InputWindowHandle(
7165 mAppToken != null ? mAppToken.mInputApplicationHandle : null, this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007166 }
7167
7168 void attach() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007169 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007170 TAG, "Attaching " + this + " token=" + mToken
7171 + ", list=" + mToken.windows);
7172 mSession.windowAddedLocked();
7173 }
7174
7175 public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
7176 mHaveFrame = true;
7177
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007178 final Rect container = mContainingFrame;
7179 container.set(pf);
7180
7181 final Rect display = mDisplayFrame;
7182 display.set(df);
7183
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007184 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007185 container.intersect(mCompatibleScreenFrame);
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007186 if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
7187 display.intersect(mCompatibleScreenFrame);
7188 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007189 }
7190
7191 final int pw = container.right - container.left;
7192 final int ph = container.bottom - container.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007193
7194 int w,h;
7195 if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
7196 w = mAttrs.width < 0 ? pw : mAttrs.width;
7197 h = mAttrs.height< 0 ? ph : mAttrs.height;
7198 } else {
Romain Guy980a9382010-01-08 15:06:28 -08007199 w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
7200 h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007201 }
Romain Guy06882f82009-06-10 13:36:04 -07007202
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007203 if (!mParentFrame.equals(pf)) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08007204 //Slog.i(TAG, "Window " + this + " content frame from " + mParentFrame
7205 // + " to " + pf);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007206 mParentFrame.set(pf);
7207 mContentChanged = true;
7208 }
7209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007210 final Rect content = mContentFrame;
7211 content.set(cf);
Romain Guy06882f82009-06-10 13:36:04 -07007212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007213 final Rect visible = mVisibleFrame;
7214 visible.set(vf);
Romain Guy06882f82009-06-10 13:36:04 -07007215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007216 final Rect frame = mFrame;
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07007217 final int fw = frame.width();
7218 final int fh = frame.height();
Romain Guy06882f82009-06-10 13:36:04 -07007219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007220 //System.out.println("In: w=" + w + " h=" + h + " container=" +
7221 // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
7222
7223 Gravity.apply(mAttrs.gravity, w, h, container,
7224 (int) (mAttrs.x + mAttrs.horizontalMargin * pw),
7225 (int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
7226
7227 //System.out.println("Out: " + mFrame);
7228
7229 // Now make sure the window fits in the overall display.
7230 Gravity.applyDisplay(mAttrs.gravity, df, frame);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007231
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007232 // Make sure the content and visible frames are inside of the
7233 // final window frame.
7234 if (content.left < frame.left) content.left = frame.left;
7235 if (content.top < frame.top) content.top = frame.top;
7236 if (content.right > frame.right) content.right = frame.right;
7237 if (content.bottom > frame.bottom) content.bottom = frame.bottom;
7238 if (visible.left < frame.left) visible.left = frame.left;
7239 if (visible.top < frame.top) visible.top = frame.top;
7240 if (visible.right > frame.right) visible.right = frame.right;
7241 if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007242
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007243 final Rect contentInsets = mContentInsets;
7244 contentInsets.left = content.left-frame.left;
7245 contentInsets.top = content.top-frame.top;
7246 contentInsets.right = frame.right-content.right;
7247 contentInsets.bottom = frame.bottom-content.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007248
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007249 final Rect visibleInsets = mVisibleInsets;
7250 visibleInsets.left = visible.left-frame.left;
7251 visibleInsets.top = visible.top-frame.top;
7252 visibleInsets.right = frame.right-visible.right;
7253 visibleInsets.bottom = frame.bottom-visible.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007254
Dianne Hackborn284ac932009-08-28 10:34:25 -07007255 if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
7256 updateWallpaperOffsetLocked(this, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07007257 mDisplay.getHeight(), false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07007258 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007260 if (localLOGV) {
7261 //if ("com.google.android.youtube".equals(mAttrs.packageName)
7262 // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007263 Slog.v(TAG, "Resolving (mRequestedWidth="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007264 + mRequestedWidth + ", mRequestedheight="
7265 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
7266 + "): frame=" + mFrame.toShortString()
7267 + " ci=" + contentInsets.toShortString()
7268 + " vi=" + visibleInsets.toShortString());
7269 //}
7270 }
7271 }
Romain Guy06882f82009-06-10 13:36:04 -07007272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007273 public Rect getFrameLw() {
7274 return mFrame;
7275 }
7276
7277 public Rect getShownFrameLw() {
7278 return mShownFrame;
7279 }
7280
7281 public Rect getDisplayFrameLw() {
7282 return mDisplayFrame;
7283 }
7284
7285 public Rect getContentFrameLw() {
7286 return mContentFrame;
7287 }
7288
7289 public Rect getVisibleFrameLw() {
7290 return mVisibleFrame;
7291 }
7292
7293 public boolean getGivenInsetsPendingLw() {
7294 return mGivenInsetsPending;
7295 }
7296
7297 public Rect getGivenContentInsetsLw() {
7298 return mGivenContentInsets;
7299 }
Romain Guy06882f82009-06-10 13:36:04 -07007300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007301 public Rect getGivenVisibleInsetsLw() {
7302 return mGivenVisibleInsets;
7303 }
Romain Guy06882f82009-06-10 13:36:04 -07007304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007305 public WindowManager.LayoutParams getAttrs() {
7306 return mAttrs;
7307 }
7308
7309 public int getSurfaceLayer() {
7310 return mLayer;
7311 }
Romain Guy06882f82009-06-10 13:36:04 -07007312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007313 public IApplicationToken getAppToken() {
7314 return mAppToken != null ? mAppToken.appToken : null;
7315 }
Jeff Brown349703e2010-06-22 01:27:15 -07007316
7317 public long getInputDispatchingTimeoutNanos() {
7318 return mAppToken != null
7319 ? mAppToken.inputDispatchingTimeoutNanos
7320 : DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
7321 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007322
7323 public boolean hasAppShownWindows() {
7324 return mAppToken != null ? mAppToken.firstWindowDrawn : false;
7325 }
7326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007327 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007328 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007329 TAG, "Setting animation in " + this + ": " + anim);
7330 mAnimating = false;
7331 mLocalAnimating = false;
7332 mAnimation = anim;
7333 mAnimation.restrictDuration(MAX_ANIMATION_DURATION);
7334 mAnimation.scaleCurrentDuration(mWindowAnimationScale);
7335 }
7336
7337 public void clearAnimation() {
7338 if (mAnimation != null) {
7339 mAnimating = true;
7340 mLocalAnimating = false;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007341 mAnimation.cancel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007342 mAnimation = null;
7343 }
7344 }
Romain Guy06882f82009-06-10 13:36:04 -07007345
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007346 Surface createSurfaceLocked() {
7347 if (mSurface == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007348 mReportDestroySurface = false;
7349 mSurfacePendingDestroy = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007350 mDrawPending = true;
7351 mCommitDrawPending = false;
7352 mReadyToShow = false;
7353 if (mAppToken != null) {
7354 mAppToken.allDrawn = false;
7355 }
7356
7357 int flags = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007358
7359 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
7360 flags |= Surface.SECURE;
7361 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007362 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007363 TAG, "Creating surface in session "
7364 + mSession.mSurfaceSession + " window " + this
7365 + " w=" + mFrame.width()
7366 + " h=" + mFrame.height() + " format="
7367 + mAttrs.format + " flags=" + flags);
7368
7369 int w = mFrame.width();
7370 int h = mFrame.height();
7371 if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
7372 // for a scaled surface, we always want the requested
7373 // size.
7374 w = mRequestedWidth;
7375 h = mRequestedHeight;
7376 }
7377
Romain Guy9825ec62009-10-01 00:58:09 -07007378 // Something is wrong and SurfaceFlinger will not like this,
7379 // try to revert to sane values
7380 if (w <= 0) w = 1;
7381 if (h <= 0) h = 1;
7382
Dianne Hackborn16064f92010-03-25 00:47:24 -07007383 mSurfaceShown = false;
7384 mSurfaceLayer = 0;
7385 mSurfaceAlpha = 1;
7386 mSurfaceX = 0;
7387 mSurfaceY = 0;
7388 mSurfaceW = w;
7389 mSurfaceH = h;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007390 try {
Romain Guyd10cd572010-10-10 13:33:22 -07007391 final boolean isHwAccelerated = (mAttrs.flags &
7392 WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
7393 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : mAttrs.format;
7394 if (isHwAccelerated && mAttrs.format == PixelFormat.OPAQUE) {
7395 flags |= Surface.OPAQUE;
7396 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007397 mSurface = new Surface(
Romain Guy06882f82009-06-10 13:36:04 -07007398 mSession.mSurfaceSession, mSession.mPid,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08007399 mAttrs.getTitle().toString(),
Romain Guyd10cd572010-10-10 13:33:22 -07007400 0, w, h, format, flags);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007401 if (SHOW_TRANSACTIONS) Slog.i(TAG, " CREATE SURFACE "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007402 + mSurface + " IN SESSION "
7403 + mSession.mSurfaceSession
7404 + ": pid=" + mSession.mPid + " format="
7405 + mAttrs.format + " flags=0x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007406 + Integer.toHexString(flags)
7407 + " / " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007408 } catch (Surface.OutOfResourcesException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007409 Slog.w(TAG, "OutOfResourcesException creating surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007410 reclaimSomeSurfaceMemoryLocked(this, "create");
7411 return null;
7412 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007413 Slog.e(TAG, "Exception creating surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007414 return null;
7415 }
Romain Guy06882f82009-06-10 13:36:04 -07007416
Joe Onorato8a9b2202010-02-26 18:56:32 -08007417 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007418 TAG, "Got surface: " + mSurface
7419 + ", set left=" + mFrame.left + " top=" + mFrame.top
7420 + ", animLayer=" + mAnimLayer);
7421 if (SHOW_TRANSACTIONS) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08007422 Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
7423 logSurface(this, "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007424 mFrame.width() + "x" + mFrame.height() + "), layer=" +
7425 mAnimLayer + " HIDE", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007426 }
7427 Surface.openTransaction();
7428 try {
7429 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07007430 mSurfaceX = mFrame.left + mXOffset;
Dianne Hackborn529bef62010-03-25 11:48:43 -07007431 mSurfaceY = mFrame.top + mYOffset;
Dianne Hackborn16064f92010-03-25 00:47:24 -07007432 mSurface.setPosition(mSurfaceX, mSurfaceY);
7433 mSurfaceLayer = mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007434 mSurface.setLayer(mAnimLayer);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007435 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007436 mSurface.hide();
7437 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007438 if (SHOW_TRANSACTIONS) logSurface(this, "DITHER", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007439 mSurface.setFlags(Surface.SURFACE_DITHER,
7440 Surface.SURFACE_DITHER);
7441 }
7442 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007443 Slog.w(TAG, "Error creating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007444 reclaimSomeSurfaceMemoryLocked(this, "create-init");
7445 }
7446 mLastHidden = true;
7447 } finally {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007448 Surface.closeTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08007449 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION createSurfaceLocked");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007450 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007451 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007452 TAG, "Created surface " + this);
7453 }
7454 return mSurface;
7455 }
Romain Guy06882f82009-06-10 13:36:04 -07007456
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007457 void destroySurfaceLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007458 if (mAppToken != null && this == mAppToken.startingWindow) {
7459 mAppToken.startingDisplayed = false;
7460 }
Romain Guy06882f82009-06-10 13:36:04 -07007461
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007462 if (mSurface != null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007463 mDrawPending = false;
7464 mCommitDrawPending = false;
7465 mReadyToShow = false;
7466
7467 int i = mChildWindows.size();
7468 while (i > 0) {
7469 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07007470 WindowState c = mChildWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007471 c.mAttachedHidden = true;
7472 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007473
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007474 if (mReportDestroySurface) {
7475 mReportDestroySurface = false;
7476 mSurfacePendingDestroy = true;
7477 try {
7478 mClient.dispatchGetNewSurface();
7479 // We'll really destroy on the next time around.
7480 return;
7481 } catch (RemoteException e) {
7482 }
7483 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007485 try {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007486 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007487 RuntimeException e = null;
7488 if (!HIDE_STACK_CRAWLS) {
7489 e = new RuntimeException();
7490 e.fillInStackTrace();
7491 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007492 Slog.w(TAG, "Window " + this + " destroying surface "
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007493 + mSurface + ", session " + mSession, e);
7494 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007495 if (SHOW_TRANSACTIONS) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007496 RuntimeException e = null;
7497 if (!HIDE_STACK_CRAWLS) {
7498 e = new RuntimeException();
7499 e.fillInStackTrace();
7500 }
7501 if (SHOW_TRANSACTIONS) logSurface(this, "DESTROY", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007502 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007503 mSurface.destroy();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007504 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007505 Slog.w(TAG, "Exception thrown when destroying Window " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007506 + " surface " + mSurface + " session " + mSession
7507 + ": " + e.toString());
7508 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007509
Dianne Hackborn16064f92010-03-25 00:47:24 -07007510 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007511 mSurface = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007512 }
7513 }
7514
7515 boolean finishDrawingLocked() {
7516 if (mDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007517 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007518 TAG, "finishDrawingLocked: " + mSurface);
7519 mCommitDrawPending = true;
7520 mDrawPending = false;
7521 return true;
7522 }
7523 return false;
7524 }
7525
7526 // This must be called while inside a transaction.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007527 boolean commitFinishDrawingLocked(long currentTime) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007528 //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007529 if (!mCommitDrawPending) {
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007530 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007531 }
7532 mCommitDrawPending = false;
7533 mReadyToShow = true;
7534 final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
7535 final AppWindowToken atoken = mAppToken;
7536 if (atoken == null || atoken.allDrawn || starting) {
7537 performShowLocked();
7538 }
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007539 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007540 }
7541
7542 // This must be called while inside a transaction.
7543 boolean performShowLocked() {
7544 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007545 RuntimeException e = null;
7546 if (!HIDE_STACK_CRAWLS) {
7547 e = new RuntimeException();
7548 e.fillInStackTrace();
7549 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007550 Slog.v(TAG, "performShow on " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007551 + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
7552 + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
7553 }
7554 if (mReadyToShow && isReadyForDisplay()) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007555 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) logSurface(this,
7556 "SHOW (performShowLocked)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007557 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007558 + " during animation: policyVis=" + mPolicyVisibility
7559 + " attHidden=" + mAttachedHidden
7560 + " tok.hiddenRequested="
7561 + (mAppToken != null ? mAppToken.hiddenRequested : false)
Dianne Hackborn248b1882009-09-16 16:46:44 -07007562 + " tok.hidden="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007563 + (mAppToken != null ? mAppToken.hidden : false)
7564 + " animating=" + mAnimating
7565 + " tok animating="
7566 + (mAppToken != null ? mAppToken.animating : false));
7567 if (!showSurfaceRobustlyLocked(this)) {
7568 return false;
7569 }
7570 mLastAlpha = -1;
7571 mHasDrawn = true;
7572 mLastHidden = false;
7573 mReadyToShow = false;
7574 enableScreenIfNeededLocked();
7575
7576 applyEnterAnimationLocked(this);
Romain Guy06882f82009-06-10 13:36:04 -07007577
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007578 int i = mChildWindows.size();
7579 while (i > 0) {
7580 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07007581 WindowState c = mChildWindows.get(i);
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07007582 if (c.mAttachedHidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007583 c.mAttachedHidden = false;
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07007584 if (c.mSurface != null) {
7585 c.performShowLocked();
7586 // It hadn't been shown, which means layout not
7587 // performed on it, so now we want to make sure to
7588 // do a layout. If called from within the transaction
7589 // loop, this will cause it to restart with a new
7590 // layout.
7591 mLayoutNeeded = true;
7592 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007593 }
7594 }
Romain Guy06882f82009-06-10 13:36:04 -07007595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007596 if (mAttrs.type != TYPE_APPLICATION_STARTING
7597 && mAppToken != null) {
7598 mAppToken.firstWindowDrawn = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007599
Dianne Hackborn248b1882009-09-16 16:46:44 -07007600 if (mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007601 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007602 "Finish starting " + mToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007603 + ": first real window is shown, no animation");
Dianne Hackborn248b1882009-09-16 16:46:44 -07007604 // If this initial window is animating, stop it -- we
7605 // will do an animation to reveal it from behind the
7606 // starting window, so there is no need for it to also
7607 // be doing its own stuff.
7608 if (mAnimation != null) {
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007609 mAnimation.cancel();
Dianne Hackborn248b1882009-09-16 16:46:44 -07007610 mAnimation = null;
7611 // Make sure we clean up the animation.
7612 mAnimating = true;
7613 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007614 mFinishedStarting.add(mAppToken);
7615 mH.sendEmptyMessage(H.FINISHED_STARTING);
7616 }
7617 mAppToken.updateReportedVisibilityLocked();
7618 }
7619 }
7620 return true;
7621 }
Romain Guy06882f82009-06-10 13:36:04 -07007622
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007623 // This must be called while inside a transaction. Returns true if
7624 // there is more animation to run.
7625 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007626 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007627 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07007628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007629 if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
7630 mHasTransformation = true;
7631 mHasLocalTransformation = true;
7632 if (!mLocalAnimating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007633 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007634 TAG, "Starting animation in " + this +
7635 " @ " + currentTime + ": ww=" + mFrame.width() + " wh=" + mFrame.height() +
7636 " dw=" + dw + " dh=" + dh + " scale=" + mWindowAnimationScale);
7637 mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
7638 mAnimation.setStartTime(currentTime);
7639 mLocalAnimating = true;
7640 mAnimating = true;
7641 }
7642 mTransformation.clear();
7643 final boolean more = mAnimation.getTransformation(
7644 currentTime, mTransformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007645 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007646 TAG, "Stepped animation in " + this +
7647 ": more=" + more + ", xform=" + mTransformation);
7648 if (more) {
7649 // we're not done!
7650 return true;
7651 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007652 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007653 TAG, "Finished animation in " + this +
7654 " @ " + currentTime);
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007655
7656 if (mAnimation != null) {
7657 mAnimation.cancel();
7658 mAnimation = null;
7659 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007660 //WindowManagerService.this.dump();
7661 }
7662 mHasLocalTransformation = false;
7663 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007664 && mAppToken.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007665 // When our app token is animating, we kind-of pretend like
7666 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
7667 // part of this check means that we will only do this if
7668 // our window is not currently exiting, or it is not
7669 // locally animating itself. The idea being that one that
7670 // is exiting and doing a local animation should be removed
7671 // once that animation is done.
7672 mAnimating = true;
7673 mHasTransformation = true;
7674 mTransformation.clear();
7675 return false;
7676 } else if (mHasTransformation) {
7677 // Little trick to get through the path below to act like
7678 // we have finished an animation.
7679 mAnimating = true;
7680 } else if (isAnimating()) {
7681 mAnimating = true;
7682 }
7683 } else if (mAnimation != null) {
7684 // If the display is frozen, and there is a pending animation,
7685 // clear it and make sure we run the cleanup code.
7686 mAnimating = true;
7687 mLocalAnimating = true;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007688 mAnimation.cancel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007689 mAnimation = null;
7690 }
Romain Guy06882f82009-06-10 13:36:04 -07007691
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007692 if (!mAnimating && !mLocalAnimating) {
7693 return false;
7694 }
7695
Joe Onorato8a9b2202010-02-26 18:56:32 -08007696 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007697 TAG, "Animation done in " + this + ": exiting=" + mExiting
7698 + ", reportedVisible="
7699 + (mAppToken != null ? mAppToken.reportedVisible : false));
Romain Guy06882f82009-06-10 13:36:04 -07007700
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007701 mAnimating = false;
7702 mLocalAnimating = false;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007703 if (mAnimation != null) {
7704 mAnimation.cancel();
7705 mAnimation = null;
7706 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007707 mAnimLayer = mLayer;
7708 if (mIsImWindow) {
7709 mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007710 } else if (mIsWallpaper) {
7711 mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007712 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007713 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007714 + " anim layer: " + mAnimLayer);
7715 mHasTransformation = false;
7716 mHasLocalTransformation = false;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007717 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
7718 if (DEBUG_VISIBILITY) {
7719 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
7720 + mPolicyVisibilityAfterAnim);
7721 }
7722 mPolicyVisibility = mPolicyVisibilityAfterAnim;
7723 if (!mPolicyVisibility) {
7724 if (mCurrentFocus == this) {
7725 mFocusMayChange = true;
7726 }
7727 // Window is no longer visible -- make sure if we were waiting
7728 // for it to be displayed before enabling the display, that
7729 // we allow the display to be enabled now.
7730 enableScreenIfNeededLocked();
7731 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08007732 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007733 mTransformation.clear();
7734 if (mHasDrawn
7735 && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
7736 && mAppToken != null
7737 && mAppToken.firstWindowDrawn
7738 && mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007739 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007740 + mToken + ": first real window done animating");
7741 mFinishedStarting.add(mAppToken);
7742 mH.sendEmptyMessage(H.FINISHED_STARTING);
7743 }
Romain Guy06882f82009-06-10 13:36:04 -07007744
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007745 finishExit();
7746
7747 if (mAppToken != null) {
7748 mAppToken.updateReportedVisibilityLocked();
7749 }
7750
7751 return false;
7752 }
7753
7754 void finishExit() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007755 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007756 TAG, "finishExit in " + this
7757 + ": exiting=" + mExiting
7758 + " remove=" + mRemoveOnExit
7759 + " windowAnimating=" + isWindowAnimating());
Romain Guy06882f82009-06-10 13:36:04 -07007760
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007761 final int N = mChildWindows.size();
7762 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07007763 mChildWindows.get(i).finishExit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007764 }
Romain Guy06882f82009-06-10 13:36:04 -07007765
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007766 if (!mExiting) {
7767 return;
7768 }
Romain Guy06882f82009-06-10 13:36:04 -07007769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007770 if (isWindowAnimating()) {
7771 return;
7772 }
7773
Joe Onorato8a9b2202010-02-26 18:56:32 -08007774 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007775 TAG, "Exit animation finished in " + this
7776 + ": remove=" + mRemoveOnExit);
7777 if (mSurface != null) {
7778 mDestroySurface.add(this);
7779 mDestroying = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007780 if (SHOW_TRANSACTIONS) logSurface(this, "HIDE (finishExit)", null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007781 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007782 try {
7783 mSurface.hide();
7784 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007785 Slog.w(TAG, "Error hiding surface in " + this, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007786 }
7787 mLastHidden = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007788 }
7789 mExiting = false;
7790 if (mRemoveOnExit) {
7791 mPendingRemove.add(this);
7792 mRemoveOnExit = false;
7793 }
7794 }
Romain Guy06882f82009-06-10 13:36:04 -07007795
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007796 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
7797 if (dsdx < .99999f || dsdx > 1.00001f) return false;
7798 if (dtdy < .99999f || dtdy > 1.00001f) return false;
7799 if (dtdx < -.000001f || dtdx > .000001f) return false;
7800 if (dsdy < -.000001f || dsdy > .000001f) return false;
7801 return true;
7802 }
Romain Guy06882f82009-06-10 13:36:04 -07007803
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007804 void computeShownFrameLocked() {
7805 final boolean selfTransformation = mHasLocalTransformation;
7806 Transformation attachedTransformation =
7807 (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
7808 ? mAttachedWindow.mTransformation : null;
7809 Transformation appTransformation =
7810 (mAppToken != null && mAppToken.hasTransformation)
7811 ? mAppToken.transformation : null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007812
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007813 // Wallpapers are animated based on the "real" window they
7814 // are currently targeting.
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007815 if (mAttrs.type == TYPE_WALLPAPER && mLowerWallpaperTarget == null
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07007816 && mWallpaperTarget != null) {
Dianne Hackborn5baba162009-09-23 17:01:12 -07007817 if (mWallpaperTarget.mHasLocalTransformation &&
7818 mWallpaperTarget.mAnimation != null &&
7819 !mWallpaperTarget.mAnimation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007820 attachedTransformation = mWallpaperTarget.mTransformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07007821 if (DEBUG_WALLPAPER && attachedTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007822 Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07007823 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007824 }
7825 if (mWallpaperTarget.mAppToken != null &&
Dianne Hackborn5baba162009-09-23 17:01:12 -07007826 mWallpaperTarget.mAppToken.hasTransformation &&
7827 mWallpaperTarget.mAppToken.animation != null &&
7828 !mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007829 appTransformation = mWallpaperTarget.mAppToken.transformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07007830 if (DEBUG_WALLPAPER && appTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007831 Slog.v(TAG, "WP target app xform: " + appTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07007832 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007833 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007834 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007835
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007836 final boolean screenAnimation = mScreenRotationAnimation != null
7837 && mScreenRotationAnimation.isAnimating();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007838 if (selfTransformation || attachedTransformation != null
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007839 || appTransformation != null || screenAnimation) {
Romain Guy06882f82009-06-10 13:36:04 -07007840 // cache often used attributes locally
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007841 final Rect frame = mFrame;
7842 final float tmpFloats[] = mTmpFloats;
7843 final Matrix tmpMatrix = mTmpMatrix;
7844
7845 // Compute the desired transformation.
Dianne Hackborn65c23872009-09-18 17:47:02 -07007846 tmpMatrix.setTranslate(0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007847 if (selfTransformation) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007848 tmpMatrix.postConcat(mTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007849 }
Dianne Hackborn50660e22011-02-02 17:12:25 -08007850 tmpMatrix.postTranslate(frame.left + mXOffset, frame.top + mYOffset);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007851 if (attachedTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007852 tmpMatrix.postConcat(attachedTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007853 }
7854 if (appTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007855 tmpMatrix.postConcat(appTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007856 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007857 if (screenAnimation) {
7858 tmpMatrix.postConcat(
7859 mScreenRotationAnimation.getEnterTransformation().getMatrix());
7860 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007861
7862 // "convert" it into SurfaceFlinger's format
7863 // (a 2x2 matrix + an offset)
7864 // Here we must not transform the position of the surface
7865 // since it is already included in the transformation.
Joe Onorato8a9b2202010-02-26 18:56:32 -08007866 //Slog.i(TAG, "Transform: " + matrix);
Romain Guy06882f82009-06-10 13:36:04 -07007867
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08007868 mHaveMatrix = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007869 tmpMatrix.getValues(tmpFloats);
7870 mDsDx = tmpFloats[Matrix.MSCALE_X];
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007871 mDtDx = tmpFloats[Matrix.MSKEW_Y];
7872 mDsDy = tmpFloats[Matrix.MSKEW_X];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007873 mDtDy = tmpFloats[Matrix.MSCALE_Y];
Dianne Hackborn50660e22011-02-02 17:12:25 -08007874 int x = (int)tmpFloats[Matrix.MTRANS_X];
7875 int y = (int)tmpFloats[Matrix.MTRANS_Y];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007876 int w = frame.width();
7877 int h = frame.height();
7878 mShownFrame.set(x, y, x+w, y+h);
7879
7880 // Now set the alpha... but because our current hardware
7881 // can't do alpha transformation on a non-opaque surface,
7882 // turn it off if we are running an animation that is also
7883 // transforming since it is more important to have that
7884 // animation be smooth.
7885 mShownAlpha = mAlpha;
7886 if (!mLimitedAlphaCompositing
7887 || (!PixelFormat.formatHasAlpha(mAttrs.format)
7888 || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
7889 && x == frame.left && y == frame.top))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007890 //Slog.i(TAG, "Applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007891 if (selfTransformation) {
7892 mShownAlpha *= mTransformation.getAlpha();
7893 }
7894 if (attachedTransformation != null) {
7895 mShownAlpha *= attachedTransformation.getAlpha();
7896 }
7897 if (appTransformation != null) {
7898 mShownAlpha *= appTransformation.getAlpha();
7899 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007900 if (screenAnimation) {
7901 mShownAlpha *=
7902 mScreenRotationAnimation.getEnterTransformation().getAlpha();
7903 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007904 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007905 //Slog.i(TAG, "Not applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007906 }
Romain Guy06882f82009-06-10 13:36:04 -07007907
Joe Onorato8a9b2202010-02-26 18:56:32 -08007908 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007909 TAG, "Continuing animation in " + this +
7910 ": " + mShownFrame +
7911 ", alpha=" + mTransformation.getAlpha());
7912 return;
7913 }
Romain Guy06882f82009-06-10 13:36:04 -07007914
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007915 mShownFrame.set(mFrame);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007916 if (mXOffset != 0 || mYOffset != 0) {
7917 mShownFrame.offset(mXOffset, mYOffset);
7918 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007919 mShownAlpha = mAlpha;
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08007920 mHaveMatrix = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007921 mDsDx = 1;
7922 mDtDx = 0;
7923 mDsDy = 0;
7924 mDtDy = 1;
7925 }
Romain Guy06882f82009-06-10 13:36:04 -07007926
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007927 /**
7928 * Is this window visible? It is not visible if there is no
7929 * surface, or we are in the process of running an exit animation
7930 * that will remove the surface, or its app token has been hidden.
7931 */
7932 public boolean isVisibleLw() {
7933 final AppWindowToken atoken = mAppToken;
7934 return mSurface != null && mPolicyVisibility && !mAttachedHidden
7935 && (atoken == null || !atoken.hiddenRequested)
7936 && !mExiting && !mDestroying;
7937 }
7938
7939 /**
Dianne Hackborn3d163f072009-10-07 21:26:57 -07007940 * Like {@link #isVisibleLw}, but also counts a window that is currently
7941 * "hidden" behind the keyguard as visible. This allows us to apply
7942 * things like window flags that impact the keyguard.
7943 * XXX I am starting to think we need to have ANOTHER visibility flag
7944 * for this "hidden behind keyguard" state rather than overloading
7945 * mPolicyVisibility. Ungh.
7946 */
7947 public boolean isVisibleOrBehindKeyguardLw() {
7948 final AppWindowToken atoken = mAppToken;
7949 return mSurface != null && !mAttachedHidden
7950 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007951 && !mDrawPending && !mCommitDrawPending
Dianne Hackborn3d163f072009-10-07 21:26:57 -07007952 && !mExiting && !mDestroying;
7953 }
7954
7955 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007956 * Is this window visible, ignoring its app token? It is not visible
7957 * if there is no surface, or we are in the process of running an exit animation
7958 * that will remove the surface.
7959 */
7960 public boolean isWinVisibleLw() {
7961 final AppWindowToken atoken = mAppToken;
7962 return mSurface != null && mPolicyVisibility && !mAttachedHidden
7963 && (atoken == null || !atoken.hiddenRequested || atoken.animating)
7964 && !mExiting && !mDestroying;
7965 }
7966
7967 /**
7968 * The same as isVisible(), but follows the current hidden state of
7969 * the associated app token, not the pending requested hidden state.
7970 */
7971 boolean isVisibleNow() {
7972 return mSurface != null && mPolicyVisibility && !mAttachedHidden
The Android Open Source Project10592532009-03-18 17:39:46 -07007973 && !mRootToken.hidden && !mExiting && !mDestroying;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007974 }
7975
7976 /**
Christopher Tatea53146c2010-09-07 11:57:52 -07007977 * Can this window possibly be a drag/drop target? The test here is
7978 * a combination of the above "visible now" with the check that the
7979 * Input Manager uses when discarding windows from input consideration.
7980 */
7981 boolean isPotentialDragTarget() {
7982 return isVisibleNow() && (mInputChannel != null) && !mRemoved;
7983 }
7984
7985 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007986 * Same as isVisible(), but we also count it as visible between the
7987 * call to IWindowSession.add() and the first relayout().
7988 */
7989 boolean isVisibleOrAdding() {
7990 final AppWindowToken atoken = mAppToken;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007991 return ((mSurface != null && !mReportDestroySurface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007992 || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
7993 && mPolicyVisibility && !mAttachedHidden
7994 && (atoken == null || !atoken.hiddenRequested)
7995 && !mExiting && !mDestroying;
7996 }
7997
7998 /**
7999 * Is this window currently on-screen? It is on-screen either if it
8000 * is visible or it is currently running an animation before no longer
8001 * being visible.
8002 */
8003 boolean isOnScreen() {
8004 final AppWindowToken atoken = mAppToken;
8005 if (atoken != null) {
8006 return mSurface != null && mPolicyVisibility && !mDestroying
8007 && ((!mAttachedHidden && !atoken.hiddenRequested)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008008 || mAnimation != null || atoken.animation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008009 } else {
8010 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008011 && (!mAttachedHidden || mAnimation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008012 }
8013 }
Romain Guy06882f82009-06-10 13:36:04 -07008014
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008015 /**
8016 * Like isOnScreen(), but we don't return true if the window is part
8017 * of a transition that has not yet been started.
8018 */
8019 boolean isReadyForDisplay() {
Dianne Hackborna8f60182009-09-01 19:01:50 -07008020 if (mRootToken.waitingToShow &&
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07008021 mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07008022 return false;
8023 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008024 final AppWindowToken atoken = mAppToken;
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008025 final boolean animating = atoken != null
8026 ? (atoken.animation != null) : false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008027 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008028 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
8029 && !mRootToken.hidden)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07008030 || mAnimation != null || animating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008031 }
8032
8033 /** Is the window or its container currently animating? */
8034 boolean isAnimating() {
8035 final WindowState attached = mAttachedWindow;
8036 final AppWindowToken atoken = mAppToken;
8037 return mAnimation != null
8038 || (attached != null && attached.mAnimation != null)
Romain Guy06882f82009-06-10 13:36:04 -07008039 || (atoken != null &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008040 (atoken.animation != null
8041 || atoken.inPendingTransaction));
8042 }
8043
8044 /** Is this window currently animating? */
8045 boolean isWindowAnimating() {
8046 return mAnimation != null;
8047 }
8048
8049 /**
8050 * Like isOnScreen, but returns false if the surface hasn't yet
8051 * been drawn.
8052 */
8053 public boolean isDisplayedLw() {
8054 final AppWindowToken atoken = mAppToken;
8055 return mSurface != null && mPolicyVisibility && !mDestroying
8056 && !mDrawPending && !mCommitDrawPending
8057 && ((!mAttachedHidden &&
8058 (atoken == null || !atoken.hiddenRequested))
8059 || mAnimating);
8060 }
8061
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008062 /**
8063 * Returns true if the window has a surface that it has drawn a
8064 * complete UI in to.
8065 */
8066 public boolean isDrawnLw() {
8067 final AppWindowToken atoken = mAppToken;
8068 return mSurface != null && !mDestroying
8069 && !mDrawPending && !mCommitDrawPending;
8070 }
8071
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008072 /**
Dianne Hackborn25994b42009-09-04 14:21:19 -07008073 * Return true if the window is opaque and fully drawn. This indicates
8074 * it may obscure windows behind it.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008075 */
8076 boolean isOpaqueDrawn() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07008077 return (mAttrs.format == PixelFormat.OPAQUE
8078 || mAttrs.type == TYPE_WALLPAPER)
8079 && mSurface != null && mAnimation == null
8080 && (mAppToken == null || mAppToken.animation == null)
8081 && !mDrawPending && !mCommitDrawPending;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008082 }
8083
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008084 /**
8085 * Return whether this window is wanting to have a translation
8086 * animation applied to it for an in-progress move. (Only makes
8087 * sense to call from performLayoutAndPlaceSurfacesLockedInner().)
8088 */
8089 boolean shouldAnimateMove() {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08008090 return mContentChanged && !mExiting && !mLastHidden && !mDisplayFrozen
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008091 && (mFrame.top != mLastFrame.top
8092 || mFrame.left != mLastFrame.left)
Dianne Hackborn0f761d62010-11-30 22:06:10 -08008093 && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove())
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008094 && mPolicy.isScreenOn();
8095 }
8096
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008097 boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
8098 return
8099 // only if the application is requesting compatible window
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07008100 (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
8101 // only if it's visible
8102 mHasDrawn && mViewVisibility == View.VISIBLE &&
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07008103 // and only if the application fills the compatible screen
8104 mFrame.left <= mCompatibleScreenFrame.left &&
8105 mFrame.top <= mCompatibleScreenFrame.top &&
8106 mFrame.right >= mCompatibleScreenFrame.right &&
Dianne Hackbornac1471a2011-02-03 13:46:06 -08008107 mFrame.bottom >= mCompatibleScreenFrame.bottom;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008108 }
8109
8110 boolean isFullscreen(int screenWidth, int screenHeight) {
8111 return mFrame.left <= 0 && mFrame.top <= 0 &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07008112 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008113 }
8114
8115 void removeLocked() {
Jeff Brownc5ed5912010-07-14 18:48:53 -07008116 disposeInputChannel();
8117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008118 if (mAttachedWindow != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008119 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mAttachedWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008120 mAttachedWindow.mChildWindows.remove(this);
8121 }
8122 destroySurfaceLocked();
8123 mSession.windowRemovedLocked();
8124 try {
8125 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
8126 } catch (RuntimeException e) {
8127 // Ignore if it has already been removed (usually because
8128 // we are doing this as part of processing a death note.)
8129 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07008130 }
8131
8132 void disposeInputChannel() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07008133 if (mInputChannel != null) {
8134 mInputManager.unregisterInputChannel(mInputChannel);
8135
8136 mInputChannel.dispose();
8137 mInputChannel = null;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07008138 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008139 }
8140
8141 private class DeathRecipient implements IBinder.DeathRecipient {
8142 public void binderDied() {
8143 try {
8144 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008145 WindowState win = windowForClientLocked(mSession, mClient, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008146 Slog.i(TAG, "WIN DEATH: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008147 if (win != null) {
8148 removeWindowLocked(mSession, win);
8149 }
8150 }
8151 } catch (IllegalArgumentException ex) {
8152 // This will happen if the window has already been
8153 // removed.
8154 }
8155 }
8156 }
8157
8158 /** Returns true if this window desires key events. */
8159 public final boolean canReceiveKeys() {
8160 return isVisibleOrAdding()
8161 && (mViewVisibility == View.VISIBLE)
8162 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
8163 }
8164
8165 public boolean hasDrawnLw() {
8166 return mHasDrawn;
8167 }
8168
8169 public boolean showLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008170 return showLw(doAnimation, true);
8171 }
8172
8173 boolean showLw(boolean doAnimation, boolean requestAnim) {
8174 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
8175 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008176 }
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008177 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008178 if (doAnimation) {
8179 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
8180 + mPolicyVisibility + " mAnimation=" + mAnimation);
8181 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
8182 doAnimation = false;
8183 } else if (mPolicyVisibility && mAnimation == null) {
8184 // Check for the case where we are currently visible and
8185 // not animating; we do not want to do animation at such a
8186 // point to become visible when we already are.
8187 doAnimation = false;
8188 }
8189 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008190 mPolicyVisibility = true;
8191 mPolicyVisibilityAfterAnim = true;
8192 if (doAnimation) {
8193 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
8194 }
8195 if (requestAnim) {
8196 requestAnimationLocked(0);
8197 }
8198 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008199 }
8200
8201 public boolean hideLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008202 return hideLw(doAnimation, true);
8203 }
8204
8205 boolean hideLw(boolean doAnimation, boolean requestAnim) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008206 if (doAnimation) {
8207 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
8208 doAnimation = false;
8209 }
8210 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008211 boolean current = doAnimation ? mPolicyVisibilityAfterAnim
8212 : mPolicyVisibility;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008213 if (!current) {
8214 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008215 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008216 if (doAnimation) {
8217 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
8218 if (mAnimation == null) {
8219 doAnimation = false;
8220 }
8221 }
8222 if (doAnimation) {
8223 mPolicyVisibilityAfterAnim = false;
8224 } else {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008225 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008226 mPolicyVisibilityAfterAnim = false;
8227 mPolicyVisibility = false;
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08008228 // Window is no longer visible -- make sure if we were waiting
8229 // for it to be displayed before enabling the display, that
8230 // we allow the display to be enabled now.
8231 enableScreenIfNeededLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008232 if (mCurrentFocus == this) {
8233 mFocusMayChange = true;
8234 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008235 }
8236 if (requestAnim) {
8237 requestAnimationLocked(0);
8238 }
8239 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008240 }
8241
Jeff Brownfbf09772011-01-16 14:06:57 -08008242 public void getTouchableRegion(Region outRegion) {
8243 final Rect frame = mFrame;
8244 switch (mTouchableInsets) {
8245 default:
8246 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
8247 outRegion.set(frame);
8248 break;
8249 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: {
8250 final Rect inset = mGivenContentInsets;
8251 outRegion.set(
8252 frame.left + inset.left, frame.top + inset.top,
8253 frame.right - inset.right, frame.bottom - inset.bottom);
8254 break;
8255 }
8256 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: {
8257 final Rect inset = mGivenVisibleInsets;
8258 outRegion.set(
8259 frame.left + inset.left, frame.top + inset.top,
8260 frame.right - inset.right, frame.bottom - inset.bottom);
8261 break;
8262 }
8263 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: {
8264 final Region givenTouchableRegion = mGivenTouchableRegion;
8265 outRegion.set(givenTouchableRegion);
8266 outRegion.translate(frame.left, frame.top);
8267 break;
8268 }
8269 }
8270 }
8271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008272 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008273 pw.print(prefix); pw.print("mSession="); pw.print(mSession);
8274 pw.print(" mClient="); pw.println(mClient.asBinder());
8275 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
8276 if (mAttachedWindow != null || mLayoutAttached) {
8277 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
8278 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
8279 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07008280 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
8281 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
8282 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008283 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
8284 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008285 }
8286 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
8287 pw.print(" mSubLayer="); pw.print(mSubLayer);
8288 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
8289 pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
8290 : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
8291 pw.print("="); pw.print(mAnimLayer);
8292 pw.print(" mLastLayer="); pw.println(mLastLayer);
8293 if (mSurface != null) {
8294 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
Dianne Hackborn16064f92010-03-25 00:47:24 -07008295 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
8296 pw.print(" layer="); pw.print(mSurfaceLayer);
8297 pw.print(" alpha="); pw.print(mSurfaceAlpha);
8298 pw.print(" rect=("); pw.print(mSurfaceX);
8299 pw.print(","); pw.print(mSurfaceY);
8300 pw.print(") "); pw.print(mSurfaceW);
8301 pw.print(" x "); pw.println(mSurfaceH);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008302 }
8303 pw.print(prefix); pw.print("mToken="); pw.println(mToken);
8304 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
8305 if (mAppToken != null) {
8306 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
8307 }
8308 if (mTargetAppToken != null) {
8309 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
8310 }
8311 pw.print(prefix); pw.print("mViewVisibility=0x");
8312 pw.print(Integer.toHexString(mViewVisibility));
8313 pw.print(" mLastHidden="); pw.print(mLastHidden);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008314 pw.print(" mHaveFrame="); pw.print(mHaveFrame);
8315 pw.print(" mObscured="); pw.println(mObscured);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008316 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
8317 pw.print(prefix); pw.print("mPolicyVisibility=");
8318 pw.print(mPolicyVisibility);
8319 pw.print(" mPolicyVisibilityAfterAnim=");
8320 pw.print(mPolicyVisibilityAfterAnim);
8321 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
8322 }
Dianne Hackborn9b52a212009-12-11 14:51:35 -08008323 if (!mRelayoutCalled) {
8324 pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
8325 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008326 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008327 pw.print(" h="); pw.print(mRequestedHeight);
8328 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008329 if (mXOffset != 0 || mYOffset != 0) {
8330 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
8331 pw.print(" y="); pw.println(mYOffset);
8332 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008333 pw.print(prefix); pw.print("mGivenContentInsets=");
8334 mGivenContentInsets.printShortString(pw);
8335 pw.print(" mGivenVisibleInsets=");
8336 mGivenVisibleInsets.printShortString(pw);
8337 pw.println();
8338 if (mTouchableInsets != 0 || mGivenInsetsPending) {
8339 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
8340 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
8341 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008342 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008343 pw.print(prefix); pw.print("mShownFrame=");
8344 mShownFrame.printShortString(pw);
8345 pw.print(" last="); mLastShownFrame.printShortString(pw);
8346 pw.println();
8347 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
8348 pw.print(" last="); mLastFrame.printShortString(pw);
8349 pw.println();
8350 pw.print(prefix); pw.print("mContainingFrame=");
8351 mContainingFrame.printShortString(pw);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008352 pw.print(" mParentFrame=");
8353 mParentFrame.printShortString(pw);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008354 pw.print(" mDisplayFrame=");
8355 mDisplayFrame.printShortString(pw);
8356 pw.println();
8357 pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
8358 pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
8359 pw.println();
8360 pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
8361 pw.print(" last="); mLastContentInsets.printShortString(pw);
8362 pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
8363 pw.print(" last="); mLastVisibleInsets.printShortString(pw);
8364 pw.println();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008365 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
8366 || mAnimation != null) {
8367 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
8368 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
8369 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
8370 pw.print(" mAnimation="); pw.println(mAnimation);
8371 }
8372 if (mHasTransformation || mHasLocalTransformation) {
8373 pw.print(prefix); pw.print("XForm: has=");
8374 pw.print(mHasTransformation);
8375 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
8376 pw.print(" "); mTransformation.printShortString(pw);
8377 pw.println();
8378 }
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08008379 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
8380 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
8381 pw.print(" mAlpha="); pw.print(mAlpha);
8382 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
8383 }
8384 if (mHaveMatrix) {
8385 pw.print(prefix); pw.print("mDsDx="); pw.print(mDsDx);
8386 pw.print(" mDtDx="); pw.print(mDtDx);
8387 pw.print(" mDsDy="); pw.print(mDsDy);
8388 pw.print(" mDtDy="); pw.println(mDtDy);
8389 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008390 pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
8391 pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
8392 pw.print(" mReadyToShow="); pw.print(mReadyToShow);
8393 pw.print(" mHasDrawn="); pw.println(mHasDrawn);
8394 if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
8395 pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
8396 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
8397 pw.print(" mDestroying="); pw.print(mDestroying);
8398 pw.print(" mRemoved="); pw.println(mRemoved);
8399 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008400 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008401 pw.print(prefix); pw.print("mOrientationChanging=");
8402 pw.print(mOrientationChanging);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008403 pw.print(" mAppFreezing="); pw.print(mAppFreezing);
8404 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008405 }
Mitsuru Oshima589cebe2009-07-22 20:38:58 -07008406 if (mHScale != 1 || mVScale != 1) {
8407 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
8408 pw.print(" mVScale="); pw.println(mVScale);
8409 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07008410 if (mWallpaperX != -1 || mWallpaperY != -1) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008411 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
8412 pw.print(" mWallpaperY="); pw.println(mWallpaperY);
8413 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08008414 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
8415 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
8416 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
8417 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008418 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07008419
8420 String makeInputChannelName() {
8421 return Integer.toHexString(System.identityHashCode(this))
8422 + " " + mAttrs.getTitle();
8423 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008424
8425 @Override
8426 public String toString() {
Mattias Petersson1622eee2010-12-21 10:15:11 +01008427 if (mStringNameCache == null || mLastTitle != mAttrs.getTitle()
8428 || mWasPaused != mToken.paused) {
8429 mLastTitle = mAttrs.getTitle();
8430 mWasPaused = mToken.paused;
8431 mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
8432 + " " + mLastTitle + " paused=" + mWasPaused + "}";
8433 }
8434 return mStringNameCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008435 }
8436 }
Romain Guy06882f82009-06-10 13:36:04 -07008437
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008438 // -------------------------------------------------------------
8439 // Window Token State
8440 // -------------------------------------------------------------
8441
8442 class WindowToken {
8443 // The actual token.
8444 final IBinder token;
8445
8446 // The type of window this token is for, as per WindowManager.LayoutParams.
8447 final int windowType;
Romain Guy06882f82009-06-10 13:36:04 -07008448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008449 // Set if this token was explicitly added by a client, so should
8450 // not be removed when all windows are removed.
8451 final boolean explicit;
Romain Guy06882f82009-06-10 13:36:04 -07008452
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008453 // For printing.
8454 String stringName;
Romain Guy06882f82009-06-10 13:36:04 -07008455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008456 // If this is an AppWindowToken, this is non-null.
8457 AppWindowToken appWindowToken;
Romain Guy06882f82009-06-10 13:36:04 -07008458
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008459 // All of the windows associated with this token.
8460 final ArrayList<WindowState> windows = new ArrayList<WindowState>();
8461
8462 // Is key dispatching paused for this token?
8463 boolean paused = false;
8464
8465 // Should this token's windows be hidden?
8466 boolean hidden;
8467
8468 // Temporary for finding which tokens no longer have visible windows.
8469 boolean hasVisible;
8470
Dianne Hackborna8f60182009-09-01 19:01:50 -07008471 // Set to true when this token is in a pending transaction where it
8472 // will be shown.
8473 boolean waitingToShow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008474
Dianne Hackborna8f60182009-09-01 19:01:50 -07008475 // Set to true when this token is in a pending transaction where it
8476 // will be hidden.
8477 boolean waitingToHide;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008478
Dianne Hackborna8f60182009-09-01 19:01:50 -07008479 // Set to true when this token is in a pending transaction where its
8480 // windows will be put to the bottom of the list.
8481 boolean sendingToBottom;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008482
Dianne Hackborna8f60182009-09-01 19:01:50 -07008483 // Set to true when this token is in a pending transaction where its
8484 // windows will be put to the top of the list.
8485 boolean sendingToTop;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008486
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008487 WindowToken(IBinder _token, int type, boolean _explicit) {
8488 token = _token;
8489 windowType = type;
8490 explicit = _explicit;
8491 }
8492
8493 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008494 pw.print(prefix); pw.print("token="); pw.println(token);
8495 pw.print(prefix); pw.print("windows="); pw.println(windows);
8496 pw.print(prefix); pw.print("windowType="); pw.print(windowType);
8497 pw.print(" hidden="); pw.print(hidden);
8498 pw.print(" hasVisible="); pw.println(hasVisible);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008499 if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) {
8500 pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
8501 pw.print(" waitingToHide="); pw.print(waitingToHide);
8502 pw.print(" sendingToBottom="); pw.print(sendingToBottom);
8503 pw.print(" sendingToTop="); pw.println(sendingToTop);
8504 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008505 }
8506
8507 @Override
8508 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008509 if (stringName == null) {
8510 StringBuilder sb = new StringBuilder();
8511 sb.append("WindowToken{");
8512 sb.append(Integer.toHexString(System.identityHashCode(this)));
8513 sb.append(" token="); sb.append(token); sb.append('}');
8514 stringName = sb.toString();
8515 }
8516 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008517 }
8518 };
8519
8520 class AppWindowToken extends WindowToken {
8521 // Non-null only for application tokens.
8522 final IApplicationToken appToken;
8523
8524 // All of the windows and child windows that are included in this
8525 // application token. Note this list is NOT sorted!
8526 final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
8527
8528 int groupId = -1;
8529 boolean appFullscreen;
8530 int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Jeff Brown349703e2010-06-22 01:27:15 -07008531
8532 // The input dispatching timeout for this application token in nanoseconds.
8533 long inputDispatchingTimeoutNanos;
Romain Guy06882f82009-06-10 13:36:04 -07008534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008535 // These are used for determining when all windows associated with
8536 // an activity have been drawn, so they can be made visible together
8537 // at the same time.
8538 int lastTransactionSequence = mTransactionSequence-1;
8539 int numInterestingWindows;
8540 int numDrawnWindows;
8541 boolean inPendingTransaction;
8542 boolean allDrawn;
Romain Guy06882f82009-06-10 13:36:04 -07008543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008544 // Is this token going to be hidden in a little while? If so, it
8545 // won't be taken into account for setting the screen orientation.
8546 boolean willBeHidden;
Romain Guy06882f82009-06-10 13:36:04 -07008547
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008548 // Is this window's surface needed? This is almost like hidden, except
8549 // it will sometimes be true a little earlier: when the token has
8550 // been shown, but is still waiting for its app transition to execute
8551 // before making its windows shown.
8552 boolean hiddenRequested;
Romain Guy06882f82009-06-10 13:36:04 -07008553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008554 // Have we told the window clients to hide themselves?
8555 boolean clientHidden;
Romain Guy06882f82009-06-10 13:36:04 -07008556
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008557 // Last visibility state we reported to the app token.
8558 boolean reportedVisible;
8559
8560 // Set to true when the token has been removed from the window mgr.
8561 boolean removed;
8562
8563 // Have we been asked to have this token keep the screen frozen?
8564 boolean freezingScreen;
Romain Guy06882f82009-06-10 13:36:04 -07008565
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008566 boolean animating;
8567 Animation animation;
8568 boolean hasTransformation;
8569 final Transformation transformation = new Transformation();
Romain Guy06882f82009-06-10 13:36:04 -07008570
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008571 // Offset to the window of all layers in the token, for use by
8572 // AppWindowToken animations.
8573 int animLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -07008574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008575 // Information about an application starting window if displayed.
8576 StartingData startingData;
8577 WindowState startingWindow;
8578 View startingView;
8579 boolean startingDisplayed;
8580 boolean startingMoved;
8581 boolean firstWindowDrawn;
8582
Jeff Brown928e0542011-01-10 11:17:36 -08008583 // Input application handle used by the input dispatcher.
8584 InputApplicationHandle mInputApplicationHandle;
8585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008586 AppWindowToken(IApplicationToken _token) {
8587 super(_token.asBinder(),
8588 WindowManager.LayoutParams.TYPE_APPLICATION, true);
8589 appWindowToken = this;
8590 appToken = _token;
Jeff Brown928e0542011-01-10 11:17:36 -08008591 mInputApplicationHandle = new InputApplicationHandle(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008592 }
Romain Guy06882f82009-06-10 13:36:04 -07008593
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008594 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008595 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008596 TAG, "Setting animation in " + this + ": " + anim);
8597 animation = anim;
8598 animating = false;
8599 anim.restrictDuration(MAX_ANIMATION_DURATION);
8600 anim.scaleCurrentDuration(mTransitionAnimationScale);
8601 int zorder = anim.getZAdjustment();
8602 int adj = 0;
8603 if (zorder == Animation.ZORDER_TOP) {
8604 adj = TYPE_LAYER_OFFSET;
8605 } else if (zorder == Animation.ZORDER_BOTTOM) {
8606 adj = -TYPE_LAYER_OFFSET;
8607 }
Romain Guy06882f82009-06-10 13:36:04 -07008608
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008609 if (animLayerAdjustment != adj) {
8610 animLayerAdjustment = adj;
8611 updateLayers();
8612 }
8613 }
Romain Guy06882f82009-06-10 13:36:04 -07008614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008615 public void setDummyAnimation() {
8616 if (animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008617 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008618 TAG, "Setting dummy animation in " + this);
8619 animation = sDummyAnimation;
8620 }
8621 }
8622
8623 public void clearAnimation() {
8624 if (animation != null) {
8625 animation = null;
8626 animating = true;
8627 }
8628 }
Romain Guy06882f82009-06-10 13:36:04 -07008629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008630 void updateLayers() {
8631 final int N = allAppWindows.size();
8632 final int adj = animLayerAdjustment;
8633 for (int i=0; i<N; i++) {
8634 WindowState w = allAppWindows.get(i);
8635 w.mAnimLayer = w.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008636 if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008637 + w.mAnimLayer);
Dianne Hackborne75d8722011-01-27 19:37:40 -08008638 if (w == mInputMethodTarget && !mInputMethodTargetWaitingAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008639 setInputMethodAnimLayerAdjustment(adj);
8640 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008641 if (w == mWallpaperTarget && mLowerWallpaperTarget == null) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008642 setWallpaperAnimLayerAdjustmentLocked(adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008643 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008644 }
8645 }
Romain Guy06882f82009-06-10 13:36:04 -07008646
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008647 void sendAppVisibilityToClients() {
8648 final int N = allAppWindows.size();
8649 for (int i=0; i<N; i++) {
8650 WindowState win = allAppWindows.get(i);
8651 if (win == startingWindow && clientHidden) {
8652 // Don't hide the starting window.
8653 continue;
8654 }
8655 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008656 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008657 "Setting visibility of " + win + ": " + (!clientHidden));
8658 win.mClient.dispatchAppVisibility(!clientHidden);
8659 } catch (RemoteException e) {
8660 }
8661 }
8662 }
Romain Guy06882f82009-06-10 13:36:04 -07008663
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008664 void showAllWindowsLocked() {
8665 final int NW = allAppWindows.size();
8666 for (int i=0; i<NW; i++) {
8667 WindowState w = allAppWindows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008668 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008669 "performing show on: " + w);
8670 w.performShowLocked();
8671 }
8672 }
Romain Guy06882f82009-06-10 13:36:04 -07008673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008674 // This must be called while inside a transaction.
8675 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008676 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008677 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07008678
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008679 if (animation == sDummyAnimation) {
8680 // This guy is going to animate, but not yet. For now count
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008681 // it as not animating for purposes of scheduling transactions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008682 // when it is really time to animate, this will be set to
8683 // a real animation and the next call will execute normally.
8684 return false;
8685 }
Romain Guy06882f82009-06-10 13:36:04 -07008686
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008687 if ((allDrawn || animating || startingDisplayed) && animation != null) {
8688 if (!animating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008689 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008690 TAG, "Starting animation in " + this +
8691 " @ " + currentTime + ": dw=" + dw + " dh=" + dh
8692 + " scale=" + mTransitionAnimationScale
8693 + " allDrawn=" + allDrawn + " animating=" + animating);
8694 animation.initialize(dw, dh, dw, dh);
8695 animation.setStartTime(currentTime);
8696 animating = true;
8697 }
8698 transformation.clear();
8699 final boolean more = animation.getTransformation(
8700 currentTime, transformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008701 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008702 TAG, "Stepped animation in " + this +
8703 ": more=" + more + ", xform=" + transformation);
8704 if (more) {
8705 // we're done!
8706 hasTransformation = true;
8707 return true;
8708 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008709 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008710 TAG, "Finished animation in " + this +
8711 " @ " + currentTime);
8712 animation = null;
8713 }
8714 } else if (animation != null) {
8715 // If the display is frozen, and there is a pending animation,
8716 // clear it and make sure we run the cleanup code.
8717 animating = true;
8718 animation = null;
8719 }
8720
8721 hasTransformation = false;
Romain Guy06882f82009-06-10 13:36:04 -07008722
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008723 if (!animating) {
8724 return false;
8725 }
8726
8727 clearAnimation();
8728 animating = false;
Dianne Hackborne75d8722011-01-27 19:37:40 -08008729 if (animLayerAdjustment != 0) {
8730 animLayerAdjustment = 0;
8731 updateLayers();
8732 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008733 if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == this) {
8734 moveInputMethodWindowsIfNeededLocked(true);
8735 }
Romain Guy06882f82009-06-10 13:36:04 -07008736
Joe Onorato8a9b2202010-02-26 18:56:32 -08008737 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008738 TAG, "Animation done in " + this
8739 + ": reportedVisible=" + reportedVisible);
8740
8741 transformation.clear();
Romain Guy06882f82009-06-10 13:36:04 -07008742
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008743 final int N = windows.size();
8744 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07008745 windows.get(i).finishExit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008746 }
8747 updateReportedVisibilityLocked();
Romain Guy06882f82009-06-10 13:36:04 -07008748
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008749 return false;
8750 }
8751
8752 void updateReportedVisibilityLocked() {
8753 if (appToken == null) {
8754 return;
8755 }
Romain Guy06882f82009-06-10 13:36:04 -07008756
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008757 int numInteresting = 0;
8758 int numVisible = 0;
8759 boolean nowGone = true;
Romain Guy06882f82009-06-10 13:36:04 -07008760
Joe Onorato8a9b2202010-02-26 18:56:32 -08008761 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008762 final int N = allAppWindows.size();
8763 for (int i=0; i<N; i++) {
8764 WindowState win = allAppWindows.get(i);
Dianne Hackborn6cf67fa2009-12-21 16:46:34 -08008765 if (win == startingWindow || win.mAppFreezing
The Android Open Source Project727cec02010-04-08 11:35:37 -07008766 || win.mViewVisibility != View.VISIBLE
Ulf Rosdahl39357702010-09-29 12:34:38 +02008767 || win.mAttrs.type == TYPE_APPLICATION_STARTING
8768 || win.mDestroying) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008769 continue;
8770 }
8771 if (DEBUG_VISIBILITY) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008772 Slog.v(TAG, "Win " + win + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008773 + win.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008774 + ", isAnimating=" + win.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008775 if (!win.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008776 Slog.v(TAG, "Not displayed: s=" + win.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008777 + " pv=" + win.mPolicyVisibility
8778 + " dp=" + win.mDrawPending
8779 + " cdp=" + win.mCommitDrawPending
8780 + " ah=" + win.mAttachedHidden
8781 + " th="
8782 + (win.mAppToken != null
8783 ? win.mAppToken.hiddenRequested : false)
8784 + " a=" + win.mAnimating);
8785 }
8786 }
8787 numInteresting++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008788 if (win.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008789 if (!win.isAnimating()) {
8790 numVisible++;
8791 }
8792 nowGone = false;
8793 } else if (win.isAnimating()) {
8794 nowGone = false;
8795 }
8796 }
Romain Guy06882f82009-06-10 13:36:04 -07008797
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008798 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008799 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008800 + numInteresting + " visible=" + numVisible);
8801 if (nowVisible != reportedVisible) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008802 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008803 TAG, "Visibility changed in " + this
8804 + ": vis=" + nowVisible);
8805 reportedVisible = nowVisible;
8806 Message m = mH.obtainMessage(
8807 H.REPORT_APPLICATION_TOKEN_WINDOWS,
8808 nowVisible ? 1 : 0,
8809 nowGone ? 1 : 0,
8810 this);
8811 mH.sendMessage(m);
8812 }
8813 }
Romain Guy06882f82009-06-10 13:36:04 -07008814
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07008815 WindowState findMainWindow() {
8816 int j = windows.size();
8817 while (j > 0) {
8818 j--;
8819 WindowState win = windows.get(j);
8820 if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
8821 || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
8822 return win;
8823 }
8824 }
8825 return null;
8826 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008827
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008828 void dump(PrintWriter pw, String prefix) {
8829 super.dump(pw, prefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008830 if (appToken != null) {
8831 pw.print(prefix); pw.println("app=true");
8832 }
8833 if (allAppWindows.size() > 0) {
8834 pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
8835 }
8836 pw.print(prefix); pw.print("groupId="); pw.print(groupId);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008837 pw.print(" appFullscreen="); pw.print(appFullscreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008838 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
8839 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
8840 pw.print(" clientHidden="); pw.print(clientHidden);
8841 pw.print(" willBeHidden="); pw.print(willBeHidden);
8842 pw.print(" reportedVisible="); pw.println(reportedVisible);
8843 if (paused || freezingScreen) {
8844 pw.print(prefix); pw.print("paused="); pw.print(paused);
8845 pw.print(" freezingScreen="); pw.println(freezingScreen);
8846 }
8847 if (numInterestingWindows != 0 || numDrawnWindows != 0
8848 || inPendingTransaction || allDrawn) {
8849 pw.print(prefix); pw.print("numInterestingWindows=");
8850 pw.print(numInterestingWindows);
8851 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
8852 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
8853 pw.print(" allDrawn="); pw.println(allDrawn);
8854 }
8855 if (animating || animation != null) {
8856 pw.print(prefix); pw.print("animating="); pw.print(animating);
8857 pw.print(" animation="); pw.println(animation);
8858 }
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08008859 if (hasTransformation) {
8860 pw.print(prefix); pw.print("XForm: ");
8861 transformation.printShortString(pw);
8862 pw.println();
8863 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008864 if (animLayerAdjustment != 0) {
8865 pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
8866 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008867 if (startingData != null || removed || firstWindowDrawn) {
8868 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
8869 pw.print(" removed="); pw.print(removed);
8870 pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn);
8871 }
8872 if (startingWindow != null || startingView != null
8873 || startingDisplayed || startingMoved) {
8874 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
8875 pw.print(" startingView="); pw.print(startingView);
8876 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
8877 pw.print(" startingMoved"); pw.println(startingMoved);
8878 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008879 }
8880
8881 @Override
8882 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008883 if (stringName == null) {
8884 StringBuilder sb = new StringBuilder();
8885 sb.append("AppWindowToken{");
8886 sb.append(Integer.toHexString(System.identityHashCode(this)));
8887 sb.append(" token="); sb.append(token); sb.append('}');
8888 stringName = sb.toString();
8889 }
8890 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008891 }
8892 }
Romain Guy06882f82009-06-10 13:36:04 -07008893
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008894 // -------------------------------------------------------------
8895 // DummyAnimation
8896 // -------------------------------------------------------------
8897
8898 // This is an animation that does nothing: it just immediately finishes
8899 // itself every time it is called. It is used as a stub animation in cases
8900 // where we want to synchronize multiple things that may be animating.
8901 static final class DummyAnimation extends Animation {
8902 public boolean getTransformation(long currentTime, Transformation outTransformation) {
8903 return false;
8904 }
8905 }
8906 static final Animation sDummyAnimation = new DummyAnimation();
Romain Guy06882f82009-06-10 13:36:04 -07008907
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008908 // -------------------------------------------------------------
8909 // Async Handler
8910 // -------------------------------------------------------------
8911
8912 static final class StartingData {
8913 final String pkg;
8914 final int theme;
8915 final CharSequence nonLocalizedLabel;
8916 final int labelRes;
8917 final int icon;
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08008918 final int windowFlags;
Romain Guy06882f82009-06-10 13:36:04 -07008919
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008920 StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08008921 int _labelRes, int _icon, int _windowFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008922 pkg = _pkg;
8923 theme = _theme;
8924 nonLocalizedLabel = _nonLocalizedLabel;
8925 labelRes = _labelRes;
8926 icon = _icon;
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08008927 windowFlags = _windowFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008928 }
8929 }
8930
8931 private final class H extends Handler {
8932 public static final int REPORT_FOCUS_CHANGE = 2;
8933 public static final int REPORT_LOSING_FOCUS = 3;
8934 public static final int ANIMATE = 4;
8935 public static final int ADD_STARTING = 5;
8936 public static final int REMOVE_STARTING = 6;
8937 public static final int FINISHED_STARTING = 7;
8938 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008939 public static final int WINDOW_FREEZE_TIMEOUT = 11;
8940 public static final int HOLD_SCREEN_CHANGED = 12;
8941 public static final int APP_TRANSITION_TIMEOUT = 13;
8942 public static final int PERSIST_ANIMATION_SCALE = 14;
8943 public static final int FORCE_GC = 15;
8944 public static final int ENABLE_SCREEN = 16;
8945 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008946 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008947 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07008948 public static final int DRAG_START_TIMEOUT = 20;
Chris Tated4533f142010-10-19 15:15:08 -07008949 public static final int DRAG_END_TIMEOUT = 21;
Jeff Brown2992ea72011-01-28 22:04:14 -08008950 public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
Romain Guy06882f82009-06-10 13:36:04 -07008951
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008952 private Session mLastReportedHold;
Romain Guy06882f82009-06-10 13:36:04 -07008953
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008954 public H() {
8955 }
Romain Guy06882f82009-06-10 13:36:04 -07008956
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008957 @Override
8958 public void handleMessage(Message msg) {
8959 switch (msg.what) {
8960 case REPORT_FOCUS_CHANGE: {
8961 WindowState lastFocus;
8962 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07008963
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008964 synchronized(mWindowMap) {
8965 lastFocus = mLastFocus;
8966 newFocus = mCurrentFocus;
8967 if (lastFocus == newFocus) {
8968 // Focus is not changing, so nothing to do.
8969 return;
8970 }
8971 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008972 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008973 // + " to " + newFocus);
8974 if (newFocus != null && lastFocus != null
8975 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008976 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008977 mLosingFocus.add(lastFocus);
8978 lastFocus = null;
8979 }
8980 }
8981
8982 if (lastFocus != newFocus) {
8983 //System.out.println("Changing focus from " + lastFocus
8984 // + " to " + newFocus);
8985 if (newFocus != null) {
8986 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008987 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008988 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
8989 } catch (RemoteException e) {
8990 // Ignore if process has died.
8991 }
Konstantin Lopyrev5e7833a2010-08-09 17:01:11 -07008992 notifyFocusChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008993 }
8994
8995 if (lastFocus != null) {
8996 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008997 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008998 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
8999 } catch (RemoteException e) {
9000 // Ignore if process has died.
9001 }
9002 }
Joe Onorato664644d2011-01-23 17:53:23 -08009003
9004 mPolicy.focusChanged(lastFocus, newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009005 }
9006 } break;
9007
9008 case REPORT_LOSING_FOCUS: {
9009 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07009010
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009011 synchronized(mWindowMap) {
9012 losers = mLosingFocus;
9013 mLosingFocus = new ArrayList<WindowState>();
9014 }
9015
9016 final int N = losers.size();
9017 for (int i=0; i<N; i++) {
9018 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009019 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009020 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
9021 } catch (RemoteException e) {
9022 // Ignore if process has died.
9023 }
9024 }
9025 } break;
9026
9027 case ANIMATE: {
9028 synchronized(mWindowMap) {
9029 mAnimationPending = false;
9030 performLayoutAndPlaceSurfacesLocked();
9031 }
9032 } break;
9033
9034 case ADD_STARTING: {
9035 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
9036 final StartingData sd = wtoken.startingData;
9037
9038 if (sd == null) {
9039 // Animation has been canceled... do nothing.
9040 return;
9041 }
Romain Guy06882f82009-06-10 13:36:04 -07009042
Joe Onorato8a9b2202010-02-26 18:56:32 -08009043 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009044 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07009045
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009046 View view = null;
9047 try {
9048 view = mPolicy.addStartingWindow(
9049 wtoken.token, sd.pkg,
9050 sd.theme, sd.nonLocalizedLabel, sd.labelRes,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08009051 sd.icon, sd.windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009052 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009053 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009054 }
9055
9056 if (view != null) {
9057 boolean abort = false;
9058
9059 synchronized(mWindowMap) {
9060 if (wtoken.removed || wtoken.startingData == null) {
9061 // If the window was successfully added, then
9062 // we need to remove it.
9063 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009064 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009065 "Aborted starting " + wtoken
9066 + ": removed=" + wtoken.removed
9067 + " startingData=" + wtoken.startingData);
9068 wtoken.startingWindow = null;
9069 wtoken.startingData = null;
9070 abort = true;
9071 }
9072 } else {
9073 wtoken.startingView = view;
9074 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009075 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009076 "Added starting " + wtoken
9077 + ": startingWindow="
9078 + wtoken.startingWindow + " startingView="
9079 + wtoken.startingView);
9080 }
9081
9082 if (abort) {
9083 try {
9084 mPolicy.removeStartingWindow(wtoken.token, view);
9085 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009086 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009087 }
9088 }
9089 }
9090 } break;
9091
9092 case REMOVE_STARTING: {
9093 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
9094 IBinder token = null;
9095 View view = null;
9096 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009097 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009098 + wtoken + ": startingWindow="
9099 + wtoken.startingWindow + " startingView="
9100 + wtoken.startingView);
9101 if (wtoken.startingWindow != null) {
9102 view = wtoken.startingView;
9103 token = wtoken.token;
9104 wtoken.startingData = null;
9105 wtoken.startingView = null;
9106 wtoken.startingWindow = null;
9107 }
9108 }
9109 if (view != null) {
9110 try {
9111 mPolicy.removeStartingWindow(token, view);
9112 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009113 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009114 }
9115 }
9116 } break;
9117
9118 case FINISHED_STARTING: {
9119 IBinder token = null;
9120 View view = null;
9121 while (true) {
9122 synchronized (mWindowMap) {
9123 final int N = mFinishedStarting.size();
9124 if (N <= 0) {
9125 break;
9126 }
9127 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
9128
Joe Onorato8a9b2202010-02-26 18:56:32 -08009129 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009130 "Finished starting " + wtoken
9131 + ": startingWindow=" + wtoken.startingWindow
9132 + " startingView=" + wtoken.startingView);
9133
9134 if (wtoken.startingWindow == null) {
9135 continue;
9136 }
9137
9138 view = wtoken.startingView;
9139 token = wtoken.token;
9140 wtoken.startingData = null;
9141 wtoken.startingView = null;
9142 wtoken.startingWindow = null;
9143 }
9144
9145 try {
9146 mPolicy.removeStartingWindow(token, view);
9147 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009148 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009149 }
9150 }
9151 } break;
9152
9153 case REPORT_APPLICATION_TOKEN_WINDOWS: {
9154 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
9155
9156 boolean nowVisible = msg.arg1 != 0;
9157 boolean nowGone = msg.arg2 != 0;
9158
9159 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009160 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009161 TAG, "Reporting visible in " + wtoken
9162 + " visible=" + nowVisible
9163 + " gone=" + nowGone);
9164 if (nowVisible) {
9165 wtoken.appToken.windowsVisible();
9166 } else {
9167 wtoken.appToken.windowsGone();
9168 }
9169 } catch (RemoteException ex) {
9170 }
9171 } break;
Romain Guy06882f82009-06-10 13:36:04 -07009172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009173 case WINDOW_FREEZE_TIMEOUT: {
9174 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009175 Slog.w(TAG, "Window freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009176 int i = mWindows.size();
9177 while (i > 0) {
9178 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07009179 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009180 if (w.mOrientationChanging) {
9181 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009182 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009183 }
9184 }
9185 performLayoutAndPlaceSurfacesLocked();
9186 }
9187 break;
9188 }
Romain Guy06882f82009-06-10 13:36:04 -07009189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009190 case HOLD_SCREEN_CHANGED: {
9191 Session oldHold;
9192 Session newHold;
9193 synchronized (mWindowMap) {
9194 oldHold = mLastReportedHold;
9195 newHold = (Session)msg.obj;
9196 mLastReportedHold = newHold;
9197 }
Romain Guy06882f82009-06-10 13:36:04 -07009198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009199 if (oldHold != newHold) {
9200 try {
9201 if (oldHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07009202 mBatteryStats.noteStopWakelock(oldHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009203 "window",
9204 BatteryStats.WAKE_TYPE_WINDOW);
9205 }
9206 if (newHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07009207 mBatteryStats.noteStartWakelock(newHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009208 "window",
9209 BatteryStats.WAKE_TYPE_WINDOW);
9210 }
9211 } catch (RemoteException e) {
9212 }
9213 }
9214 break;
9215 }
Romain Guy06882f82009-06-10 13:36:04 -07009216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009217 case APP_TRANSITION_TIMEOUT: {
9218 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009219 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009220 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009221 "*** APP TRANSITION TIMEOUT");
9222 mAppTransitionReady = true;
9223 mAppTransitionTimeout = true;
9224 performLayoutAndPlaceSurfacesLocked();
9225 }
9226 }
9227 break;
9228 }
Romain Guy06882f82009-06-10 13:36:04 -07009229
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009230 case PERSIST_ANIMATION_SCALE: {
9231 Settings.System.putFloat(mContext.getContentResolver(),
9232 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
9233 Settings.System.putFloat(mContext.getContentResolver(),
9234 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
9235 break;
9236 }
Romain Guy06882f82009-06-10 13:36:04 -07009237
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009238 case FORCE_GC: {
9239 synchronized(mWindowMap) {
9240 if (mAnimationPending) {
9241 // If we are animating, don't do the gc now but
9242 // delay a bit so we don't interrupt the animation.
9243 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
9244 2000);
9245 return;
9246 }
9247 // If we are currently rotating the display, it will
9248 // schedule a new message when done.
9249 if (mDisplayFrozen) {
9250 return;
9251 }
9252 mFreezeGcPending = 0;
9253 }
9254 Runtime.getRuntime().gc();
9255 break;
9256 }
Romain Guy06882f82009-06-10 13:36:04 -07009257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009258 case ENABLE_SCREEN: {
9259 performEnableScreen();
9260 break;
9261 }
Romain Guy06882f82009-06-10 13:36:04 -07009262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009263 case APP_FREEZE_TIMEOUT: {
9264 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009265 Slog.w(TAG, "App freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009266 int i = mAppTokens.size();
9267 while (i > 0) {
9268 i--;
9269 AppWindowToken tok = mAppTokens.get(i);
9270 if (tok.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009271 Slog.w(TAG, "Force clearing freeze: " + tok);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009272 unsetAppFreezingScreenLocked(tok, true, true);
9273 }
9274 }
9275 }
9276 break;
9277 }
Romain Guy06882f82009-06-10 13:36:04 -07009278
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009279 case SEND_NEW_CONFIGURATION: {
9280 removeMessages(SEND_NEW_CONFIGURATION);
9281 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07009282 break;
9283 }
Romain Guy06882f82009-06-10 13:36:04 -07009284
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07009285 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07009286 if (mWindowsChanged) {
9287 synchronized (mWindowMap) {
9288 mWindowsChanged = false;
9289 }
9290 notifyWindowsChanged();
9291 }
9292 break;
9293 }
9294
Christopher Tatea53146c2010-09-07 11:57:52 -07009295 case DRAG_START_TIMEOUT: {
9296 IBinder win = (IBinder)msg.obj;
9297 if (DEBUG_DRAG) {
9298 Slog.w(TAG, "Timeout starting drag by win " + win);
9299 }
9300 synchronized (mWindowMap) {
9301 // !!! TODO: ANR the app that has failed to start the drag in time
9302 if (mDragState != null) {
Chris Tated4533f142010-10-19 15:15:08 -07009303 mDragState.unregister();
Jeff Brown2e44b072011-01-24 15:21:56 -08009304 mInputMonitor.updateInputWindowsLw(true /*force*/);
Christopher Tatea53146c2010-09-07 11:57:52 -07009305 mDragState.reset();
9306 mDragState = null;
9307 }
9308 }
Chris Tated4533f142010-10-19 15:15:08 -07009309 break;
Christopher Tatea53146c2010-09-07 11:57:52 -07009310 }
9311
Chris Tated4533f142010-10-19 15:15:08 -07009312 case DRAG_END_TIMEOUT: {
9313 IBinder win = (IBinder)msg.obj;
9314 if (DEBUG_DRAG) {
9315 Slog.w(TAG, "Timeout ending drag to win " + win);
9316 }
9317 synchronized (mWindowMap) {
9318 // !!! TODO: ANR the drag-receiving app
9319 mDragState.mDragResult = false;
9320 mDragState.endDragLw();
9321 }
9322 break;
9323 }
Jeff Brown2992ea72011-01-28 22:04:14 -08009324
9325 case REPORT_HARD_KEYBOARD_STATUS_CHANGE: {
9326 notifyHardKeyboardStatusChange();
9327 break;
9328 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009329 }
9330 }
9331 }
9332
9333 // -------------------------------------------------------------
9334 // IWindowManager API
9335 // -------------------------------------------------------------
9336
9337 public IWindowSession openSession(IInputMethodClient client,
9338 IInputContext inputContext) {
9339 if (client == null) throw new IllegalArgumentException("null client");
9340 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07009341 Session session = new Session(client, inputContext);
9342 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009343 }
9344
9345 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
9346 synchronized (mWindowMap) {
9347 // The focus for the client is the window immediately below
9348 // where we would place the input method window.
9349 int idx = findDesiredInputMethodWindowIndexLocked(false);
9350 WindowState imFocus;
9351 if (idx > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07009352 imFocus = mWindows.get(idx-1);
Dianne Hackborne75d8722011-01-27 19:37:40 -08009353 //Log.i(TAG, "Desired input method target: " + imFocus);
9354 //Log.i(TAG, "Current focus: " + this.mCurrentFocus);
9355 //Log.i(TAG, "Last focus: " + this.mLastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009356 if (imFocus != null) {
Dianne Hackborne75d8722011-01-27 19:37:40 -08009357 // This may be a starting window, in which case we still want
9358 // to count it as okay.
9359 if (imFocus.mAttrs.type == LayoutParams.TYPE_APPLICATION_STARTING
9360 && imFocus.mAppToken != null) {
9361 // The client has definitely started, so it really should
9362 // have a window in this app token. Let's look for it.
9363 for (int i=0; i<imFocus.mAppToken.windows.size(); i++) {
9364 WindowState w = imFocus.mAppToken.windows.get(i);
9365 if (w != imFocus) {
9366 //Log.i(TAG, "Switching to real app window: " + w);
9367 imFocus = w;
9368 break;
9369 }
9370 }
9371 }
9372 //Log.i(TAG, "IM target client: " + imFocus.mSession.mClient);
9373 //if (imFocus.mSession.mClient != null) {
9374 // Log.i(TAG, "IM target client binder: " + imFocus.mSession.mClient.asBinder());
9375 // Log.i(TAG, "Requesting client binder: " + client.asBinder());
9376 //}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009377 if (imFocus.mSession.mClient != null &&
9378 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
9379 return true;
9380 }
Dianne Hackborne75d8722011-01-27 19:37:40 -08009381
9382 // Okay, how about this... what is the current focus?
9383 // It seems in some cases we may not have moved the IM
9384 // target window, such as when it was in a pop-up window,
9385 // so let's also look at the current focus. (An example:
9386 // go to Gmail, start searching so the keyboard goes up,
9387 // press home. Sometimes the IME won't go down.)
9388 // Would be nice to fix this more correctly, but it's
9389 // way at the end of a release, and this should be good enough.
9390 if (mCurrentFocus != null && mCurrentFocus.mSession.mClient != null &&
9391 mCurrentFocus.mSession.mClient.asBinder() == client.asBinder()) {
9392 return true;
9393 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009394 }
9395 }
9396 }
9397 return false;
9398 }
Romain Guy06882f82009-06-10 13:36:04 -07009399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009400 // -------------------------------------------------------------
9401 // Internals
9402 // -------------------------------------------------------------
9403
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009404 final WindowState windowForClientLocked(Session session, IWindow client,
9405 boolean throwOnError) {
9406 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009407 }
Romain Guy06882f82009-06-10 13:36:04 -07009408
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009409 final WindowState windowForClientLocked(Session session, IBinder client,
9410 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009411 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009412 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009413 TAG, "Looking up client " + client + ": " + win);
9414 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009415 RuntimeException ex = new IllegalArgumentException(
9416 "Requested window " + client + " does not exist");
9417 if (throwOnError) {
9418 throw ex;
9419 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009420 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009421 return null;
9422 }
9423 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009424 RuntimeException ex = new IllegalArgumentException(
9425 "Requested window " + client + " is in session " +
9426 win.mSession + ", not " + session);
9427 if (throwOnError) {
9428 throw ex;
9429 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009430 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009431 return null;
9432 }
9433
9434 return win;
9435 }
9436
Dianne Hackborna8f60182009-09-01 19:01:50 -07009437 final void rebuildAppWindowListLocked() {
9438 int NW = mWindows.size();
9439 int i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009440 int lastWallpaper = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009441 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009442
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009443 if (mRebuildTmp.length < NW) {
9444 mRebuildTmp = new WindowState[NW+10];
9445 }
9446
Dianne Hackborna8f60182009-09-01 19:01:50 -07009447 // First remove all existing app windows.
9448 i=0;
9449 while (i < NW) {
Jeff Browne33348b2010-07-15 23:54:05 -07009450 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009451 if (w.mAppToken != null) {
Jeff Browne33348b2010-07-15 23:54:05 -07009452 WindowState win = mWindows.remove(i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009453 win.mRebuilding = true;
9454 mRebuildTmp[numRemoved] = win;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07009455 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009456 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009457 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07009458 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009459 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009460 continue;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009461 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER
9462 && lastWallpaper == i-1) {
9463 lastWallpaper = i;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009464 }
9465 i++;
9466 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009467
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009468 // The wallpaper window(s) typically live at the bottom of the stack,
9469 // so skip them before adding app tokens.
9470 lastWallpaper++;
9471 i = lastWallpaper;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009472
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009473 // First add all of the exiting app tokens... these are no longer
9474 // in the main app list, but still have windows shown. We put them
9475 // in the back because now that the animation is over we no longer
9476 // will care about them.
9477 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009478 for (int j=0; j<NT; j++) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009479 i = reAddAppWindowsLocked(i, mExitingAppTokens.get(j));
9480 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009481
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009482 // And add in the still active app tokens in Z order.
9483 NT = mAppTokens.size();
9484 for (int j=0; j<NT; j++) {
9485 i = reAddAppWindowsLocked(i, mAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07009486 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009487
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009488 i -= lastWallpaper;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009489 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009490 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009491 + " windows but added " + i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009492 for (i=0; i<numRemoved; i++) {
9493 WindowState ws = mRebuildTmp[i];
9494 if (ws.mRebuilding) {
9495 StringWriter sw = new StringWriter();
9496 PrintWriter pw = new PrintWriter(sw);
9497 ws.dump(pw, "");
9498 pw.flush();
9499 Slog.w(TAG, "This window was lost: " + ws);
9500 Slog.w(TAG, sw.toString());
9501 }
9502 }
9503 Slog.w(TAG, "Current app token list:");
9504 dumpAppTokensLocked();
9505 Slog.w(TAG, "Final window list:");
9506 dumpWindowsLocked();
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009507 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07009508 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009510 private final void assignLayersLocked() {
9511 int N = mWindows.size();
9512 int curBaseLayer = 0;
9513 int curLayer = 0;
9514 int i;
Romain Guy06882f82009-06-10 13:36:04 -07009515
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009516 if (DEBUG_LAYERS) {
9517 RuntimeException here = new RuntimeException("here");
9518 here.fillInStackTrace();
9519 Log.v(TAG, "Assigning layers", here);
9520 }
9521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009522 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07009523 WindowState w = mWindows.get(i);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009524 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
9525 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009526 curLayer += WINDOW_LAYER_MULTIPLIER;
9527 w.mLayer = curLayer;
9528 } else {
9529 curBaseLayer = curLayer = w.mBaseLayer;
9530 w.mLayer = curLayer;
9531 }
9532 if (w.mTargetAppToken != null) {
9533 w.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
9534 } else if (w.mAppToken != null) {
9535 w.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
9536 } else {
9537 w.mAnimLayer = w.mLayer;
9538 }
9539 if (w.mIsImWindow) {
9540 w.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07009541 } else if (w.mIsWallpaper) {
9542 w.mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009543 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009544 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009545 + w.mAnimLayer);
9546 //System.out.println(
9547 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
9548 }
9549 }
9550
9551 private boolean mInLayout = false;
9552 private final void performLayoutAndPlaceSurfacesLocked() {
9553 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07009554 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009555 throw new RuntimeException("Recursive call!");
9556 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009557 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009558 return;
9559 }
9560
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009561 if (mWaitingForConfig) {
9562 // Our configuration has changed (most likely rotation), but we
9563 // don't yet have the complete configuration to report to
9564 // applications. Don't do any window layout until we have it.
9565 return;
9566 }
9567
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009568 if (mDisplay == null) {
9569 // Not yet initialized, nothing to do.
9570 return;
9571 }
9572
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08009573 mInLayout = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009574 boolean recoveringMemory = false;
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08009575
9576 try {
9577 if (mForceRemoves != null) {
9578 recoveringMemory = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009579 // Wait a little bit for things to settle down, and off we go.
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08009580 for (int i=0; i<mForceRemoves.size(); i++) {
9581 WindowState ws = mForceRemoves.get(i);
9582 Slog.i(TAG, "Force removing: " + ws);
9583 removeWindowInnerLocked(ws.mSession, ws);
9584 }
9585 mForceRemoves = null;
9586 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
9587 Object tmp = new Object();
9588 synchronized (tmp) {
9589 try {
9590 tmp.wait(250);
9591 } catch (InterruptedException e) {
9592 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009593 }
9594 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08009595 } catch (RuntimeException e) {
9596 Slog.e(TAG, "Unhandled exception while force removing for memory", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009597 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08009598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009599 try {
9600 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Romain Guy06882f82009-06-10 13:36:04 -07009601
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009602 int N = mPendingRemove.size();
9603 if (N > 0) {
9604 if (mPendingRemoveTmp.length < N) {
9605 mPendingRemoveTmp = new WindowState[N+10];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009606 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009607 mPendingRemove.toArray(mPendingRemoveTmp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009608 mPendingRemove.clear();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009609 for (int i=0; i<N; i++) {
9610 WindowState w = mPendingRemoveTmp[i];
9611 removeWindowInnerLocked(w.mSession, w);
9612 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009613
9614 mInLayout = false;
9615 assignLayersLocked();
9616 mLayoutNeeded = true;
9617 performLayoutAndPlaceSurfacesLocked();
9618
9619 } else {
9620 mInLayout = false;
9621 if (mLayoutNeeded) {
9622 requestAnimationLocked(0);
9623 }
9624 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07009625 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07009626 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
9627 mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07009628 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009629 } catch (RuntimeException e) {
9630 mInLayout = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009631 Slog.e(TAG, "Unhandled exception while layout out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009632 }
9633 }
9634
Jeff Brown3a22cd92011-01-21 13:59:04 -08009635 private final int performLayoutLockedInner(boolean initial, boolean updateInputWindows) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009636 if (!mLayoutNeeded) {
9637 return 0;
9638 }
9639
9640 mLayoutNeeded = false;
9641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009642 final int dw = mDisplay.getWidth();
9643 final int dh = mDisplay.getHeight();
9644
9645 final int N = mWindows.size();
9646 int i;
9647
Joe Onorato8a9b2202010-02-26 18:56:32 -08009648 if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
Dianne Hackborn9b52a212009-12-11 14:51:35 -08009649 + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
9650
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009651 mPolicy.beginLayoutLw(dw, dh);
Romain Guy06882f82009-06-10 13:36:04 -07009652
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009653 int seq = mLayoutSeq+1;
9654 if (seq < 0) seq = 0;
9655 mLayoutSeq = seq;
9656
9657 // First perform layout of any root windows (not attached
9658 // to another window).
9659 int topAttached = -1;
9660 for (i = N-1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009661 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009662
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009663 // Don't do layout of a window if it is not visible, or
9664 // soon won't be visible, to avoid wasting time and funky
9665 // changes while a window is animating away.
9666 final AppWindowToken atoken = win.mAppToken;
9667 final boolean gone = win.mViewVisibility == View.GONE
9668 || !win.mRelayoutCalled
Dianne Hackbornff801ec2011-01-22 18:05:38 -08009669 || (atoken == null && win.mRootToken.hidden)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009670 || (atoken != null && atoken.hiddenRequested)
9671 || win.mAttachedHidden
9672 || win.mExiting || win.mDestroying;
9673
Dianne Hackborn1c24e952010-11-23 00:34:30 -08009674 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
9675 Slog.v(TAG, "First pass " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009676 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
9677 + " mLayoutAttached=" + win.mLayoutAttached);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08009678 if (gone) Slog.v(TAG, " (mViewVisibility="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009679 + win.mViewVisibility + " mRelayoutCalled="
9680 + win.mRelayoutCalled + " hidden="
9681 + win.mRootToken.hidden + " hiddenRequested="
9682 + (atoken != null && atoken.hiddenRequested)
9683 + " mAttachedHidden=" + win.mAttachedHidden);
9684 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009685
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009686 // If this view is GONE, then skip it -- keep the current
9687 // frame, and let the caller know so they can ignore it
9688 // if they want. (We do the normal layout for INVISIBLE
9689 // windows, since that means "perform layout as normal,
9690 // just don't display").
9691 if (!gone || !win.mHaveFrame) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009692 if (!win.mLayoutAttached) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009693 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08009694 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009695 win.mContentChanged = false;
9696 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009697 mPolicy.layoutWindowLw(win, win.mAttrs, null);
9698 win.mLayoutSeq = seq;
9699 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
9700 + win.mFrame + " mContainingFrame="
9701 + win.mContainingFrame + " mDisplayFrame="
9702 + win.mDisplayFrame);
9703 } else {
9704 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009705 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07009706 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009707 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009708
9709 // Now perform layout of attached windows, which usually
9710 // depend on the position of the window they are attached to.
9711 // XXX does not deal with windows that are attached to windows
9712 // that are themselves attached.
9713 for (i = topAttached; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009714 WindowState win = mWindows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009715
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009716 if (win.mLayoutAttached) {
9717 if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
9718 + " mHaveFrame=" + win.mHaveFrame
9719 + " mViewVisibility=" + win.mViewVisibility
9720 + " mRelayoutCalled=" + win.mRelayoutCalled);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08009721 // If this view is GONE, then skip it -- keep the current
9722 // frame, and let the caller know so they can ignore it
9723 // if they want. (We do the normal layout for INVISIBLE
9724 // windows, since that means "perform layout as normal,
9725 // just don't display").
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009726 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
9727 || !win.mHaveFrame) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009728 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08009729 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009730 win.mContentChanged = false;
9731 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009732 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
9733 win.mLayoutSeq = seq;
9734 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
9735 + win.mFrame + " mContainingFrame="
9736 + win.mContainingFrame + " mDisplayFrame="
9737 + win.mDisplayFrame);
9738 }
9739 }
9740 }
Jeff Brown349703e2010-06-22 01:27:15 -07009741
9742 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown3a22cd92011-01-21 13:59:04 -08009743 mInputMonitor.setUpdateInputWindowsNeededLw();
9744 if (updateInputWindows) {
Jeff Brown2e44b072011-01-24 15:21:56 -08009745 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08009746 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009747
9748 return mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009749 }
Romain Guy06882f82009-06-10 13:36:04 -07009750
Brad Fitzpatrick68044332010-11-22 18:19:48 -08009751 // "Something has changed! Let's make it correct now."
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009752 private final void performLayoutAndPlaceSurfacesLockedInner(
9753 boolean recoveringMemory) {
Joe Onorato34bcebc2010-07-07 18:05:01 -04009754 if (mDisplay == null) {
9755 Slog.i(TAG, "skipping performLayoutAndPlaceSurfacesLockedInner with no mDisplay");
9756 return;
9757 }
9758
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009759 final long currentTime = SystemClock.uptimeMillis();
9760 final int dw = mDisplay.getWidth();
9761 final int dh = mDisplay.getHeight();
9762
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009763 int i;
9764
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009765 if (mFocusMayChange) {
9766 mFocusMayChange = false;
Jeff Brown3a22cd92011-01-21 13:59:04 -08009767 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
9768 false /*updateInputWindows*/);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009769 }
9770
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009771 // Initialize state of exiting tokens.
9772 for (i=mExitingTokens.size()-1; i>=0; i--) {
9773 mExitingTokens.get(i).hasVisible = false;
9774 }
9775
9776 // Initialize state of exiting applications.
9777 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
9778 mExitingAppTokens.get(i).hasVisible = false;
9779 }
9780
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009781 boolean orientationChangeComplete = true;
9782 Session holdScreen = null;
9783 float screenBrightness = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009784 float buttonBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009785 boolean focusDisplayed = false;
9786 boolean animating = false;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009787 boolean createWatermark = false;
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009788 boolean updateRotation = false;
Dianne Hackborn50660e22011-02-02 17:12:25 -08009789 boolean screenRotationFinished = false;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009790
9791 if (mFxSession == null) {
9792 mFxSession = new SurfaceSession();
9793 createWatermark = true;
9794 }
9795
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08009796 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009797
9798 Surface.openTransaction();
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009799
9800 if (createWatermark) {
9801 createWatermark();
9802 }
9803 if (mWatermark != null) {
9804 mWatermark.positionSurface(dw, dh);
9805 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08009806 if (mStrictModeFlash != null) {
9807 mStrictModeFlash.positionSurface(dw, dh);
9808 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009809
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009810 try {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009811 boolean wallpaperForceHidingChanged = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009812 int repeats = 0;
9813 int changes = 0;
9814
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009815 do {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009816 repeats++;
9817 if (repeats > 6) {
9818 Slog.w(TAG, "Animation repeat aborted after too many iterations");
9819 mLayoutNeeded = false;
9820 break;
9821 }
9822
9823 if ((changes&(WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER
9824 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG
9825 | WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
9826 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
9827 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
9828 assignLayersLocked();
9829 mLayoutNeeded = true;
9830 }
9831 }
9832 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
9833 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08009834 if (updateOrientationFromAppTokensLocked(true)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009835 mLayoutNeeded = true;
9836 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
9837 }
9838 }
9839 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
9840 mLayoutNeeded = true;
9841 }
9842 }
9843
9844 // FIRST LOOP: Perform a layout, if needed.
9845 if (repeats < 4) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08009846 changes = performLayoutLockedInner(repeats == 0, false /*updateInputWindows*/);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009847 if (changes != 0) {
9848 continue;
9849 }
9850 } else {
9851 Slog.w(TAG, "Layout repeat skipped after too many iterations");
9852 changes = 0;
9853 }
9854
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009855 final int transactionSequence = ++mTransactionSequence;
9856
9857 // Update animations of all applications, including those
9858 // associated with exiting/removed apps
9859 boolean tokensAnimating = false;
9860 final int NAT = mAppTokens.size();
9861 for (i=0; i<NAT; i++) {
9862 if (mAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
9863 tokensAnimating = true;
9864 }
9865 }
9866 final int NEAT = mExitingAppTokens.size();
9867 for (i=0; i<NEAT; i++) {
9868 if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
9869 tokensAnimating = true;
9870 }
9871 }
9872
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009873 // SECOND LOOP: Execute animations and update visibility of windows.
9874
Joe Onorato8a9b2202010-02-26 18:56:32 -08009875 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009876 + transactionSequence + " tokensAnimating="
9877 + tokensAnimating);
9878
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009879 animating = tokensAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009880
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08009881 if (mScreenRotationAnimation != null) {
9882 if (mScreenRotationAnimation.isAnimating()) {
9883 if (mScreenRotationAnimation.stepAnimation(currentTime)) {
9884 animating = true;
9885 } else {
Dianne Hackborn50660e22011-02-02 17:12:25 -08009886 screenRotationFinished = true;
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009887 updateRotation = true;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08009888 }
9889 }
9890 }
9891
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009892 boolean tokenMayBeDrawn = false;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009893 boolean wallpaperMayChange = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009894 boolean forceHiding = false;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009895 WindowState windowDetachedWallpaper = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009896
9897 mPolicy.beginAnimationLw(dw, dh);
9898
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009899 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009900
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009901 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009902 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009903
9904 final WindowManager.LayoutParams attrs = w.mAttrs;
9905
9906 if (w.mSurface != null) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009907 // Take care of the window being ready to display.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009908 if (w.commitFinishDrawingLocked(currentTime)) {
9909 if ((w.mAttrs.flags
9910 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009911 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009912 "First draw done in potential wallpaper target " + w);
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009913 wallpaperMayChange = true;
9914 }
9915 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009916
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009917 final boolean wasAnimating = w.mAnimating;
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009918
9919 int animDw = dw;
9920 int animDh = dh;
9921
9922 // If the window has moved due to its containing
9923 // content frame changing, then we'd like to animate
9924 // it. The checks here are ordered by what is least
Joe Onorato3fe7f2f2010-11-20 13:48:58 -08009925 // likely to be true first.
Dianne Hackborn1c24e952010-11-23 00:34:30 -08009926 if (w.shouldAnimateMove()) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009927 // Frame has moved, containing content frame
9928 // has also moved, and we're not currently animating...
9929 // let's do something.
9930 Animation a = AnimationUtils.loadAnimation(mContext,
9931 com.android.internal.R.anim.window_move_from_decor);
9932 w.setAnimation(a);
9933 animDw = w.mLastFrame.left - w.mFrame.left;
9934 animDh = w.mLastFrame.top - w.mFrame.top;
9935 }
9936
9937 // Execute animation.
9938 final boolean nowAnimating = w.stepAnimationLocked(currentTime,
9939 animDw, animDh);
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009940
9941 // If this window is animating, make a note that we have
9942 // an animating window and take care of a request to run
9943 // a detached wallpaper animation.
9944 if (nowAnimating) {
9945 if (w.mAnimation != null && w.mAnimation.getDetachWallpaper()) {
9946 windowDetachedWallpaper = w;
9947 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009948 animating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009949 }
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009950
9951 // If this window's app token is running a detached wallpaper
9952 // animation, make a note so we can ensure the wallpaper is
9953 // displayed behind it.
9954 if (w.mAppToken != null && w.mAppToken.animation != null
9955 && w.mAppToken.animation.getDetachWallpaper()) {
9956 windowDetachedWallpaper = w;
9957 }
9958
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07009959 if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
9960 wallpaperMayChange = true;
9961 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009962
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009963 if (mPolicy.doesForceHide(w, attrs)) {
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009964 if (!wasAnimating && nowAnimating) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009965 if (DEBUG_VISIBILITY) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009966 "Animation started that could impact force hide: "
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009967 + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009968 wallpaperForceHidingChanged = true;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009969 mFocusMayChange = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009970 } else if (w.isReadyForDisplay() && w.mAnimation == null) {
9971 forceHiding = true;
9972 }
9973 } else if (mPolicy.canBeForceHidden(w, attrs)) {
9974 boolean changed;
9975 if (forceHiding) {
9976 changed = w.hideLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009977 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
9978 "Now policy hidden: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009979 } else {
9980 changed = w.showLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009981 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
9982 "Now policy shown: " + w);
9983 if (changed) {
9984 if (wallpaperForceHidingChanged
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009985 && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009986 // Assume we will need to animate. If
9987 // we don't (because the wallpaper will
9988 // stay with the lock screen), then we will
9989 // clean up later.
9990 Animation a = mPolicy.createForceHideEnterAnimation();
9991 if (a != null) {
9992 w.setAnimation(a);
9993 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009994 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009995 if (mCurrentFocus == null ||
9996 mCurrentFocus.mLayer < w.mLayer) {
9997 // We are showing on to of the current
9998 // focus, so re-evaluate focus to make
9999 // sure it is correct.
10000 mFocusMayChange = true;
10001 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010002 }
10003 }
10004 if (changed && (attrs.flags
10005 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
10006 wallpaperMayChange = true;
10007 }
10008 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010009
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010010 mPolicy.animatingWindowLw(w, attrs);
10011 }
10012
10013 final AppWindowToken atoken = w.mAppToken;
10014 if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
10015 if (atoken.lastTransactionSequence != transactionSequence) {
10016 atoken.lastTransactionSequence = transactionSequence;
10017 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
10018 atoken.startingDisplayed = false;
10019 }
10020 if ((w.isOnScreen() || w.mAttrs.type
10021 == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
10022 && !w.mExiting && !w.mDestroying) {
10023 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010024 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -070010025 + w.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010026 + ", isAnimating=" + w.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -070010027 if (!w.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010028 Slog.v(TAG, "Not displayed: s=" + w.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010029 + " pv=" + w.mPolicyVisibility
10030 + " dp=" + w.mDrawPending
10031 + " cdp=" + w.mCommitDrawPending
10032 + " ah=" + w.mAttachedHidden
10033 + " th=" + atoken.hiddenRequested
10034 + " a=" + w.mAnimating);
10035 }
10036 }
10037 if (w != atoken.startingWindow) {
10038 if (!atoken.freezingScreen || !w.mAppFreezing) {
10039 atoken.numInterestingWindows++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -070010040 if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010041 atoken.numDrawnWindows++;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010042 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010043 "tokenMayBeDrawn: " + atoken
10044 + " freezingScreen=" + atoken.freezingScreen
10045 + " mAppFreezing=" + w.mAppFreezing);
10046 tokenMayBeDrawn = true;
10047 }
10048 }
Dianne Hackborn7433e8a2009-09-27 13:21:20 -070010049 } else if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010050 atoken.startingDisplayed = true;
10051 }
10052 }
10053 } else if (w.mReadyToShow) {
10054 w.performShowLocked();
10055 }
10056 }
10057
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010058 changes |= mPolicy.finishAnimationLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010059
10060 if (tokenMayBeDrawn) {
10061 // See if any windows have been drawn, so they (and others
10062 // associated with them) can now be shown.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -080010063 final int NT = mAppTokens.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010064 for (i=0; i<NT; i++) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -080010065 AppWindowToken wtoken = mAppTokens.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010066 if (wtoken.freezingScreen) {
10067 int numInteresting = wtoken.numInterestingWindows;
10068 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010069 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010070 "allDrawn: " + wtoken
10071 + " interesting=" + numInteresting
10072 + " drawn=" + wtoken.numDrawnWindows);
10073 wtoken.showAllWindowsLocked();
10074 unsetAppFreezingScreenLocked(wtoken, false, true);
10075 orientationChangeComplete = true;
10076 }
10077 } else if (!wtoken.allDrawn) {
10078 int numInteresting = wtoken.numInterestingWindows;
10079 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010080 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010081 "allDrawn: " + wtoken
10082 + " interesting=" + numInteresting
10083 + " drawn=" + wtoken.numDrawnWindows);
10084 wtoken.allDrawn = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010085 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010086
10087 // We can now show all of the drawn windows!
10088 if (!mOpeningApps.contains(wtoken)) {
10089 wtoken.showAllWindowsLocked();
10090 }
10091 }
10092 }
10093 }
10094 }
10095
10096 // If we are ready to perform an app transition, check through
10097 // all of the app tokens to be shown and see if they are ready
10098 // to go.
10099 if (mAppTransitionReady) {
10100 int NN = mOpeningApps.size();
10101 boolean goodToGo = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010102 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010103 "Checking " + NN + " opening apps (frozen="
10104 + mDisplayFrozen + " timeout="
10105 + mAppTransitionTimeout + ")...");
10106 if (!mDisplayFrozen && !mAppTransitionTimeout) {
10107 // If the display isn't frozen, wait to do anything until
10108 // all of the apps are ready. Otherwise just go because
10109 // we'll unfreeze the display when everyone is ready.
10110 for (i=0; i<NN && goodToGo; i++) {
10111 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010112 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010113 "Check opening app" + wtoken + ": allDrawn="
10114 + wtoken.allDrawn + " startingDisplayed="
10115 + wtoken.startingDisplayed);
10116 if (!wtoken.allDrawn && !wtoken.startingDisplayed
10117 && !wtoken.startingMoved) {
10118 goodToGo = false;
10119 }
10120 }
10121 }
10122 if (goodToGo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010123 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010124 int transit = mNextAppTransition;
10125 if (mSkipAppTransitionAnimation) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070010126 transit = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010127 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070010128 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010129 mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010130 mAppTransitionRunning = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010131 mAppTransitionTimeout = false;
10132 mStartingIconInTransition = false;
10133 mSkipAppTransitionAnimation = false;
10134
10135 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
10136
Dianne Hackborna8f60182009-09-01 19:01:50 -070010137 // If there are applications waiting to come to the
10138 // top of the stack, now is the time to move their windows.
10139 // (Note that we don't do apps going to the bottom
10140 // here -- we want to keep their windows in the old
10141 // Z-order until the animation completes.)
10142 if (mToTopApps.size() > 0) {
10143 NN = mAppTokens.size();
10144 for (i=0; i<NN; i++) {
10145 AppWindowToken wtoken = mAppTokens.get(i);
10146 if (wtoken.sendingToTop) {
10147 wtoken.sendingToTop = false;
10148 moveAppWindowsLocked(wtoken, NN, false);
10149 }
10150 }
10151 mToTopApps.clear();
10152 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010153
Dianne Hackborn25994b42009-09-04 14:21:19 -070010154 WindowState oldWallpaper = mWallpaperTarget;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010155
Dianne Hackborn3be63c02009-08-20 19:31:38 -070010156 adjustWallpaperWindowsLocked();
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010157 wallpaperMayChange = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010158
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010159 // The top-most window will supply the layout params,
10160 // and we will determine it below.
10161 LayoutParams animLp = null;
10162 int bestAnimLayer = -1;
Dianne Hackborn08121bc2011-01-17 17:54:31 -080010163 boolean fullscreenAnim = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010164
Joe Onorato8a9b2202010-02-26 18:56:32 -080010165 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -070010166 "New wallpaper target=" + mWallpaperTarget
10167 + ", lower target=" + mLowerWallpaperTarget
10168 + ", upper target=" + mUpperWallpaperTarget);
Dianne Hackborn25994b42009-09-04 14:21:19 -070010169 int foundWallpapers = 0;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010170 // Do a first pass through the tokens for two
10171 // things:
10172 // (1) Determine if both the closing and opening
10173 // app token sets are wallpaper targets, in which
10174 // case special animations are needed
10175 // (since the wallpaper needs to stay static
10176 // behind them).
10177 // (2) Find the layout params of the top-most
10178 // application window in the tokens, which is
10179 // what will control the animation theme.
10180 final int NC = mClosingApps.size();
10181 NN = NC + mOpeningApps.size();
10182 for (i=0; i<NN; i++) {
10183 AppWindowToken wtoken;
10184 int mode;
10185 if (i < NC) {
10186 wtoken = mClosingApps.get(i);
10187 mode = 1;
10188 } else {
10189 wtoken = mOpeningApps.get(i-NC);
10190 mode = 2;
10191 }
10192 if (mLowerWallpaperTarget != null) {
10193 if (mLowerWallpaperTarget.mAppToken == wtoken
10194 || mUpperWallpaperTarget.mAppToken == wtoken) {
10195 foundWallpapers |= mode;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -070010196 }
10197 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010198 if (wtoken.appFullscreen) {
10199 WindowState ws = wtoken.findMainWindow();
10200 if (ws != null) {
10201 // If this is a compatibility mode
10202 // window, we will always use its anim.
10203 if ((ws.mAttrs.flags&FLAG_COMPATIBLE_WINDOW) != 0) {
10204 animLp = ws.mAttrs;
10205 bestAnimLayer = Integer.MAX_VALUE;
Dianne Hackborn08121bc2011-01-17 17:54:31 -080010206 } else if (!fullscreenAnim || ws.mLayer > bestAnimLayer) {
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010207 animLp = ws.mAttrs;
Dianne Hackborn08121bc2011-01-17 17:54:31 -080010208 bestAnimLayer = ws.mLayer;
10209 }
10210 fullscreenAnim = true;
10211 }
10212 } else if (!fullscreenAnim) {
10213 WindowState ws = wtoken.findMainWindow();
10214 if (ws != null) {
10215 if (ws.mLayer > bestAnimLayer) {
10216 animLp = ws.mAttrs;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010217 bestAnimLayer = ws.mLayer;
10218 }
Dianne Hackborn25994b42009-09-04 14:21:19 -070010219 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -070010220 }
10221 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010222
Dianne Hackborn25994b42009-09-04 14:21:19 -070010223 if (foundWallpapers == 3) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010224 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010225 "Wallpaper animation!");
10226 switch (transit) {
10227 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
10228 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
10229 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
10230 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
10231 break;
10232 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
10233 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
10234 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
10235 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
10236 break;
10237 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010238 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010239 "New transit: " + transit);
10240 } else if (oldWallpaper != null) {
10241 // We are transitioning from an activity with
10242 // a wallpaper to one without.
10243 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010244 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010245 "New transit away from wallpaper: " + transit);
10246 } else if (mWallpaperTarget != null) {
10247 // We are transitioning from an activity without
10248 // a wallpaper to now showing the wallpaper
10249 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010250 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -070010251 "New transit into wallpaper: " + transit);
10252 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010253
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010254 // If all closing windows are obscured, then there is
10255 // no need to do an animation. This is the case, for
10256 // example, when this transition is being done behind
10257 // the lock screen.
10258 if (!mPolicy.allowAppAnimationsLw()) {
10259 animLp = null;
10260 }
10261
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010262 NN = mOpeningApps.size();
10263 for (i=0; i<NN; i++) {
10264 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010265 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010266 "Now opening app" + wtoken);
10267 wtoken.reportedVisible = false;
10268 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -070010269 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010270 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010271 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010272 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010273 wtoken.showAllWindowsLocked();
10274 }
10275 NN = mClosingApps.size();
10276 for (i=0; i<NN; i++) {
10277 AppWindowToken wtoken = mClosingApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010278 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010279 "Now closing app" + wtoken);
10280 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -070010281 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070010282 setTokenVisibilityLocked(wtoken, animLp, false, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010283 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010284 wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010285 // Force the allDrawn flag, because we want to start
10286 // this guy's animations regardless of whether it's
10287 // gotten drawn.
10288 wtoken.allDrawn = true;
10289 }
10290
Dianne Hackborn8b571a82009-09-25 16:09:43 -070010291 mNextAppTransitionPackage = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010292
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010293 mOpeningApps.clear();
10294 mClosingApps.clear();
10295
10296 // This has changed the visibility of windows, so perform
10297 // a new layout to get them all up-to-date.
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -080010298 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT
10299 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010300 mLayoutNeeded = true;
Dianne Hackborn20583ff2009-07-27 21:51:05 -070010301 if (!moveInputMethodWindowsIfNeededLocked(true)) {
10302 assignLayersLocked();
10303 }
Jeff Brown3a22cd92011-01-21 13:59:04 -080010304 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
10305 false /*updateInputWindows*/);
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010306 mFocusMayChange = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010307 }
10308 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010309
Dianne Hackborn16064f92010-03-25 00:47:24 -070010310 int adjResult = 0;
10311
Dianne Hackborna8f60182009-09-01 19:01:50 -070010312 if (!animating && mAppTransitionRunning) {
10313 // We have finished the animation of an app transition. To do
10314 // this, we have delayed a lot of operations like showing and
10315 // hiding apps, moving apps in Z-order, etc. The app token list
10316 // reflects the correct Z-order, but the window list may now
10317 // be out of sync with it. So here we will just rebuild the
10318 // entire app window list. Fun!
10319 mAppTransitionRunning = false;
10320 // Clear information about apps that were moving.
10321 mToBottomApps.clear();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010322
Dianne Hackborna8f60182009-09-01 19:01:50 -070010323 rebuildAppWindowListLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010324 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn16064f92010-03-25 00:47:24 -070010325 adjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010326 moveInputMethodWindowsIfNeededLocked(false);
10327 wallpaperMayChange = true;
Suchi Amalapurapuc9568e32009-11-05 18:51:16 -080010328 // Since the window list has been rebuilt, focus might
10329 // have to be recomputed since the actual order of windows
10330 // might have changed again.
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010331 mFocusMayChange = true;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010332 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010333
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010334 if (wallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010335 // At this point, there was a window with a wallpaper that
10336 // was force hiding other windows behind it, but now it
10337 // is going away. This may be simple -- just animate
10338 // away the wallpaper and its window -- or it may be
10339 // hard -- the wallpaper now needs to be shown behind
10340 // something that was hidden.
10341 WindowState oldWallpaper = mWallpaperTarget;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010342 if (mLowerWallpaperTarget != null
10343 && mLowerWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010344 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010345 "wallpaperForceHiding changed with lower="
10346 + mLowerWallpaperTarget);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010347 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010348 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
10349 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
10350 if (mLowerWallpaperTarget.mAppToken.hidden) {
10351 // The lower target has become hidden before we
10352 // actually started the animation... let's completely
10353 // re-evaluate everything.
10354 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010355 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010356 }
10357 }
Dianne Hackborn16064f92010-03-25 00:47:24 -070010358 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010359 wallpaperMayChange = false;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010360 wallpaperForceHidingChanged = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010361 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010362 + " NEW: " + mWallpaperTarget
10363 + " LOWER: " + mLowerWallpaperTarget);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010364 if (mLowerWallpaperTarget == null) {
10365 // Whoops, we don't need a special wallpaper animation.
10366 // Clear them out.
10367 forceHiding = false;
10368 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -070010369 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010370 if (w.mSurface != null) {
10371 final WindowManager.LayoutParams attrs = w.mAttrs;
Suchi Amalapurapuc03d28b2009-10-28 14:32:05 -070010372 if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010373 if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010374 forceHiding = true;
10375 } else if (mPolicy.canBeForceHidden(w, attrs)) {
10376 if (!w.mAnimating) {
10377 // We set the animation above so it
10378 // is not yet running.
10379 w.clearAnimation();
10380 }
10381 }
10382 }
10383 }
10384 }
10385 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010386
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -080010387 if (mWindowDetachedWallpaper != windowDetachedWallpaper) {
10388 if (DEBUG_WALLPAPER) Slog.v(TAG,
10389 "Detached wallpaper changed from " + mWindowDetachedWallpaper
10390 + windowDetachedWallpaper);
10391 mWindowDetachedWallpaper = windowDetachedWallpaper;
10392 wallpaperMayChange = true;
10393 }
10394
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010395 if (wallpaperMayChange) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010396 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010397 "Wallpaper may change! Adjusting");
Dianne Hackborn16064f92010-03-25 00:47:24 -070010398 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010399 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010400
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010401 if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010402 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010403 "Wallpaper layer changed: assigning layers + relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010404 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010405 assignLayersLocked();
10406 } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010407 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010408 "Wallpaper visibility changed: relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010409 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010410 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010411
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010412 if (mFocusMayChange) {
10413 mFocusMayChange = false;
Jeff Brown3a22cd92011-01-21 13:59:04 -080010414 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
10415 false /*updateInputWindows*/)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010416 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010417 adjResult = 0;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010418 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010419 }
10420
10421 if (mLayoutNeeded) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010422 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010423 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010424
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010425 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
10426 + Integer.toHexString(changes));
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010427 } while (changes != 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010428
10429 // THIRD LOOP: Update the surfaces of all windows.
10430
10431 final boolean someoneLosingFocus = mLosingFocus.size() != 0;
10432
10433 boolean obscured = false;
10434 boolean blurring = false;
10435 boolean dimming = false;
10436 boolean covered = false;
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010437 boolean syswin = false;
Dianne Hackbornac1471a2011-02-03 13:46:06 -080010438 boolean backgroundFillerWasShown = mBackgroundFillerTarget != null;
10439 mBackgroundFillerTarget = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010440
Dianne Hackbornbdd52b22009-09-02 21:46:19 -070010441 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010442
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010443 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -070010444 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010445
10446 boolean displayed = false;
10447 final WindowManager.LayoutParams attrs = w.mAttrs;
10448 final int attrFlags = attrs.flags;
10449
10450 if (w.mSurface != null) {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010451 // XXX NOTE: The logic here could be improved. We have
10452 // the decision about whether to resize a window separated
10453 // from whether to hide the surface. This can cause us to
10454 // resize a surface even if we are going to hide it. You
10455 // can see this by (1) holding device in landscape mode on
10456 // home screen; (2) tapping browser icon (device will rotate
10457 // to landscape; (3) tap home. The wallpaper will be resized
10458 // in step 2 but then immediately hidden, causing us to
10459 // have to resize and then redraw it again in step 3. It
10460 // would be nice to figure out how to avoid this, but it is
10461 // difficult because we do need to resize surfaces in some
10462 // cases while they are hidden such as when first showing a
10463 // window.
10464
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010465 w.computeShownFrameLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010466 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010467 TAG, "Placing surface #" + i + " " + w.mSurface
10468 + ": new=" + w.mShownFrame + ", old="
10469 + w.mLastShownFrame);
10470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010471 int width, height;
10472 if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010473 // for a scaled surface, we just want to use
10474 // the requested size.
10475 width = w.mRequestedWidth;
10476 height = w.mRequestedHeight;
10477 w.mLastRequestedWidth = width;
10478 w.mLastRequestedHeight = height;
10479 w.mLastShownFrame.set(w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010480 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010481 width = w.mShownFrame.width();
10482 height = w.mShownFrame.height();
10483 w.mLastShownFrame.set(w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010484 }
10485
Jeff Brownfbae7222011-01-23 13:07:25 -080010486 if (w.mSurface != null) {
10487 if (w.mSurfaceX != w.mShownFrame.left
10488 || w.mSurfaceY != w.mShownFrame.top) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010489 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010490 if (SHOW_TRANSACTIONS) logSurface(w,
Jeff Brownfbae7222011-01-23 13:07:25 -080010491 "POS " + w.mShownFrame.left
10492 + ", " + w.mShownFrame.top, null);
10493 w.mSurfaceX = w.mShownFrame.left;
10494 w.mSurfaceY = w.mShownFrame.top;
10495 w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
10496 } catch (RuntimeException e) {
10497 Slog.w(TAG, "Error positioning surface of " + w
10498 + " pos=(" + w.mShownFrame.left
10499 + "," + w.mShownFrame.top + ")", e);
10500 if (!recoveringMemory) {
10501 reclaimSomeSurfaceMemoryLocked(w, "position");
10502 }
10503 }
10504 }
10505
10506 if (width < 1) {
10507 width = 1;
10508 }
10509 if (height < 1) {
10510 height = 1;
10511 }
10512
10513 if (w.mSurfaceW != width || w.mSurfaceH != height) {
10514 try {
10515 if (SHOW_TRANSACTIONS) logSurface(w,
10516 "SIZE " + w.mShownFrame.width() + "x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010517 + w.mShownFrame.height(), null);
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010518 w.mSurfaceResized = true;
Dianne Hackborn16064f92010-03-25 00:47:24 -070010519 w.mSurfaceW = width;
10520 w.mSurfaceH = height;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010521 w.mSurface.setSize(width, height);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010522 } catch (RuntimeException e) {
10523 // If something goes wrong with the surface (such
10524 // as running out of memory), don't take down the
10525 // entire system.
Jeff Brownfbae7222011-01-23 13:07:25 -080010526 Slog.e(TAG, "Error resizing surface of " + w
10527 + " size=(" + width + "x" + height + ")", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010528 if (!recoveringMemory) {
10529 reclaimSomeSurfaceMemoryLocked(w, "size");
10530 }
10531 }
10532 }
10533 }
Jeff Brownfbae7222011-01-23 13:07:25 -080010534
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010535 if (!w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010536 w.mContentInsetsChanged =
10537 !w.mLastContentInsets.equals(w.mContentInsets);
10538 w.mVisibleInsetsChanged =
10539 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010540 boolean configChanged =
10541 w.mConfiguration != mCurConfiguration
10542 && (w.mConfiguration == null
10543 || mCurConfiguration.diff(w.mConfiguration) != 0);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010544 if (DEBUG_CONFIGURATION && configChanged) {
10545 Slog.v(TAG, "Win " + w + " config changed: "
10546 + mCurConfiguration);
10547 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010548 if (localLOGV) Slog.v(TAG, "Resizing " + w
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010549 + ": configChanged=" + configChanged
10550 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
Jeff Brownfbae7222011-01-23 13:07:25 -080010551 boolean frameChanged = !w.mLastFrame.equals(w.mFrame);
10552 if (frameChanged
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010553 || w.mContentInsetsChanged
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010554 || w.mVisibleInsetsChanged
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010555 || w.mSurfaceResized
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010556 || configChanged) {
Jeff Brownfbae7222011-01-23 13:07:25 -080010557 if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
10558 Slog.v(TAG, "Resize reasons: "
10559 + "frameChanged=" + frameChanged
10560 + " contentInsetsChanged=" + w.mContentInsetsChanged
10561 + " visibleInsetsChanged=" + w.mVisibleInsetsChanged
10562 + " surfaceResized=" + w.mSurfaceResized
10563 + " configChanged=" + configChanged);
10564 }
10565
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010566 w.mLastFrame.set(w.mFrame);
10567 w.mLastContentInsets.set(w.mContentInsets);
10568 w.mLastVisibleInsets.set(w.mVisibleInsets);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010569 // If the screen is currently frozen, then keep
10570 // it frozen until this window draws at its new
10571 // orientation.
10572 if (mDisplayFrozen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010573 if (DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010574 "Resizing while display frozen: " + w);
10575 w.mOrientationChanging = true;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010576 if (!mWindowsFreezingScreen) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010577 mWindowsFreezingScreen = true;
10578 // XXX should probably keep timeout from
10579 // when we first froze the display.
10580 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
10581 mH.sendMessageDelayed(mH.obtainMessage(
10582 H.WINDOW_FREEZE_TIMEOUT), 2000);
10583 }
10584 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010585 // If the orientation is changing, then we need to
10586 // hold off on unfreezing the display until this
10587 // window has been redrawn; to do that, we need
10588 // to go through the process of getting informed
10589 // by the application when it has finished drawing.
10590 if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010591 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010592 "Orientation start waiting for draw in "
10593 + w + ", surface " + w.mSurface);
10594 w.mDrawPending = true;
10595 w.mCommitDrawPending = false;
10596 w.mReadyToShow = false;
10597 if (w.mAppToken != null) {
10598 w.mAppToken.allDrawn = false;
10599 }
10600 }
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010601 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010602 "Resizing window " + w + " to " + w.mFrame);
10603 mResizingWindows.add(w);
10604 } else if (w.mOrientationChanging) {
10605 if (!w.mDrawPending && !w.mCommitDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010606 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010607 "Orientation not waiting for draw in "
10608 + w + ", surface " + w.mSurface);
10609 w.mOrientationChanging = false;
10610 }
10611 }
10612 }
10613
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010614 if (w.mAttachedHidden || !w.isReadyForDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010615 if (!w.mLastHidden) {
10616 //dump();
10617 w.mLastHidden = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010618 if (SHOW_TRANSACTIONS) logSurface(w,
10619 "HIDE (performLayout)", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010620 if (w.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010621 w.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010622 try {
10623 w.mSurface.hide();
10624 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010625 Slog.w(TAG, "Exception hiding surface in " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010626 }
10627 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010628 }
10629 // If we are waiting for this window to handle an
10630 // orientation change, well, it is hidden, so
10631 // doesn't really matter. Note that this does
10632 // introduce a potential glitch if the window
10633 // becomes unhidden before it has drawn for the
10634 // new orientation.
10635 if (w.mOrientationChanging) {
10636 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010637 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010638 "Orientation change skips hidden " + w);
10639 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010640 } else if (w.mLastLayer != w.mAnimLayer
10641 || w.mLastAlpha != w.mShownAlpha
10642 || w.mLastDsDx != w.mDsDx
10643 || w.mLastDtDx != w.mDtDx
10644 || w.mLastDsDy != w.mDsDy
10645 || w.mLastDtDy != w.mDtDy
10646 || w.mLastHScale != w.mHScale
10647 || w.mLastVScale != w.mVScale
10648 || w.mLastHidden) {
10649 displayed = true;
10650 w.mLastAlpha = w.mShownAlpha;
10651 w.mLastLayer = w.mAnimLayer;
10652 w.mLastDsDx = w.mDsDx;
10653 w.mLastDtDx = w.mDtDx;
10654 w.mLastDsDy = w.mDsDy;
10655 w.mLastDtDy = w.mDtDy;
10656 w.mLastHScale = w.mHScale;
10657 w.mLastVScale = w.mVScale;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010658 if (SHOW_TRANSACTIONS) logSurface(w,
10659 "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010660 + " matrix=[" + (w.mDsDx*w.mHScale)
10661 + "," + (w.mDtDx*w.mVScale)
10662 + "][" + (w.mDsDy*w.mHScale)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010663 + "," + (w.mDtDy*w.mVScale) + "]", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010664 if (w.mSurface != null) {
10665 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010666 w.mSurfaceAlpha = w.mShownAlpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010667 w.mSurface.setAlpha(w.mShownAlpha);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010668 w.mSurfaceLayer = w.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010669 w.mSurface.setLayer(w.mAnimLayer);
10670 w.mSurface.setMatrix(
10671 w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
10672 w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
10673 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010674 Slog.w(TAG, "Error updating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010675 if (!recoveringMemory) {
10676 reclaimSomeSurfaceMemoryLocked(w, "update");
10677 }
10678 }
10679 }
10680
10681 if (w.mLastHidden && !w.mDrawPending
10682 && !w.mCommitDrawPending
10683 && !w.mReadyToShow) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010684 if (SHOW_TRANSACTIONS) logSurface(w,
10685 "SHOW (performLayout)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010686 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010687 + " during relayout");
10688 if (showSurfaceRobustlyLocked(w)) {
10689 w.mHasDrawn = true;
10690 w.mLastHidden = false;
10691 } else {
10692 w.mOrientationChanging = false;
10693 }
10694 }
10695 if (w.mSurface != null) {
10696 w.mToken.hasVisible = true;
10697 }
10698 } else {
10699 displayed = true;
10700 }
10701
10702 if (displayed) {
10703 if (!covered) {
Romain Guy980a9382010-01-08 15:06:28 -080010704 if (attrs.width == LayoutParams.MATCH_PARENT
10705 && attrs.height == LayoutParams.MATCH_PARENT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010706 covered = true;
10707 }
10708 }
10709 if (w.mOrientationChanging) {
10710 if (w.mDrawPending || w.mCommitDrawPending) {
10711 orientationChangeComplete = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010712 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010713 "Orientation continue waiting for draw in " + w);
10714 } else {
10715 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010716 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010717 "Orientation change complete in " + w);
10718 }
10719 }
10720 w.mToken.hasVisible = true;
10721 }
10722 } else if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010723 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010724 "Orientation change skips hidden " + w);
10725 w.mOrientationChanging = false;
10726 }
10727
Dianne Hackborn0f761d62010-11-30 22:06:10 -080010728 if (w.mContentChanged) {
10729 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
10730 w.mContentChanged = false;
10731 }
10732
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010733 final boolean canBeSeen = w.isDisplayedLw();
10734
10735 if (someoneLosingFocus && w == mCurrentFocus && canBeSeen) {
10736 focusDisplayed = true;
10737 }
10738
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070010739 final boolean obscuredChanged = w.mObscured != obscured;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010740
Dianne Hackbornac1471a2011-02-03 13:46:06 -080010741 if (mBackgroundFillerTarget != null) {
10742 if (w.isAnimating()) {
10743 // Background filler is below all other windows that
10744 // are animating.
10745 mBackgroundFillerTarget = w;
10746 } else if (w.mIsWallpaper) {
10747 mBackgroundFillerTarget = w;
10748 }
10749 }
10750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010751 // Update effect.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010752 if (!(w.mObscured=obscured)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010753 if (w.mSurface != null) {
10754 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
10755 holdScreen = w.mSession;
10756 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010757 if (!syswin && w.mAttrs.screenBrightness >= 0
10758 && screenBrightness < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010759 screenBrightness = w.mAttrs.screenBrightness;
10760 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010761 if (!syswin && w.mAttrs.buttonBrightness >= 0
10762 && buttonBrightness < 0) {
10763 buttonBrightness = w.mAttrs.buttonBrightness;
10764 }
Mike Lockwood46af6a82010-03-09 08:28:22 -050010765 if (canBeSeen
10766 && (attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
10767 || attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD
10768 || attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_ERROR)) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010769 syswin = true;
10770 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010771 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010772
Dianne Hackborn25994b42009-09-04 14:21:19 -070010773 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
10774 if (opaqueDrawn && w.isFullscreen(dw, dh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010775 // This window completely covers everything behind it,
10776 // so we want to leave all of them as unblurred (for
10777 // performance reasons).
10778 obscured = true;
Dianne Hackbornac1471a2011-02-03 13:46:06 -080010779 } else if (w.needsBackgroundFiller(dw, dh) && (canBeSeen || w.isAnimating())) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010780 // This window is in compatibility mode, and needs background filler.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010781 obscured = true;
Dianne Hackbornac1471a2011-02-03 13:46:06 -080010782 mBackgroundFillerTarget = w;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010783 } else if (canBeSeen && !obscured &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010784 (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010785 if (localLOGV) Slog.v(TAG, "Win " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010786 + ": blurring=" + blurring
10787 + " obscured=" + obscured
10788 + " displayed=" + displayed);
10789 if ((attrFlags&FLAG_DIM_BEHIND) != 0) {
10790 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010791 //Slog.i(TAG, "DIM BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010792 dimming = true;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010793 if (mDimAnimator == null) {
10794 mDimAnimator = new DimAnimator(mFxSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010795 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010796 mDimAnimator.show(dw, dh);
Dianne Hackborn1c24e952010-11-23 00:34:30 -080010797 mDimAnimator.updateParameters(mContext.getResources(),
10798 w, currentTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010799 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010800 }
10801 if ((attrFlags&FLAG_BLUR_BEHIND) != 0) {
10802 if (!blurring) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010803 //Slog.i(TAG, "BLUR BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010804 blurring = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010805 if (mBlurSurface == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010806 try {
Romain Guy06882f82009-06-10 13:36:04 -070010807 mBlurSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080010808 "BlurSurface",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010809 -1, 16, 16,
10810 PixelFormat.OPAQUE,
10811 Surface.FX_SURFACE_BLUR);
10812 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010813 Slog.e(TAG, "Exception creating Blur surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010814 }
Dianne Hackbornac1471a2011-02-03 13:46:06 -080010815 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10816 + mBlurSurface + ": CREATE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010817 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010818 if (mBlurSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010819 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10820 + mBlurSurface + ": pos=(0,0) (" +
10821 dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010822 mBlurSurface.setPosition(0, 0);
10823 mBlurSurface.setSize(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010824 mBlurSurface.setLayer(w.mAnimLayer-2);
10825 if (!mBlurShown) {
10826 try {
10827 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10828 + mBlurSurface + ": SHOW");
10829 mBlurSurface.show();
10830 } catch (RuntimeException e) {
10831 Slog.w(TAG, "Failure showing blur surface", e);
10832 }
10833 mBlurShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010834 }
10835 }
10836 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010837 }
10838 }
10839 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010840
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070010841 if (obscuredChanged && mWallpaperTarget == w) {
10842 // This is the wallpaper target and its obscured state
10843 // changed... make sure the current wallaper's visibility
10844 // has been updated accordingly.
10845 updateWallpaperVisibilityLocked();
10846 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010847 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010848
Dianne Hackbornac1471a2011-02-03 13:46:06 -080010849 if (mBackgroundFillerTarget != null) {
10850 if (mBackgroundFillerSurface == null) {
10851 try {
10852 mBackgroundFillerSurface = new Surface(mFxSession, 0,
10853 "BackGroundFiller",
10854 0, dw, dh,
10855 PixelFormat.OPAQUE,
10856 Surface.FX_SURFACE_NORMAL);
10857 } catch (Exception e) {
10858 Slog.e(TAG, "Exception creating filler surface", e);
10859 }
10860 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BG FILLER "
10861 + mBackgroundFillerSurface + ": CREATE");
10862 }
10863 try {
10864 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BG FILLER "
10865 + mBackgroundFillerSurface + " SHOW: pos=(0,0) ("
10866 + dw + "x" + dh + ") layer="
10867 + (mBackgroundFillerTarget.mLayer - 1));
10868 mBackgroundFillerSurface.setPosition(0, 0);
10869 mBackgroundFillerSurface.setSize(dw, dh);
10870 // Using the same layer as Dim because they will never be shown at the
10871 // same time. NOTE: we do NOT use mAnimLayer, because we don't
10872 // want this surface dragged up in front of stuff that is animating.
10873 mBackgroundFillerSurface.setLayer(mBackgroundFillerTarget.mLayer - 1);
10874 mBackgroundFillerSurface.show();
10875 } catch (RuntimeException e) {
10876 Slog.e(TAG, "Exception showing filler surface");
10877 }
10878 } else if (backgroundFillerWasShown) {
10879 mBackgroundFillerTarget = null;
10880 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BG FILLER "
10881 + mBackgroundFillerSurface + " HIDE");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010882 try {
10883 mBackgroundFillerSurface.hide();
10884 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010885 Slog.e(TAG, "Exception hiding filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010886 }
10887 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010888
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010889 if (mDimAnimator != null && mDimAnimator.mDimShown) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010890 animating |= mDimAnimator.updateSurface(dimming, currentTime,
10891 mDisplayFrozen || !mPolicy.isScreenOn());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010892 }
Romain Guy06882f82009-06-10 13:36:04 -070010893
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010894 if (!blurring && mBlurShown) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010895 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR " + mBlurSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010896 + ": HIDE");
10897 try {
10898 mBlurSurface.hide();
10899 } catch (IllegalArgumentException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010900 Slog.w(TAG, "Illegal argument exception hiding blur surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010901 }
10902 mBlurShown = false;
10903 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010904 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010905 Slog.e(TAG, "Unhandled exception in Window Manager", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010906 }
10907
10908 Surface.closeTransaction();
Romain Guy06882f82009-06-10 13:36:04 -070010909
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -080010910 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
10911
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010912 if (mWatermark != null) {
10913 mWatermark.drawIfNeeded();
10914 }
10915
Joe Onorato8a9b2202010-02-26 18:56:32 -080010916 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010917 "With display frozen, orientationChangeComplete="
10918 + orientationChangeComplete);
10919 if (orientationChangeComplete) {
10920 if (mWindowsFreezingScreen) {
10921 mWindowsFreezingScreen = false;
10922 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
10923 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010924 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010925 }
Romain Guy06882f82009-06-10 13:36:04 -070010926
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010927 i = mResizingWindows.size();
10928 if (i > 0) {
10929 do {
10930 i--;
10931 WindowState win = mResizingWindows.get(i);
10932 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010933 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
10934 "Reporting new frame to " + win + ": " + win.mFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010935 int diff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010936 boolean configChanged =
10937 win.mConfiguration != mCurConfiguration
10938 && (win.mConfiguration == null
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010939 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0);
10940 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
10941 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010942 Slog.i(TAG, "Sending new config to window " + win + ": "
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010943 + win.mFrame.width() + "x" + win.mFrame.height()
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010944 + " / " + mCurConfiguration + " / 0x"
10945 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010946 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010947 win.mConfiguration = mCurConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010948 win.mClient.resized(win.mFrame.width(),
10949 win.mFrame.height(), win.mLastContentInsets,
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010950 win.mLastVisibleInsets, win.mDrawPending,
10951 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010952 win.mContentInsetsChanged = false;
10953 win.mVisibleInsetsChanged = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010954 win.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010955 } catch (RemoteException e) {
10956 win.mOrientationChanging = false;
10957 }
10958 } while (i > 0);
10959 mResizingWindows.clear();
10960 }
Romain Guy06882f82009-06-10 13:36:04 -070010961
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010962 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010963 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010964 i = mDestroySurface.size();
10965 if (i > 0) {
10966 do {
10967 i--;
10968 WindowState win = mDestroySurface.get(i);
10969 win.mDestroying = false;
10970 if (mInputMethodWindow == win) {
10971 mInputMethodWindow = null;
10972 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010973 if (win == mWallpaperTarget) {
10974 wallpaperDestroyed = true;
10975 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010976 win.destroySurfaceLocked();
10977 } while (i > 0);
10978 mDestroySurface.clear();
10979 }
10980
10981 // Time to remove any exiting tokens?
10982 for (i=mExitingTokens.size()-1; i>=0; i--) {
10983 WindowToken token = mExitingTokens.get(i);
10984 if (!token.hasVisible) {
10985 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070010986 if (token.windowType == TYPE_WALLPAPER) {
10987 mWallpaperTokens.remove(token);
10988 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010989 }
10990 }
10991
10992 // Time to remove any exiting applications?
10993 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
10994 AppWindowToken token = mExitingAppTokens.get(i);
10995 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -070010996 // Make sure there is no animation running on this token,
10997 // so any windows associated with it will be removed as
10998 // soon as their animations are complete
10999 token.animation = null;
11000 token.animating = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -080011001 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
11002 "performLayout: App token exiting now removed" + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011003 mAppTokens.remove(token);
11004 mExitingAppTokens.remove(i);
11005 }
11006 }
11007
Dianne Hackborna8f60182009-09-01 19:01:50 -070011008 boolean needRelayout = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011009
Dianne Hackborna8f60182009-09-01 19:01:50 -070011010 if (!animating && mAppTransitionRunning) {
11011 // We have finished the animation of an app transition. To do
11012 // this, we have delayed a lot of operations like showing and
11013 // hiding apps, moving apps in Z-order, etc. The app token list
11014 // reflects the correct Z-order, but the window list may now
11015 // be out of sync with it. So here we will just rebuild the
11016 // entire app window list. Fun!
11017 mAppTransitionRunning = false;
11018 needRelayout = true;
11019 rebuildAppWindowListLocked();
Dianne Hackborn16064f92010-03-25 00:47:24 -070011020 assignLayersLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070011021 // Clear information about apps that were moving.
11022 mToBottomApps.clear();
11023 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011025 if (focusDisplayed) {
11026 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
11027 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011028 if (wallpaperDestroyed) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011029 needRelayout = adjustWallpaperWindowsLocked() != 0;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011030 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070011031 if (needRelayout) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070011032 requestAnimationLocked(0);
11033 } else if (animating) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011034 requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
11035 }
Jeff Browneb857f12010-07-16 10:06:33 -070011036
Jeff Brown3a22cd92011-01-21 13:59:04 -080011037 // Finally update all input windows now that the window changes have stabilized.
Jeff Brown2e44b072011-01-24 15:21:56 -080011038 mInputMonitor.updateInputWindowsLw(true /*force*/);
Jeff Browneb857f12010-07-16 10:06:33 -070011039
Jeff Brown8e03b752010-06-13 19:16:55 -070011040 setHoldScreenLocked(holdScreen != null);
Dianne Hackborn428ecb62011-01-26 14:53:23 -080011041 if (!mDisplayFrozen) {
11042 if (screenBrightness < 0 || screenBrightness > 1.0f) {
11043 mPowerManager.setScreenBrightnessOverride(-1);
11044 } else {
11045 mPowerManager.setScreenBrightnessOverride((int)
11046 (screenBrightness * Power.BRIGHTNESS_ON));
11047 }
11048 if (buttonBrightness < 0 || buttonBrightness > 1.0f) {
11049 mPowerManager.setButtonBrightnessOverride(-1);
11050 } else {
11051 mPowerManager.setButtonBrightnessOverride((int)
11052 (buttonBrightness * Power.BRIGHTNESS_ON));
11053 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050011054 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011055 if (holdScreen != mHoldingScreenOn) {
11056 mHoldingScreenOn = holdScreen;
11057 Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
11058 mH.sendMessage(m);
11059 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011060
Dianne Hackborn93e462b2009-09-15 22:50:40 -070011061 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080011062 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Dianne Hackborn93e462b2009-09-15 22:50:40 -070011063 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
11064 LocalPowerManager.BUTTON_EVENT, true);
11065 mTurnOnScreen = false;
11066 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -080011067
Dianne Hackborn50660e22011-02-02 17:12:25 -080011068 if (screenRotationFinished && mScreenRotationAnimation != null) {
11069 mScreenRotationAnimation.kill();
11070 mScreenRotationAnimation = null;
11071 }
11072
Dianne Hackborn89ba6752011-01-23 16:51:16 -080011073 if (updateRotation) {
11074 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
11075 boolean changed = setRotationUncheckedLocked(
11076 WindowManagerPolicy.USE_LAST_ROTATION, 0, false);
11077 if (changed) {
Dianne Hackborn3e4f9d042011-02-04 14:05:55 -080011078 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackborn89ba6752011-01-23 16:51:16 -080011079 }
11080 }
11081
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -080011082 // Check to see if we are now in a state where the screen should
11083 // be enabled, because the window obscured flags have changed.
11084 enableScreenIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011085 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070011086
11087 /**
11088 * Must be called with the main window manager lock held.
11089 */
11090 void setHoldScreenLocked(boolean holding) {
11091 boolean state = mHoldingScreenWakeLock.isHeld();
11092 if (holding != state) {
11093 if (holding) {
11094 mHoldingScreenWakeLock.acquire();
11095 } else {
11096 mPolicy.screenOnStoppedLw();
11097 mHoldingScreenWakeLock.release();
11098 }
11099 }
11100 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011101
11102 void requestAnimationLocked(long delay) {
11103 if (!mAnimationPending) {
11104 mAnimationPending = true;
11105 mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
11106 }
11107 }
Romain Guy06882f82009-06-10 13:36:04 -070011108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011109 /**
11110 * Have the surface flinger show a surface, robustly dealing with
11111 * error conditions. In particular, if there is not enough memory
11112 * to show the surface, then we will try to get rid of other surfaces
11113 * in order to succeed.
Romain Guy06882f82009-06-10 13:36:04 -070011114 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011115 * @return Returns true if the surface was successfully shown.
11116 */
11117 boolean showSurfaceRobustlyLocked(WindowState win) {
11118 try {
11119 if (win.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011120 win.mSurfaceShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011121 win.mSurface.show();
Dianne Hackborn93e462b2009-09-15 22:50:40 -070011122 if (win.mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080011123 if (DEBUG_VISIBILITY) Slog.v(TAG,
11124 "Show surface turning screen on: " + win);
Dianne Hackborn93e462b2009-09-15 22:50:40 -070011125 win.mTurnOnScreen = false;
11126 mTurnOnScreen = true;
11127 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011128 }
11129 return true;
11130 } catch (RuntimeException e) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -080011131 Slog.w(TAG, "Failure showing surface " + win.mSurface + " in " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011132 }
Romain Guy06882f82009-06-10 13:36:04 -070011133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011134 reclaimSomeSurfaceMemoryLocked(win, "show");
Romain Guy06882f82009-06-10 13:36:04 -070011135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011136 return false;
11137 }
Romain Guy06882f82009-06-10 13:36:04 -070011138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011139 void reclaimSomeSurfaceMemoryLocked(WindowState win, String operation) {
11140 final Surface surface = win.mSurface;
Romain Guy06882f82009-06-10 13:36:04 -070011141
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011142 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, win.toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011143 win.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -070011144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011145 if (mForceRemoves == null) {
11146 mForceRemoves = new ArrayList<WindowState>();
11147 }
Romain Guy06882f82009-06-10 13:36:04 -070011148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011149 long callingIdentity = Binder.clearCallingIdentity();
11150 try {
11151 // There was some problem... first, do a sanity check of the
11152 // window list to make sure we haven't left any dangling surfaces
11153 // around.
11154 int N = mWindows.size();
11155 boolean leakedSurface = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011156 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011157 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -070011158 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011159 if (ws.mSurface != null) {
11160 if (!mSessions.contains(ws.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011161 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011162 + ws + " surface=" + ws.mSurface
11163 + " token=" + win.mToken
11164 + " pid=" + ws.mSession.mPid
11165 + " uid=" + ws.mSession.mUid);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -080011166 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011167 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070011168 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011169 ws.mSurface = null;
11170 mForceRemoves.add(ws);
11171 i--;
11172 N--;
11173 leakedSurface = true;
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -080011174 } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011175 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011176 + ws + " surface=" + ws.mSurface
11177 + " token=" + win.mAppToken);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -080011178 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011179 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070011180 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011181 ws.mSurface = null;
11182 leakedSurface = true;
11183 }
11184 }
11185 }
Romain Guy06882f82009-06-10 13:36:04 -070011186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011187 boolean killedApps = false;
11188 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011189 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011190 SparseIntArray pidCandidates = new SparseIntArray();
11191 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -070011192 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011193 if (ws.mSurface != null) {
11194 pidCandidates.append(ws.mSession.mPid, ws.mSession.mPid);
11195 }
11196 }
11197 if (pidCandidates.size() > 0) {
11198 int[] pids = new int[pidCandidates.size()];
11199 for (int i=0; i<pids.length; i++) {
11200 pids[i] = pidCandidates.keyAt(i);
11201 }
11202 try {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -070011203 if (mActivityManager.killPids(pids, "Free memory")) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011204 killedApps = true;
11205 }
11206 } catch (RemoteException e) {
11207 }
11208 }
11209 }
Romain Guy06882f82009-06-10 13:36:04 -070011210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011211 if (leakedSurface || killedApps) {
11212 // We managed to reclaim some memory, so get rid of the trouble
11213 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -080011214 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011215 if (surface != null) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -080011216 if (SHOW_TRANSACTIONS) logSurface(win, "RECOVER DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011217 surface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070011218 win.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011219 win.mSurface = null;
11220 }
Romain Guy06882f82009-06-10 13:36:04 -070011221
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011222 try {
11223 win.mClient.dispatchGetNewSurface();
11224 } catch (RemoteException e) {
11225 }
11226 }
11227 } finally {
11228 Binder.restoreCallingIdentity(callingIdentity);
11229 }
11230 }
Romain Guy06882f82009-06-10 13:36:04 -070011231
Jeff Brown3a22cd92011-01-21 13:59:04 -080011232 private boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011233 WindowState newFocus = computeFocusedWindowLocked();
11234 if (mCurrentFocus != newFocus) {
11235 // This check makes sure that we don't already have the focus
11236 // change message pending.
11237 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
11238 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011239 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011240 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
11241 final WindowState oldFocus = mCurrentFocus;
11242 mCurrentFocus = newFocus;
11243 mLosingFocus.remove(newFocus);
Romain Guy06882f82009-06-10 13:36:04 -070011244
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011245 final WindowState imWindow = mInputMethodWindow;
11246 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080011247 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011248 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080011249 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
11250 mLayoutNeeded = true;
11251 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011252 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Jeff Brown3a22cd92011-01-21 13:59:04 -080011253 performLayoutLockedInner(true /*initial*/, updateInputWindows);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080011254 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
11255 // Client will do the layout, but we need to assign layers
11256 // for handleNewWindowLocked() below.
11257 assignLayersLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011258 }
11259 }
Jeff Brown349703e2010-06-22 01:27:15 -070011260
11261 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
11262 // If we defer assigning layers, then the caller is responsible for
11263 // doing this part.
Jeff Brown3a22cd92011-01-21 13:59:04 -080011264 finishUpdateFocusedWindowAfterAssignLayersLocked(updateInputWindows);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080011265 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011266 return true;
11267 }
11268 return false;
11269 }
Jeff Brown349703e2010-06-22 01:27:15 -070011270
Jeff Brown3a22cd92011-01-21 13:59:04 -080011271 private void finishUpdateFocusedWindowAfterAssignLayersLocked(boolean updateInputWindows) {
11272 mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows);
Jeff Brown349703e2010-06-22 01:27:15 -070011273 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011274
11275 private WindowState computeFocusedWindowLocked() {
11276 WindowState result = null;
11277 WindowState win;
11278
11279 int i = mWindows.size() - 1;
11280 int nextAppIndex = mAppTokens.size()-1;
11281 WindowToken nextApp = nextAppIndex >= 0
11282 ? mAppTokens.get(nextAppIndex) : null;
11283
11284 while (i >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -070011285 win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011286
Joe Onorato8a9b2202010-02-26 18:56:32 -080011287 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011288 TAG, "Looking for focus: " + i
11289 + " = " + win
11290 + ", flags=" + win.mAttrs.flags
11291 + ", canReceive=" + win.canReceiveKeys());
11292
11293 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -070011294
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011295 // If this window's application has been removed, just skip it.
11296 if (thisApp != null && thisApp.removed) {
11297 i--;
11298 continue;
11299 }
Romain Guy06882f82009-06-10 13:36:04 -070011300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011301 // If there is a focused app, don't allow focus to go to any
11302 // windows below it. If this is an application window, step
11303 // through the app tokens until we find its app.
11304 if (thisApp != null && nextApp != null && thisApp != nextApp
11305 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
11306 int origAppIndex = nextAppIndex;
11307 while (nextAppIndex > 0) {
11308 if (nextApp == mFocusedApp) {
11309 // Whoops, we are below the focused app... no focus
11310 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -080011311 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011312 TAG, "Reached focused app: " + mFocusedApp);
11313 return null;
11314 }
11315 nextAppIndex--;
11316 nextApp = mAppTokens.get(nextAppIndex);
11317 if (nextApp == thisApp) {
11318 break;
11319 }
11320 }
11321 if (thisApp != nextApp) {
11322 // Uh oh, the app token doesn't exist! This shouldn't
11323 // happen, but if it does we can get totally hosed...
11324 // so restart at the original app.
11325 nextAppIndex = origAppIndex;
11326 nextApp = mAppTokens.get(nextAppIndex);
11327 }
11328 }
11329
11330 // Dispatch to this window if it is wants key events.
11331 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011332 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011333 TAG, "Found focus @ " + i + " = " + win);
11334 result = win;
11335 break;
11336 }
11337
11338 i--;
11339 }
11340
11341 return result;
11342 }
11343
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -080011344 private void startFreezingDisplayLocked(boolean inTransaction) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011345 if (mDisplayFrozen) {
11346 return;
11347 }
Romain Guy06882f82009-06-10 13:36:04 -070011348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011349 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -070011350
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011351 long now = SystemClock.uptimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011352 //Slog.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011353 if (mFreezeGcPending != 0) {
11354 if (now > (mFreezeGcPending+1000)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011355 //Slog.i(TAG, "Gc! " + now + " > " + (mFreezeGcPending+1000));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011356 mH.removeMessages(H.FORCE_GC);
11357 Runtime.getRuntime().gc();
11358 mFreezeGcPending = now;
11359 }
11360 } else {
11361 mFreezeGcPending = now;
11362 }
Romain Guy06882f82009-06-10 13:36:04 -070011363
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011364 mDisplayFrozen = true;
Jeff Brown349703e2010-06-22 01:27:15 -070011365
Jeff Brown00fa7bd2010-07-02 15:37:36 -070011366 mInputMonitor.freezeInputDispatchingLw();
Jeff Brown349703e2010-06-22 01:27:15 -070011367
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070011368 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
11369 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011370 mNextAppTransitionPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011371 mAppTransitionReady = true;
11372 }
Romain Guy06882f82009-06-10 13:36:04 -070011373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011374 if (PROFILE_ORIENTATION) {
11375 File file = new File("/data/system/frozen");
11376 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
11377 }
Dianne Hackborna1111872010-11-23 20:55:11 -080011378
11379 if (CUSTOM_SCREEN_ROTATION) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080011380 if (mScreenRotationAnimation != null && mScreenRotationAnimation.isAnimating()) {
11381 mScreenRotationAnimation.kill();
11382 mScreenRotationAnimation = null;
11383 }
Dianne Hackborna1111872010-11-23 20:55:11 -080011384 if (mScreenRotationAnimation == null) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080011385 mScreenRotationAnimation = new ScreenRotationAnimation(mContext,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -080011386 mDisplay, mFxSession, inTransaction);
Dianne Hackborna1111872010-11-23 20:55:11 -080011387 }
11388 } else {
11389 Surface.freezeDisplay(0);
11390 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011391 }
Romain Guy06882f82009-06-10 13:36:04 -070011392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011393 private void stopFreezingDisplayLocked() {
11394 if (!mDisplayFrozen) {
11395 return;
11396 }
Romain Guy06882f82009-06-10 13:36:04 -070011397
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011398 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
11399 return;
11400 }
11401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011402 mDisplayFrozen = false;
11403 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
11404 if (PROFILE_ORIENTATION) {
11405 Debug.stopMethodTracing();
11406 }
Dianne Hackborna1111872010-11-23 20:55:11 -080011407
Dianne Hackborn89ba6752011-01-23 16:51:16 -080011408 boolean updateRotation = false;
11409
Dianne Hackborna1111872010-11-23 20:55:11 -080011410 if (CUSTOM_SCREEN_ROTATION) {
11411 if (mScreenRotationAnimation != null) {
Dianne Hackborn50660e22011-02-02 17:12:25 -080011412 if (mScreenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080011413 mTransitionAnimationScale)) {
11414 requestAnimationLocked(0);
11415 } else {
11416 mScreenRotationAnimation = null;
Dianne Hackborn89ba6752011-01-23 16:51:16 -080011417 updateRotation = true;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080011418 }
Dianne Hackborna1111872010-11-23 20:55:11 -080011419 }
11420 } else {
11421 Surface.unfreezeDisplay(0);
11422 }
Romain Guy06882f82009-06-10 13:36:04 -070011423
Jeff Brown00fa7bd2010-07-02 15:37:36 -070011424 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011425
Dianne Hackborn420829e2011-01-28 11:30:35 -080011426 boolean configChanged;
11427
Christopher Tateb696aee2010-04-02 19:08:30 -070011428 // While the display is frozen we don't re-compute the orientation
11429 // to avoid inconsistent states. However, something interesting
11430 // could have actually changed during that time so re-evaluate it
11431 // now to catch that.
Dianne Hackborn420829e2011-01-28 11:30:35 -080011432 configChanged = updateOrientationFromAppTokensLocked(false);
Christopher Tateb696aee2010-04-02 19:08:30 -070011433
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011434 // A little kludge: a lot could have happened while the
11435 // display was frozen, so now that we are coming back we
11436 // do a gc so that any remote references the system
11437 // processes holds on others can be released if they are
11438 // no longer needed.
11439 mH.removeMessages(H.FORCE_GC);
11440 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
11441 2000);
Romain Guy06882f82009-06-10 13:36:04 -070011442
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011443 mScreenFrozenLock.release();
Dianne Hackborn89ba6752011-01-23 16:51:16 -080011444
11445 if (updateRotation) {
11446 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Dianne Hackborn420829e2011-01-28 11:30:35 -080011447 configChanged |= setRotationUncheckedLocked(
Dianne Hackborn89ba6752011-01-23 16:51:16 -080011448 WindowManagerPolicy.USE_LAST_ROTATION, 0, false);
Dianne Hackborn420829e2011-01-28 11:30:35 -080011449 }
11450
11451 if (configChanged) {
11452 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackborn89ba6752011-01-23 16:51:16 -080011453 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011454 }
Romain Guy06882f82009-06-10 13:36:04 -070011455
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011456 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
11457 DisplayMetrics dm) {
11458 if (index < tokens.length) {
11459 String str = tokens[index];
11460 if (str != null && str.length() > 0) {
11461 try {
11462 int val = Integer.parseInt(str);
11463 return val;
11464 } catch (Exception e) {
11465 }
11466 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011467 }
11468 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
11469 return defDps;
11470 }
11471 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
11472 return val;
11473 }
11474
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011475 static class Watermark {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011476 final String[] mTokens;
11477 final String mText;
11478 final Paint mTextPaint;
11479 final int mTextWidth;
11480 final int mTextHeight;
11481 final int mTextAscent;
11482 final int mTextDescent;
11483 final int mDeltaX;
11484 final int mDeltaY;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011485
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011486 Surface mSurface;
11487 int mLastDW;
11488 int mLastDH;
11489 boolean mDrawNeeded;
11490
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011491 Watermark(Display display, SurfaceSession session, String[] tokens) {
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011492 final DisplayMetrics dm = new DisplayMetrics();
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011493 display.getMetrics(dm);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011494
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011495 if (false) {
11496 Log.i(TAG, "*********************** WATERMARK");
11497 for (int i=0; i<tokens.length; i++) {
11498 Log.i(TAG, " TOKEN #" + i + ": " + tokens[i]);
11499 }
11500 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011501
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011502 mTokens = tokens;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011503
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011504 StringBuilder builder = new StringBuilder(32);
11505 int len = mTokens[0].length();
11506 len = len & ~1;
11507 for (int i=0; i<len; i+=2) {
11508 int c1 = mTokens[0].charAt(i);
11509 int c2 = mTokens[0].charAt(i+1);
11510 if (c1 >= 'a' && c1 <= 'f') c1 = c1 - 'a' + 10;
11511 else if (c1 >= 'A' && c1 <= 'F') c1 = c1 - 'A' + 10;
11512 else c1 -= '0';
11513 if (c2 >= 'a' && c2 <= 'f') c2 = c2 - 'a' + 10;
11514 else if (c2 >= 'A' && c2 <= 'F') c2 = c2 - 'A' + 10;
11515 else c2 -= '0';
11516 builder.append((char)(255-((c1*16)+c2)));
11517 }
11518 mText = builder.toString();
11519 if (false) {
11520 Log.i(TAG, "Final text: " + mText);
11521 }
11522
11523 int fontSize = getPropertyInt(tokens, 1,
11524 TypedValue.COMPLEX_UNIT_DIP, 20, dm);
11525
11526 mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
11527 mTextPaint.setTextSize(fontSize);
11528 mTextPaint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD));
11529
11530 FontMetricsInt fm = mTextPaint.getFontMetricsInt();
11531 mTextWidth = (int)mTextPaint.measureText(mText);
11532 mTextAscent = fm.ascent;
11533 mTextDescent = fm.descent;
11534 mTextHeight = fm.descent - fm.ascent;
11535
11536 mDeltaX = getPropertyInt(tokens, 2,
11537 TypedValue.COMPLEX_UNIT_PX, mTextWidth*2, dm);
11538 mDeltaY = getPropertyInt(tokens, 3,
11539 TypedValue.COMPLEX_UNIT_PX, mTextHeight*3, dm);
11540 int shadowColor = getPropertyInt(tokens, 4,
11541 TypedValue.COMPLEX_UNIT_PX, 0xb0000000, dm);
11542 int color = getPropertyInt(tokens, 5,
11543 TypedValue.COMPLEX_UNIT_PX, 0x60ffffff, dm);
11544 int shadowRadius = getPropertyInt(tokens, 6,
11545 TypedValue.COMPLEX_UNIT_PX, 7, dm);
11546 int shadowDx = getPropertyInt(tokens, 8,
11547 TypedValue.COMPLEX_UNIT_PX, 0, dm);
11548 int shadowDy = getPropertyInt(tokens, 9,
11549 TypedValue.COMPLEX_UNIT_PX, 0, dm);
11550
11551 mTextPaint.setColor(color);
11552 mTextPaint.setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011553
11554 try {
11555 mSurface = new Surface(session, 0,
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011556 "WatermarkSurface", -1, 1, 1, PixelFormat.TRANSLUCENT, 0);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011557 mSurface.setLayer(TYPE_LAYER_MULTIPLIER*100);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011558 mSurface.setPosition(0, 0);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011559 mSurface.show();
11560 } catch (OutOfResourcesException e) {
11561 }
11562 }
11563
11564 void positionSurface(int dw, int dh) {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011565 if (mLastDW != dw || mLastDH != dh) {
11566 mLastDW = dw;
11567 mLastDH = dh;
11568 mSurface.setSize(dw, dh);
11569 mDrawNeeded = true;
11570 }
11571 }
11572
11573 void drawIfNeeded() {
11574 if (mDrawNeeded) {
11575 final int dw = mLastDW;
11576 final int dh = mLastDH;
11577
11578 mDrawNeeded = false;
11579 Rect dirty = new Rect(0, 0, dw, dh);
11580 Canvas c = null;
11581 try {
11582 c = mSurface.lockCanvas(dirty);
11583 } catch (IllegalArgumentException e) {
11584 } catch (OutOfResourcesException e) {
11585 }
11586 if (c != null) {
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011587 c.drawColor(0, PorterDuff.Mode.CLEAR);
11588
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011589 int deltaX = mDeltaX;
11590 int deltaY = mDeltaY;
11591
11592 // deltaX shouldn't be close to a round fraction of our
11593 // x step, or else things will line up too much.
11594 int div = (dw+mTextWidth)/deltaX;
11595 int rem = (dw+mTextWidth) - (div*deltaX);
11596 int qdelta = deltaX/4;
11597 if (rem < qdelta || rem > (deltaX-qdelta)) {
11598 deltaX += deltaX/3;
11599 }
11600
11601 int y = -mTextHeight;
11602 int x = -mTextWidth;
11603 while (y < (dh+mTextHeight)) {
11604 c.drawText(mText, x, y, mTextPaint);
11605 x += deltaX;
11606 if (x >= dw) {
11607 x -= (dw+mTextWidth);
11608 y += deltaY;
11609 }
11610 }
11611 mSurface.unlockCanvasAndPost(c);
11612 }
11613 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011614 }
11615 }
11616
11617 void createWatermark() {
11618 if (mWatermark != null) {
11619 return;
11620 }
11621
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011622 File file = new File("/system/etc/setup.conf");
11623 FileInputStream in = null;
11624 try {
11625 in = new FileInputStream(file);
11626 DataInputStream ind = new DataInputStream(in);
11627 String line = ind.readLine();
11628 if (line != null) {
11629 String[] toks = line.split("%");
11630 if (toks != null && toks.length > 0) {
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011631 mWatermark = new Watermark(mDisplay, mFxSession, toks);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011632 }
11633 }
11634 } catch (FileNotFoundException e) {
11635 } catch (IOException e) {
11636 } finally {
11637 if (in != null) {
11638 try {
11639 in.close();
11640 } catch (IOException e) {
11641 }
11642 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011643 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011644 }
11645
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011646 @Override
Joe Onorato664644d2011-01-23 17:53:23 -080011647 public void statusBarVisibilityChanged(int visibility) {
11648 synchronized (mWindowMap) {
11649 final int N = mWindows.size();
11650 for (int i = 0; i < N; i++) {
11651 WindowState ws = mWindows.get(i);
11652 try {
11653 if (ws.getAttrs().hasSystemUiListeners) {
11654 ws.mClient.dispatchSystemUiVisibilityChanged(visibility);
11655 }
11656 } catch (RemoteException e) {
11657 // so sorry
11658 }
11659 }
11660 }
11661 }
11662
11663 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011664 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11665 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
11666 != PackageManager.PERMISSION_GRANTED) {
11667 pw.println("Permission Denial: can't dump WindowManager from from pid="
11668 + Binder.getCallingPid()
11669 + ", uid=" + Binder.getCallingUid());
11670 return;
11671 }
Romain Guy06882f82009-06-10 13:36:04 -070011672
Jeff Brown00fa7bd2010-07-02 15:37:36 -070011673 mInputManager.dump(pw);
Dianne Hackborna2e92262010-03-02 17:19:29 -080011674 pw.println(" ");
11675
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011676 synchronized(mWindowMap) {
11677 pw.println("Current Window Manager state:");
11678 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -070011679 WindowState w = mWindows.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011680 pw.print(" Window #"); pw.print(i); pw.print(' ');
11681 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011682 w.dump(pw, " ");
11683 }
11684 if (mInputMethodDialogs.size() > 0) {
11685 pw.println(" ");
11686 pw.println(" Input method dialogs:");
11687 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
11688 WindowState w = mInputMethodDialogs.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011689 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011690 }
11691 }
11692 if (mPendingRemove.size() > 0) {
11693 pw.println(" ");
11694 pw.println(" Remove pending for:");
11695 for (int i=mPendingRemove.size()-1; i>=0; i--) {
11696 WindowState w = mPendingRemove.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011697 pw.print(" Remove #"); pw.print(i); pw.print(' ');
11698 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011699 w.dump(pw, " ");
11700 }
11701 }
11702 if (mForceRemoves != null && mForceRemoves.size() > 0) {
11703 pw.println(" ");
11704 pw.println(" Windows force removing:");
11705 for (int i=mForceRemoves.size()-1; i>=0; i--) {
11706 WindowState w = mForceRemoves.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011707 pw.print(" Removing #"); pw.print(i); pw.print(' ');
11708 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011709 w.dump(pw, " ");
11710 }
11711 }
11712 if (mDestroySurface.size() > 0) {
11713 pw.println(" ");
11714 pw.println(" Windows waiting to destroy their surface:");
11715 for (int i=mDestroySurface.size()-1; i>=0; i--) {
11716 WindowState w = mDestroySurface.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011717 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
11718 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011719 w.dump(pw, " ");
11720 }
11721 }
11722 if (mLosingFocus.size() > 0) {
11723 pw.println(" ");
11724 pw.println(" Windows losing focus:");
11725 for (int i=mLosingFocus.size()-1; i>=0; i--) {
11726 WindowState w = mLosingFocus.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011727 pw.print(" Losing #"); pw.print(i); pw.print(' ');
11728 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011729 w.dump(pw, " ");
11730 }
11731 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011732 if (mResizingWindows.size() > 0) {
11733 pw.println(" ");
11734 pw.println(" Windows waiting to resize:");
11735 for (int i=mResizingWindows.size()-1; i>=0; i--) {
11736 WindowState w = mResizingWindows.get(i);
11737 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
11738 pw.print(w); pw.println(":");
11739 w.dump(pw, " ");
11740 }
11741 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011742 if (mSessions.size() > 0) {
11743 pw.println(" ");
11744 pw.println(" All active sessions:");
11745 Iterator<Session> it = mSessions.iterator();
11746 while (it.hasNext()) {
11747 Session s = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011748 pw.print(" Session "); pw.print(s); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011749 s.dump(pw, " ");
11750 }
11751 }
11752 if (mTokenMap.size() > 0) {
11753 pw.println(" ");
11754 pw.println(" All tokens:");
11755 Iterator<WindowToken> it = mTokenMap.values().iterator();
11756 while (it.hasNext()) {
11757 WindowToken token = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011758 pw.print(" Token "); pw.print(token.token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011759 token.dump(pw, " ");
11760 }
11761 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070011762 if (mWallpaperTokens.size() > 0) {
11763 pw.println(" ");
11764 pw.println(" Wallpaper tokens:");
11765 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
11766 WindowToken token = mWallpaperTokens.get(i);
11767 pw.print(" Wallpaper #"); pw.print(i);
11768 pw.print(' '); pw.print(token); pw.println(':');
11769 token.dump(pw, " ");
11770 }
11771 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011772 if (mAppTokens.size() > 0) {
11773 pw.println(" ");
11774 pw.println(" Application tokens in Z order:");
11775 for (int i=mAppTokens.size()-1; i>=0; i--) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011776 pw.print(" App #"); pw.print(i); pw.print(": ");
11777 pw.println(mAppTokens.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011778 }
11779 }
11780 if (mFinishedStarting.size() > 0) {
11781 pw.println(" ");
11782 pw.println(" Finishing start of application tokens:");
11783 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
11784 WindowToken token = mFinishedStarting.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011785 pw.print(" Finished Starting #"); pw.print(i);
11786 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011787 token.dump(pw, " ");
11788 }
11789 }
11790 if (mExitingTokens.size() > 0) {
11791 pw.println(" ");
11792 pw.println(" Exiting tokens:");
11793 for (int i=mExitingTokens.size()-1; i>=0; i--) {
11794 WindowToken token = mExitingTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011795 pw.print(" Exiting #"); pw.print(i);
11796 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011797 token.dump(pw, " ");
11798 }
11799 }
11800 if (mExitingAppTokens.size() > 0) {
11801 pw.println(" ");
11802 pw.println(" Exiting application tokens:");
11803 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
11804 WindowToken token = mExitingAppTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011805 pw.print(" Exiting App #"); pw.print(i);
11806 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011807 token.dump(pw, " ");
11808 }
11809 }
11810 pw.println(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011811 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
11812 pw.print(" mLastFocus="); pw.println(mLastFocus);
11813 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
11814 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
11815 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
Dianne Hackbornf21adf62009-08-13 10:20:21 -070011816 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011817 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
11818 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
11819 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
11820 }
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -080011821 if (mWindowDetachedWallpaper != null) {
11822 pw.print(" mWindowDetachedWallpaper="); pw.println(mWindowDetachedWallpaper);
11823 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011824 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
11825 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
11826 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011827 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
11828 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
11829 pw.print(" mLayoutNeeded="); pw.print(mLayoutNeeded);
11830 pw.print(" mBlurShown="); pw.println(mBlurShown);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011831 if (mDimAnimator != null) {
11832 mDimAnimator.printTo(pw);
11833 } else {
Dianne Hackborna2e92262010-03-02 17:19:29 -080011834 pw.println( " no DimAnimator ");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011835 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011836 pw.print(" mInputMethodAnimLayerAdjustment=");
Dianne Hackborn759a39e2009-08-09 17:20:27 -070011837 pw.print(mInputMethodAnimLayerAdjustment);
11838 pw.print(" mWallpaperAnimLayerAdjustment=");
11839 pw.println(mWallpaperAnimLayerAdjustment);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011840 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
11841 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011842 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
11843 pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011844 pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
11845 pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011846 pw.print(" mRotation="); pw.print(mRotation);
11847 pw.print(", mForcedAppOrientation="); pw.print(mForcedAppOrientation);
11848 pw.print(", mRequestedRotation="); pw.println(mRequestedRotation);
Dianne Hackborn89ba6752011-01-23 16:51:16 -080011849 pw.print(" mDeferredRotation="); pw.print(mDeferredRotation);
11850 pw.print(", mDeferredRotationAnimFlags="); pw.print(mDeferredRotationAnimFlags);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011851 pw.print(" mAnimationPending="); pw.print(mAnimationPending);
11852 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
11853 pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale);
11854 pw.print(" mNextAppTransition=0x");
11855 pw.print(Integer.toHexString(mNextAppTransition));
11856 pw.print(", mAppTransitionReady="); pw.print(mAppTransitionReady);
Dianne Hackborna8f60182009-09-01 19:01:50 -070011857 pw.print(", mAppTransitionRunning="); pw.print(mAppTransitionRunning);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011858 pw.print(", mAppTransitionTimeout="); pw.println( mAppTransitionTimeout);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011859 if (mNextAppTransitionPackage != null) {
11860 pw.print(" mNextAppTransitionPackage=");
11861 pw.print(mNextAppTransitionPackage);
11862 pw.print(", mNextAppTransitionEnter=0x");
11863 pw.print(Integer.toHexString(mNextAppTransitionEnter));
11864 pw.print(", mNextAppTransitionExit=0x");
11865 pw.print(Integer.toHexString(mNextAppTransitionExit));
11866 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011867 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
11868 pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
11869 if (mOpeningApps.size() > 0) {
11870 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
11871 }
11872 if (mClosingApps.size() > 0) {
11873 pw.print(" mClosingApps="); pw.println(mClosingApps);
11874 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070011875 if (mToTopApps.size() > 0) {
11876 pw.print(" mToTopApps="); pw.println(mToTopApps);
11877 }
11878 if (mToBottomApps.size() > 0) {
11879 pw.print(" mToBottomApps="); pw.println(mToBottomApps);
11880 }
Dianne Hackborn87fc3082010-12-03 13:09:12 -080011881 if (mDisplay != null) {
11882 pw.print(" DisplayWidth="); pw.print(mDisplay.getWidth());
11883 pw.print(" DisplayHeight="); pw.println(mDisplay.getHeight());
11884 } else {
11885 pw.println(" NO DISPLAY");
11886 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -080011887 pw.println(" Policy:");
11888 mPolicy.dump(" ", fd, pw, args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011889 }
11890 }
11891
Jeff Brown349703e2010-06-22 01:27:15 -070011892 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011893 public void monitor() {
11894 synchronized (mWindowMap) { }
Mike Lockwood983ee092009-11-22 01:42:24 -050011895 synchronized (mKeyguardTokenWatcher) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070011896 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011897
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011898 /**
11899 * DimAnimator class that controls the dim animation. This holds the surface and
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011900 * all state used for dim animation.
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011901 */
11902 private static class DimAnimator {
11903 Surface mDimSurface;
11904 boolean mDimShown = false;
11905 float mDimCurrentAlpha;
11906 float mDimTargetAlpha;
11907 float mDimDeltaPerMs;
11908 long mLastDimAnimTime;
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011909
11910 int mLastDimWidth, mLastDimHeight;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011911
11912 DimAnimator (SurfaceSession session) {
11913 if (mDimSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011914 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011915 + mDimSurface + ": CREATE");
11916 try {
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080011917 mDimSurface = new Surface(session, 0,
11918 "DimSurface",
11919 -1, 16, 16, PixelFormat.OPAQUE,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011920 Surface.FX_SURFACE_DIM);
Maciej Białka9ee5c222010-03-24 10:25:40 +010011921 mDimSurface.setAlpha(0.0f);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011922 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011923 Slog.e(TAG, "Exception creating Dim surface", e);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011924 }
11925 }
11926 }
11927
11928 /**
11929 * Show the dim surface.
11930 */
11931 void show(int dw, int dh) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011932 if (!mDimShown) {
11933 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
11934 dw + "x" + dh + ")");
11935 mDimShown = true;
11936 try {
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011937 mLastDimWidth = dw;
11938 mLastDimHeight = dh;
Dianne Hackborn16064f92010-03-25 00:47:24 -070011939 mDimSurface.setPosition(0, 0);
11940 mDimSurface.setSize(dw, dh);
11941 mDimSurface.show();
11942 } catch (RuntimeException e) {
11943 Slog.w(TAG, "Failure showing dim surface", e);
11944 }
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011945 } else if (mLastDimWidth != dw || mLastDimHeight != dh) {
11946 mLastDimWidth = dw;
11947 mLastDimHeight = dh;
11948 mDimSurface.setSize(dw, dh);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011949 }
11950 }
11951
11952 /**
11953 * Set's the dim surface's layer and update dim parameters that will be used in
11954 * {@link updateSurface} after all windows are examined.
11955 */
Dianne Hackborn1c24e952010-11-23 00:34:30 -080011956 void updateParameters(Resources res, WindowState w, long currentTime) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011957 mDimSurface.setLayer(w.mAnimLayer-1);
11958
11959 final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011960 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011961 + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011962 if (mDimTargetAlpha != target) {
11963 // If the desired dim level has changed, then
11964 // start an animation to it.
11965 mLastDimAnimTime = currentTime;
11966 long duration = (w.mAnimating && w.mAnimation != null)
11967 ? w.mAnimation.computeDurationHint()
11968 : DEFAULT_DIM_DURATION;
11969 if (target > mDimTargetAlpha) {
Dianne Hackborn1c24e952010-11-23 00:34:30 -080011970 TypedValue tv = new TypedValue();
11971 res.getValue(com.android.internal.R.fraction.config_dimBehindFadeDuration,
11972 tv, true);
11973 if (tv.type == TypedValue.TYPE_FRACTION) {
11974 duration = (long)tv.getFraction((float)duration, (float)duration);
11975 } else if (tv.type >= TypedValue.TYPE_FIRST_INT
11976 && tv.type <= TypedValue.TYPE_LAST_INT) {
11977 duration = tv.data;
11978 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011979 }
11980 if (duration < 1) {
11981 // Don't divide by zero
11982 duration = 1;
11983 }
11984 mDimTargetAlpha = target;
11985 mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration;
11986 }
11987 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011988
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011989 /**
11990 * Updating the surface's alpha. Returns true if the animation continues, or returns
11991 * false when the animation is finished and the dim surface is hidden.
11992 */
11993 boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) {
11994 if (!dimming) {
11995 if (mDimTargetAlpha != 0) {
11996 mLastDimAnimTime = currentTime;
11997 mDimTargetAlpha = 0;
11998 mDimDeltaPerMs = (-mDimCurrentAlpha) / DEFAULT_DIM_DURATION;
11999 }
12000 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080012001
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012002 boolean animating = false;
12003 if (mLastDimAnimTime != 0) {
12004 mDimCurrentAlpha += mDimDeltaPerMs
12005 * (currentTime-mLastDimAnimTime);
12006 boolean more = true;
12007 if (displayFrozen) {
12008 // If the display is frozen, there is no reason to animate.
12009 more = false;
12010 } else if (mDimDeltaPerMs > 0) {
12011 if (mDimCurrentAlpha > mDimTargetAlpha) {
12012 more = false;
12013 }
12014 } else if (mDimDeltaPerMs < 0) {
12015 if (mDimCurrentAlpha < mDimTargetAlpha) {
12016 more = false;
12017 }
12018 } else {
12019 more = false;
12020 }
12021
12022 // Do we need to continue animating?
12023 if (more) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012024 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012025 + mDimSurface + ": alpha=" + mDimCurrentAlpha);
12026 mLastDimAnimTime = currentTime;
12027 mDimSurface.setAlpha(mDimCurrentAlpha);
12028 animating = true;
12029 } else {
12030 mDimCurrentAlpha = mDimTargetAlpha;
12031 mLastDimAnimTime = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012032 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012033 + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
12034 mDimSurface.setAlpha(mDimCurrentAlpha);
12035 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012036 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012037 + ": HIDE");
12038 try {
12039 mDimSurface.hide();
12040 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012041 Slog.w(TAG, "Illegal argument exception hiding dim surface");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012042 }
12043 mDimShown = false;
12044 }
12045 }
12046 }
12047 return animating;
12048 }
12049
12050 public void printTo(PrintWriter pw) {
12051 pw.print(" mDimShown="); pw.print(mDimShown);
12052 pw.print(" current="); pw.print(mDimCurrentAlpha);
12053 pw.print(" target="); pw.print(mDimTargetAlpha);
12054 pw.print(" delta="); pw.print(mDimDeltaPerMs);
12055 pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
12056 }
12057 }
12058
12059 /**
12060 * Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
12061 * This is used for opening/closing transition for apps in compatible mode.
12062 */
12063 private static class FadeInOutAnimation extends Animation {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012064 boolean mFadeIn;
12065
12066 public FadeInOutAnimation(boolean fadeIn) {
12067 setInterpolator(new AccelerateInterpolator());
12068 setDuration(DEFAULT_FADE_IN_OUT_DURATION);
12069 mFadeIn = fadeIn;
12070 }
12071
12072 @Override
12073 protected void applyTransformation(float interpolatedTime, Transformation t) {
12074 float x = interpolatedTime;
12075 if (!mFadeIn) {
12076 x = 1.0f - x; // reverse the interpolation for fade out
12077 }
Dianne Hackbornac1471a2011-02-03 13:46:06 -080012078 t.setAlpha(x);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070012079 }
12080 }
Jeff Brown2992ea72011-01-28 22:04:14 -080012081
12082 public interface OnHardKeyboardStatusChangeListener {
12083 public void onHardKeyboardStatusChange(boolean available, boolean enabled);
12084 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012085}