blob: deafb36e1d3f3133f26bfc711ba987ad53cbc020 [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;
Jim Millerd6b57052010-06-07 17:52:42 -070050import android.app.admin.DevicePolicyManager;
Jim Miller284b62e2010-06-08 14:27:42 -070051import android.content.BroadcastReceiver;
Christopher Tatea53146c2010-09-07 11:57:52 -070052import android.content.ClipData;
53import android.content.ClipDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054import android.content.Context;
Jim Miller284b62e2010-06-08 14:27:42 -070055import android.content.Intent;
56import android.content.IntentFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.content.pm.ActivityInfo;
58import android.content.pm.PackageManager;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070059import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060import android.content.res.Configuration;
Dianne Hackborn1c24e952010-11-23 00:34:30 -080061import android.content.res.Resources;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080062import android.graphics.Bitmap;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070063import android.graphics.Canvas;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import android.graphics.Matrix;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070065import android.graphics.Paint;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.graphics.PixelFormat;
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070067import android.graphics.PorterDuff;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068import android.graphics.Rect;
69import android.graphics.Region;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070070import android.graphics.Typeface;
71import android.graphics.Paint.FontMetricsInt;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072import android.os.BatteryStats;
73import android.os.Binder;
Dianne Hackborn75804932009-10-20 20:15:20 -070074import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.os.Debug;
76import android.os.Handler;
77import android.os.IBinder;
78import android.os.LocalPowerManager;
79import android.os.Looper;
80import android.os.Message;
81import android.os.Parcel;
82import android.os.ParcelFileDescriptor;
83import android.os.Power;
84import android.os.PowerManager;
85import android.os.Process;
86import android.os.RemoteException;
87import android.os.ServiceManager;
Brad Fitzpatrickec062f62010-11-03 09:56:54 -070088import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089import android.os.SystemClock;
90import android.os.SystemProperties;
91import android.os.TokenWatcher;
92import android.provider.Settings;
Dianne Hackborn723738c2009-06-25 19:48:04 -070093import android.util.DisplayMetrics;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094import android.util.EventLog;
Jim Millerd6b57052010-06-07 17:52:42 -070095import android.util.Log;
Joe Onorato8a9b2202010-02-26 18:56:32 -080096import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097import android.util.SparseIntArray;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070098import android.util.TypedValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099import android.view.Display;
Christopher Tatea53146c2010-09-07 11:57:52 -0700100import android.view.DragEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101import android.view.Gravity;
102import android.view.IApplicationToken;
103import android.view.IOnKeyguardExitResult;
104import android.view.IRotationWatcher;
105import android.view.IWindow;
106import android.view.IWindowManager;
107import android.view.IWindowSession;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700108import android.view.InputChannel;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700109import android.view.InputDevice;
Jeff Brownbbda99d2010-07-28 15:48:59 -0700110import android.view.InputEvent;
Christopher Tatea53146c2010-09-07 11:57:52 -0700111import android.view.InputHandler;
112import android.view.InputQueue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113import android.view.KeyEvent;
114import android.view.MotionEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115import android.view.Surface;
116import android.view.SurfaceSession;
117import android.view.View;
118import android.view.ViewTreeObserver;
119import android.view.WindowManager;
120import android.view.WindowManagerImpl;
121import android.view.WindowManagerPolicy;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700122import android.view.Surface.OutOfResourcesException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123import android.view.WindowManager.LayoutParams;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700124import android.view.animation.AccelerateInterpolator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125import android.view.animation.Animation;
126import android.view.animation.AnimationUtils;
127import android.view.animation.Transformation;
128
129import java.io.BufferedWriter;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700130import java.io.DataInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131import java.io.File;
132import java.io.FileDescriptor;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700133import java.io.FileInputStream;
134import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135import java.io.IOException;
136import java.io.OutputStream;
137import java.io.OutputStreamWriter;
138import java.io.PrintWriter;
139import java.io.StringWriter;
140import java.net.Socket;
141import java.util.ArrayList;
142import java.util.HashMap;
143import java.util.HashSet;
144import java.util.Iterator;
145import java.util.List;
146
147/** {@hide} */
Dianne Hackbornddca3ee2009-07-23 19:01:31 -0700148public class WindowManagerService extends IWindowManager.Stub
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700149 implements Watchdog.Monitor {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 static final String TAG = "WindowManager";
151 static final boolean DEBUG = false;
152 static final boolean DEBUG_FOCUS = false;
153 static final boolean DEBUG_ANIM = false;
Dianne Hackborn9b52a212009-12-11 14:51:35 -0800154 static final boolean DEBUG_LAYOUT = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800155 static final boolean DEBUG_RESIZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156 static final boolean DEBUG_LAYERS = false;
157 static final boolean DEBUG_INPUT = false;
158 static final boolean DEBUG_INPUT_METHOD = false;
159 static final boolean DEBUG_VISIBILITY = false;
Dianne Hackbornbdd52b22009-09-02 21:46:19 -0700160 static final boolean DEBUG_WINDOW_MOVEMENT = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 static final boolean DEBUG_ORIENTATION = false;
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700162 static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 static final boolean DEBUG_APP_TRANSITIONS = false;
164 static final boolean DEBUG_STARTING_WINDOW = false;
165 static final boolean DEBUG_REORDER = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700166 static final boolean DEBUG_WALLPAPER = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700167 static final boolean DEBUG_DRAG = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 static final boolean SHOW_TRANSACTIONS = false;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700169 static final boolean HIDE_STACK_CRAWLS = true;
Michael Chan53071d62009-05-13 17:29:48 -0700170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 static final boolean PROFILE_ORIENTATION = false;
172 static final boolean BLUR = true;
Dave Bortcfe65242009-04-09 14:51:04 -0700173 static final boolean localLOGV = DEBUG;
Romain Guy06882f82009-06-10 13:36:04 -0700174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175 /** How much to multiply the policy's type layer, to reserve room
176 * for multiple windows of the same type and Z-ordering adjustment
177 * with TYPE_LAYER_OFFSET. */
178 static final int TYPE_LAYER_MULTIPLIER = 10000;
Romain Guy06882f82009-06-10 13:36:04 -0700179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800180 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
181 * or below others in the same layer. */
182 static final int TYPE_LAYER_OFFSET = 1000;
Romain Guy06882f82009-06-10 13:36:04 -0700183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184 /** How much to increment the layer for each window, to reserve room
185 * for effect surfaces between them.
186 */
187 static final int WINDOW_LAYER_MULTIPLIER = 5;
Romain Guy06882f82009-06-10 13:36:04 -0700188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189 /** The maximum length we will accept for a loaded animation duration:
190 * this is 10 seconds.
191 */
192 static final int MAX_ANIMATION_DURATION = 10*1000;
193
194 /** Amount of time (in milliseconds) to animate the dim surface from one
195 * value to another, when no window animation is driving it.
196 */
197 static final int DEFAULT_DIM_DURATION = 200;
198
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700199 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
200 * compatible windows.
201 */
202 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
203
Dianne Hackborna1111872010-11-23 20:55:11 -0800204 /**
205 * If true, the window manager will do its own custom freezing and general
206 * management of the screen during rotation.
207 */
208 static final boolean CUSTOM_SCREEN_ROTATION = true;
209
Jeff Brown7fbdc842010-06-17 20:52:56 -0700210 // Maximum number of milliseconds to wait for input event injection.
211 // FIXME is this value reasonable?
212 private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000;
Jeff Brown349703e2010-06-22 01:27:15 -0700213
214 // Default input dispatching timeout in nanoseconds.
215 private static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
Romain Guy06882f82009-06-10 13:36:04 -0700216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217 static final int UPDATE_FOCUS_NORMAL = 0;
218 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
219 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
220 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700221
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800222 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700223 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224
225 /**
226 * Condition waited on by {@link #reenableKeyguard} to know the call to
227 * the window policy has finished.
Mike Lockwood983ee092009-11-22 01:42:24 -0500228 * This is set to true only if mKeyguardTokenWatcher.acquired() has
229 * actually disabled the keyguard.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800230 */
Mike Lockwood983ee092009-11-22 01:42:24 -0500231 private boolean mKeyguardDisabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800232
Jim Miller284b62e2010-06-08 14:27:42 -0700233 private static final int ALLOW_DISABLE_YES = 1;
234 private static final int ALLOW_DISABLE_NO = 0;
235 private static final int ALLOW_DISABLE_UNKNOWN = -1; // check with DevicePolicyManager
236 private int mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN; // sync'd by mKeyguardTokenWatcher
237
Mike Lockwood983ee092009-11-22 01:42:24 -0500238 final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher(
239 new Handler(), "WindowManagerService.mKeyguardTokenWatcher") {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240 public void acquired() {
Jim Miller284b62e2010-06-08 14:27:42 -0700241 if (shouldAllowDisableKeyguard()) {
242 mPolicy.enableKeyguard(false);
243 mKeyguardDisabled = true;
244 } else {
245 Log.v(TAG, "Not disabling keyguard since device policy is enforced");
246 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 }
248 public void released() {
Dianne Hackborna33e3f72009-09-29 17:28:24 -0700249 mPolicy.enableKeyguard(true);
Mike Lockwood983ee092009-11-22 01:42:24 -0500250 synchronized (mKeyguardTokenWatcher) {
251 mKeyguardDisabled = false;
252 mKeyguardTokenWatcher.notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 }
254 }
255 };
256
Jim Miller284b62e2010-06-08 14:27:42 -0700257 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
258 @Override
259 public void onReceive(Context context, Intent intent) {
260 mPolicy.enableKeyguard(true);
261 synchronized(mKeyguardTokenWatcher) {
262 // lazily evaluate this next time we're asked to disable keyguard
263 mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
264 mKeyguardDisabled = false;
265 }
266 }
267 };
268
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269 final Context mContext;
270
271 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700274
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
276
277 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281 /**
282 * All currently active sessions with clients.
283 */
284 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286 /**
287 * Mapping from an IWindow IBinder to the server's Window object.
288 * This is also used as the lock for all of our state.
289 */
290 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
291
292 /**
293 * Mapping from a token IBinder to a WindowToken object.
294 */
295 final HashMap<IBinder, WindowToken> mTokenMap =
296 new HashMap<IBinder, WindowToken>();
297
298 /**
299 * The same tokens as mTokenMap, stored in a list for efficient iteration
300 * over them.
301 */
302 final ArrayList<WindowToken> mTokenList = new ArrayList<WindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 /**
305 * Window tokens that are in the process of exiting, but still
306 * on screen for animations.
307 */
308 final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
309
310 /**
311 * Z-ordered (bottom-most first) list of all application tokens, for
312 * controlling the ordering of windows in different applications. This
313 * contains WindowToken objects.
314 */
315 final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
316
317 /**
318 * Application tokens that are in the process of exiting, but still
319 * on screen for animations.
320 */
321 final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
322
323 /**
324 * List of window tokens that have finished starting their application,
325 * and now need to have the policy remove their windows.
326 */
327 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
328
329 /**
330 * Z-ordered (bottom-most first) list of all Window objects.
331 */
Jeff Browne33348b2010-07-15 23:54:05 -0700332 final ArrayList<WindowState> mWindows = new ArrayList<WindowState>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333
334 /**
335 * Windows that are being resized. Used so we can tell the client about
336 * the resize after closing the transaction in which we resized the
337 * underlying surface.
338 */
339 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
340
341 /**
342 * Windows whose animations have ended and now must be removed.
343 */
344 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
345
346 /**
347 * Windows whose surface should be destroyed.
348 */
349 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
350
351 /**
352 * Windows that have lost input focus and are waiting for the new
353 * focus window to be displayed before they are told about this.
354 */
355 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
356
357 /**
358 * This is set when we have run out of memory, and will either be an empty
359 * list or contain windows that need to be force removed.
360 */
361 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700362
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700364
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365 SurfaceSession mFxSession;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700366 private DimAnimator mDimAnimator = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800367 Surface mBlurSurface;
368 boolean mBlurShown;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700369 Watermark mWatermark;
Brad Fitzpatrick68044332010-11-22 18:19:48 -0800370 StrictModeFlash mStrictModeFlash;
Dianne Hackborna1111872010-11-23 20:55:11 -0800371 ScreenRotationAnimation mScreenRotationAnimation;
Romain Guy06882f82009-06-10 13:36:04 -0700372
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800373 int mTransactionSequence = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800375 final float[] mTmpFloats = new float[9];
376
377 boolean mSafeMode;
378 boolean mDisplayEnabled = false;
379 boolean mSystemBooted = false;
Christopher Tateb696aee2010-04-02 19:08:30 -0700380 int mInitialDisplayWidth = 0;
381 int mInitialDisplayHeight = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 int mRotation = 0;
383 int mRequestedRotation = 0;
384 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborn321ae682009-03-27 16:16:03 -0700385 int mLastRotationFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 ArrayList<IRotationWatcher> mRotationWatchers
387 = new ArrayList<IRotationWatcher>();
Romain Guy06882f82009-06-10 13:36:04 -0700388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 boolean mLayoutNeeded = true;
390 boolean mAnimationPending = false;
391 boolean mDisplayFrozen = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800392 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 boolean mWindowsFreezingScreen = false;
394 long mFreezeGcPending = 0;
395 int mAppsFreezingScreen = 0;
396
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800397 int mLayoutSeq = 0;
398
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800399 // State while inside of layoutAndPlaceSurfacesLocked().
400 boolean mFocusMayChange;
401
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800402 Configuration mCurConfiguration = new Configuration();
403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 // This is held as long as we have the screen frozen, to give us time to
405 // perform a rotation animation when turning off shows the lock screen which
406 // changes the orientation.
407 PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700408
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 // State management of app transitions. When we are preparing for a
410 // transition, mNextAppTransition will be the kind of transition to
411 // perform or TRANSIT_NONE if we are not waiting. If we are waiting,
412 // mOpeningApps and mClosingApps are the lists of tokens that will be
413 // made visible or hidden at the next transition.
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700414 int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700415 String mNextAppTransitionPackage;
416 int mNextAppTransitionEnter;
417 int mNextAppTransitionExit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418 boolean mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -0700419 boolean mAppTransitionRunning = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420 boolean mAppTransitionTimeout = false;
421 boolean mStartingIconInTransition = false;
422 boolean mSkipAppTransitionAnimation = false;
423 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
424 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Dianne Hackborna8f60182009-09-01 19:01:50 -0700425 final ArrayList<AppWindowToken> mToTopApps = new ArrayList<AppWindowToken>();
426 final ArrayList<AppWindowToken> mToBottomApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700427
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800428 Display mDisplay;
Romain Guy06882f82009-06-10 13:36:04 -0700429
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800430 H mH = new H();
431
432 WindowState mCurrentFocus = null;
433 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700434
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800435 // This just indicates the window the input method is on top of, not
436 // necessarily the window its input is going to.
437 WindowState mInputMethodTarget = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800438 boolean mInputMethodTargetWaitingAnim;
439 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 WindowState mInputMethodWindow = null;
442 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
443
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700444 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800445
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700446 // If non-null, this is the currently visible window that is associated
447 // with the wallpaper.
448 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700449 // If non-null, we are in the middle of animating from one wallpaper target
450 // to another, and this is the lower one in Z-order.
451 WindowState mLowerWallpaperTarget = null;
452 // If non-null, we are in the middle of animating from one wallpaper target
453 // to another, and this is the higher one in Z-order.
454 WindowState mUpperWallpaperTarget = null;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -0800455 // Window currently running an animation that has requested it be detached
456 // from the wallpaper. This means we need to ensure the wallpaper is
457 // visible behind it in case it animates in a way that would allow it to be
458 // seen.
459 WindowState mWindowDetachedWallpaper = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700460 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700461 float mLastWallpaperX = -1;
462 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800463 float mLastWallpaperXStep = -1;
464 float mLastWallpaperYStep = -1;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700465 // This is set when we are waiting for a wallpaper to tell us it is done
466 // changing its scroll position.
467 WindowState mWaitingOnWallpaper;
468 // The last time we had a timeout when waiting for a wallpaper.
469 long mLastWallpaperTimeoutTime;
470 // We give a wallpaper up to 150ms to finish scrolling.
471 static final long WALLPAPER_TIMEOUT = 150;
472 // Time we wait after a timeout before trying to wait again.
473 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800474
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800475 AppWindowToken mFocusedApp = null;
476
477 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700478
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800479 float mWindowAnimationScale = 1.0f;
480 float mTransitionAnimationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700481
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700482 final InputManager mInputManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800483
484 // Who is holding the screen on.
485 Session mHoldingScreenOn;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700486 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700487
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700488 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490 /**
Christopher Tatea53146c2010-09-07 11:57:52 -0700491 * Drag/drop state
492 */
493 class DragState {
494 IBinder mToken;
495 Surface mSurface;
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800496 int mFlags;
Chris Tate7b362e42010-11-04 16:02:52 -0700497 IBinder mLocalWin;
Christopher Tatea53146c2010-09-07 11:57:52 -0700498 ClipData mData;
499 ClipDescription mDataDescription;
Chris Tated4533f142010-10-19 15:15:08 -0700500 boolean mDragResult;
Chris Tateb478f462010-10-15 16:02:26 -0700501 float mCurrentX, mCurrentY;
Christopher Tatea53146c2010-09-07 11:57:52 -0700502 float mThumbOffsetX, mThumbOffsetY;
503 InputChannel mServerChannel, mClientChannel;
504 WindowState mTargetWindow;
505 ArrayList<WindowState> mNotifiedWindows;
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700506 boolean mDragInProgress;
Christopher Tatea53146c2010-09-07 11:57:52 -0700507
Christopher Tateccd24de2011-01-12 15:02:55 -0800508 boolean mPerformDeferredRotation;
509 int mRotation;
510 int mAnimFlags;
511
Christopher Tatea53146c2010-09-07 11:57:52 -0700512 private final Rect tmpRect = new Rect();
513
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800514 DragState(IBinder token, Surface surface, int flags, IBinder localWin) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700515 mToken = token;
516 mSurface = surface;
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800517 mFlags = flags;
Chris Tate7b362e42010-11-04 16:02:52 -0700518 mLocalWin = localWin;
Christopher Tatea53146c2010-09-07 11:57:52 -0700519 mNotifiedWindows = new ArrayList<WindowState>();
520 }
521
522 void reset() {
523 if (mSurface != null) {
524 mSurface.destroy();
525 }
526 mSurface = null;
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800527 mFlags = 0;
Chris Tate7b362e42010-11-04 16:02:52 -0700528 mLocalWin = null;
Christopher Tatea53146c2010-09-07 11:57:52 -0700529 mToken = null;
530 mData = null;
531 mThumbOffsetX = mThumbOffsetY = 0;
532 mNotifiedWindows = null;
Christopher Tateccd24de2011-01-12 15:02:55 -0800533 mPerformDeferredRotation = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700534 }
535
536 void register() {
537 if (DEBUG_DRAG) Slog.d(TAG, "registering drag input channel");
538 if (mClientChannel != null) {
539 Slog.e(TAG, "Duplicate register of drag input channel");
540 } else {
541 InputChannel[] channels = InputChannel.openInputChannelPair("drag");
542 mServerChannel = channels[0];
543 mClientChannel = channels[1];
Jeff Brown928e0542011-01-10 11:17:36 -0800544 mInputManager.registerInputChannel(mServerChannel, null);
Christopher Tatea53146c2010-09-07 11:57:52 -0700545 InputQueue.registerInputChannel(mClientChannel, mDragInputHandler,
546 mH.getLooper().getQueue());
547 }
548 }
549
550 void unregister() {
551 if (DEBUG_DRAG) Slog.d(TAG, "unregistering drag input channel");
552 if (mClientChannel == null) {
553 Slog.e(TAG, "Unregister of nonexistent drag input channel");
554 } else {
555 mInputManager.unregisterInputChannel(mServerChannel);
556 InputQueue.unregisterInputChannel(mClientChannel);
557 mClientChannel.dispose();
Chris Tateef70a072010-10-22 19:10:34 -0700558 mServerChannel.dispose();
Christopher Tatea53146c2010-09-07 11:57:52 -0700559 mClientChannel = null;
560 mServerChannel = null;
561 }
562 }
563
Chris Tatea32dcf72010-10-14 12:13:50 -0700564 int getDragLayerLw() {
565 return mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_DRAG)
566 * TYPE_LAYER_MULTIPLIER
567 + TYPE_LAYER_OFFSET;
568 }
569
Christopher Tatea53146c2010-09-07 11:57:52 -0700570 /* call out to each visible window/session informing it about the drag
571 */
Chris Tateb8203e92010-10-12 14:23:21 -0700572 void broadcastDragStartedLw(final float touchX, final float touchY) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700573 // Cache a base-class instance of the clip metadata so that parceling
574 // works correctly in calling out to the apps.
Dianne Hackbornf834dfa2010-10-26 12:43:57 -0700575 mDataDescription = mData.getDescription();
Christopher Tatea53146c2010-09-07 11:57:52 -0700576 mNotifiedWindows.clear();
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700577 mDragInProgress = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700578
579 if (DEBUG_DRAG) {
Chris Tateb478f462010-10-15 16:02:26 -0700580 Slog.d(TAG, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
Christopher Tatea53146c2010-09-07 11:57:52 -0700581 }
582
Christopher Tate2c095f32010-10-04 14:13:40 -0700583 final int N = mWindows.size();
584 for (int i = 0; i < N; i++) {
Chris Tateb478f462010-10-15 16:02:26 -0700585 sendDragStartedLw(mWindows.get(i), touchX, touchY, mDataDescription);
Christopher Tatea53146c2010-09-07 11:57:52 -0700586 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700587 }
588
589 /* helper - send a caller-provided event, presumed to be DRAG_STARTED, if the
590 * designated window is potentially a drop recipient. There are race situations
591 * around DRAG_ENDED broadcast, so we make sure that once we've declared that
592 * the drag has ended, we never send out another DRAG_STARTED for this drag action.
Christopher Tate2c095f32010-10-04 14:13:40 -0700593 *
594 * This method clones the 'event' parameter if it's being delivered to the same
595 * process, so it's safe for the caller to call recycle() on the event afterwards.
Christopher Tatea53146c2010-09-07 11:57:52 -0700596 */
Chris Tateb478f462010-10-15 16:02:26 -0700597 private void sendDragStartedLw(WindowState newWin, float touchX, float touchY,
598 ClipDescription desc) {
Chris Tate7b362e42010-11-04 16:02:52 -0700599 // Don't actually send the event if the drag is supposed to be pinned
600 // to the originating window but 'newWin' is not that window.
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800601 if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
Chris Tate7b362e42010-11-04 16:02:52 -0700602 final IBinder winBinder = newWin.mClient.asBinder();
603 if (winBinder != mLocalWin) {
604 if (DEBUG_DRAG) {
605 Slog.d(TAG, "Not dispatching local DRAG_STARTED to " + newWin);
606 }
607 return;
608 }
609 }
610
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700611 if (mDragInProgress && newWin.isPotentialDragTarget()) {
Chris Tateb478f462010-10-15 16:02:26 -0700612 DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED,
613 touchX - newWin.mFrame.left, touchY - newWin.mFrame.top,
Christopher Tate407b4e92010-11-30 17:14:08 -0800614 null, desc, null, false);
Christopher Tatea53146c2010-09-07 11:57:52 -0700615 try {
616 newWin.mClient.dispatchDragEvent(event);
617 // track each window that we've notified that the drag is starting
618 mNotifiedWindows.add(newWin);
619 } catch (RemoteException e) {
620 Slog.w(TAG, "Unable to drag-start window " + newWin);
Chris Tateb478f462010-10-15 16:02:26 -0700621 } finally {
622 // if the callee was local, the dispatch has already recycled the event
623 if (Process.myPid() != newWin.mSession.mPid) {
624 event.recycle();
625 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700626 }
627 }
628 }
629
630 /* helper - construct and send a DRAG_STARTED event only if the window has not
631 * previously been notified, i.e. it became visible after the drag operation
632 * was begun. This is a rare case.
633 */
634 private void sendDragStartedIfNeededLw(WindowState newWin) {
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700635 if (mDragInProgress) {
636 // If we have sent the drag-started, we needn't do so again
637 for (WindowState ws : mNotifiedWindows) {
638 if (ws == newWin) {
639 return;
640 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700641 }
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700642 if (DEBUG_DRAG) {
Chris Tateef70a072010-10-22 19:10:34 -0700643 Slog.d(TAG, "need to send DRAG_STARTED to new window " + newWin);
Christopher Tate5ada6cb2010-10-05 14:15:29 -0700644 }
Chris Tateb478f462010-10-15 16:02:26 -0700645 sendDragStartedLw(newWin, mCurrentX, mCurrentY, mDataDescription);
Christopher Tatea53146c2010-09-07 11:57:52 -0700646 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700647 }
648
Chris Tated4533f142010-10-19 15:15:08 -0700649 void broadcastDragEndedLw() {
Christopher Tatea53146c2010-09-07 11:57:52 -0700650 if (DEBUG_DRAG) {
651 Slog.d(TAG, "broadcasting DRAG_ENDED");
652 }
Chris Tated4533f142010-10-19 15:15:08 -0700653 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED,
Christopher Tate407b4e92010-11-30 17:14:08 -0800654 0, 0, null, null, null, mDragResult);
Chris Tated4533f142010-10-19 15:15:08 -0700655 for (WindowState ws: mNotifiedWindows) {
656 try {
657 ws.mClient.dispatchDragEvent(evt);
658 } catch (RemoteException e) {
659 Slog.w(TAG, "Unable to drag-end window " + ws);
Christopher Tatea53146c2010-09-07 11:57:52 -0700660 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700661 }
Chris Tated4533f142010-10-19 15:15:08 -0700662 mNotifiedWindows.clear();
663 mDragInProgress = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700664 evt.recycle();
665 }
666
Chris Tated4533f142010-10-19 15:15:08 -0700667 void endDragLw() {
668 mDragState.broadcastDragEndedLw();
669
670 // stop intercepting input
671 mDragState.unregister();
672 mInputMonitor.updateInputWindowsLw();
673
Christopher Tateccd24de2011-01-12 15:02:55 -0800674 // Retain the parameters of any deferred rotation operation so
675 // that we can perform it after the reset / unref of the drag state
676 final boolean performRotation = mPerformDeferredRotation;
677 final int rotation = mRotation;
678 final int animFlags = mAnimFlags;
679
Chris Tated4533f142010-10-19 15:15:08 -0700680 // free our resources and drop all the object references
681 mDragState.reset();
682 mDragState = null;
Christopher Tateccd24de2011-01-12 15:02:55 -0800683
684 // Now that we've officially ended the drag, execute any
685 // deferred rotation
686 if (performRotation) {
687 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-drag rotation");
688 boolean changed = setRotationUncheckedLocked(rotation, animFlags);
689 if (changed) {
690 sendNewConfiguration();
691 }
692 }
Chris Tated4533f142010-10-19 15:15:08 -0700693 }
694
Christopher Tatea53146c2010-09-07 11:57:52 -0700695 void notifyMoveLw(float x, float y) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700696 final int myPid = Process.myPid();
697
698 // Move the surface to the given touch
699 mSurface.openTransaction();
700 mSurface.setPosition((int)(x - mThumbOffsetX), (int)(y - mThumbOffsetY));
701 mSurface.closeTransaction();
702
703 // Tell the affected window
Christopher Tatea53146c2010-09-07 11:57:52 -0700704 WindowState touchedWin = getTouchedWinAtPointLw(x, y);
Christopher Tate02d2b3b2011-01-10 20:43:53 -0800705 if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
Chris Tate7b362e42010-11-04 16:02:52 -0700706 final IBinder touchedBinder = touchedWin.mClient.asBinder();
707 if (touchedBinder != mLocalWin) {
708 // This drag is pinned only to the originating window, but the drag
709 // point is outside that window. Pretend it's over empty space.
710 touchedWin = null;
711 }
712 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700713 try {
714 // have we dragged over a new window?
715 if ((touchedWin != mTargetWindow) && (mTargetWindow != null)) {
716 if (DEBUG_DRAG) {
717 Slog.d(TAG, "sending DRAG_EXITED to " + mTargetWindow);
718 }
719 // force DRAG_EXITED_EVENT if appropriate
720 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_EXITED,
Chris Tateb478f462010-10-15 16:02:26 -0700721 x - mTargetWindow.mFrame.left, y - mTargetWindow.mFrame.top,
Christopher Tate407b4e92010-11-30 17:14:08 -0800722 null, null, null, false);
Christopher Tatea53146c2010-09-07 11:57:52 -0700723 mTargetWindow.mClient.dispatchDragEvent(evt);
Christopher Tate2c095f32010-10-04 14:13:40 -0700724 if (myPid != mTargetWindow.mSession.mPid) {
725 evt.recycle();
726 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700727 }
728 if (touchedWin != null) {
Chris Tate9d1ab882010-11-02 15:55:39 -0700729 if (false && DEBUG_DRAG) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700730 Slog.d(TAG, "sending DRAG_LOCATION to " + touchedWin);
731 }
732 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_LOCATION,
Chris Tateb478f462010-10-15 16:02:26 -0700733 x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
Christopher Tate407b4e92010-11-30 17:14:08 -0800734 null, null, null, false);
Christopher Tatea53146c2010-09-07 11:57:52 -0700735 touchedWin.mClient.dispatchDragEvent(evt);
Christopher Tate2c095f32010-10-04 14:13:40 -0700736 if (myPid != touchedWin.mSession.mPid) {
737 evt.recycle();
738 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700739 }
740 } catch (RemoteException e) {
741 Slog.w(TAG, "can't send drag notification to windows");
742 }
743 mTargetWindow = touchedWin;
744 }
745
Chris Tated4533f142010-10-19 15:15:08 -0700746 // Tell the drop target about the data. Returns 'true' if we can immediately
747 // dispatch the global drag-ended message, 'false' if we need to wait for a
748 // result from the recipient.
749 boolean notifyDropLw(float x, float y) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700750 WindowState touchedWin = getTouchedWinAtPointLw(x, y);
Chris Tated4533f142010-10-19 15:15:08 -0700751 if (touchedWin == null) {
752 // "drop" outside a valid window -- no recipient to apply a
753 // timeout to, and we can send the drag-ended message immediately.
754 mDragResult = false;
755 return true;
756 }
757
758 if (DEBUG_DRAG) {
759 Slog.d(TAG, "sending DROP to " + touchedWin);
760 }
761 final int myPid = Process.myPid();
762 final IBinder token = touchedWin.mClient.asBinder();
763 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DROP,
764 x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
Christopher Tate407b4e92010-11-30 17:14:08 -0800765 null, null, mData, false);
Chris Tated4533f142010-10-19 15:15:08 -0700766 try {
767 touchedWin.mClient.dispatchDragEvent(evt);
768
769 // 5 second timeout for this window to respond to the drop
770 mH.removeMessages(H.DRAG_END_TIMEOUT, token);
771 Message msg = mH.obtainMessage(H.DRAG_END_TIMEOUT, token);
772 mH.sendMessageDelayed(msg, 5000);
773 } catch (RemoteException e) {
774 Slog.w(TAG, "can't send drop notification to win " + touchedWin);
775 return true;
776 } finally {
Christopher Tate2c095f32010-10-04 14:13:40 -0700777 if (myPid != touchedWin.mSession.mPid) {
778 evt.recycle();
779 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700780 }
Chris Tated4533f142010-10-19 15:15:08 -0700781 mToken = token;
782 return false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700783 }
784
785 // Find the visible, touch-deliverable window under the given point
786 private WindowState getTouchedWinAtPointLw(float xf, float yf) {
787 WindowState touchedWin = null;
788 final int x = (int) xf;
789 final int y = (int) yf;
790 final ArrayList<WindowState> windows = mWindows;
791 final int N = windows.size();
792 for (int i = N - 1; i >= 0; i--) {
793 WindowState child = windows.get(i);
794 final int flags = child.mAttrs.flags;
795 if (!child.isVisibleLw()) {
796 // not visible == don't tell about drags
797 continue;
798 }
799 if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
800 // not touchable == don't tell about drags
801 continue;
802 }
803 // account for the window's decor etc
804 tmpRect.set(child.mFrame);
805 if (child.mTouchableInsets == ViewTreeObserver
806 .InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT) {
807 // The point is inside of the window if it is
808 // inside the frame, AND the content part of that
809 // frame that was given by the application.
810 tmpRect.left += child.mGivenContentInsets.left;
811 tmpRect.top += child.mGivenContentInsets.top;
812 tmpRect.right -= child.mGivenContentInsets.right;
813 tmpRect.bottom -= child.mGivenContentInsets.bottom;
814 } else if (child.mTouchableInsets == ViewTreeObserver
815 .InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE) {
816 // The point is inside of the window if it is
817 // inside the frame, AND the visible part of that
818 // frame that was given by the application.
819 tmpRect.left += child.mGivenVisibleInsets.left;
820 tmpRect.top += child.mGivenVisibleInsets.top;
821 tmpRect.right -= child.mGivenVisibleInsets.right;
822 tmpRect.bottom -= child.mGivenVisibleInsets.bottom;
823 }
824 final int touchFlags = flags &
825 (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
826 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
827 if (tmpRect.contains(x, y) || touchFlags == 0) {
828 // Found it
829 touchedWin = child;
830 break;
831 }
832 }
833
834 return touchedWin;
835 }
Christopher Tateccd24de2011-01-12 15:02:55 -0800836
837 void setDeferredRotation(int rotation, int animFlags) {
838 mRotation = rotation;
839 mAnimFlags = animFlags;
840 mPerformDeferredRotation = true;
841 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700842 }
843
844 DragState mDragState = null;
845 private final InputHandler mDragInputHandler = new BaseInputHandler() {
846 @Override
Jeff Brown3915bb82010-11-05 15:02:16 -0700847 public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
848 boolean handled = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700849 try {
Jeff Brown3915bb82010-11-05 15:02:16 -0700850 if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
851 && mDragState != null) {
852 boolean endDrag = false;
853 final float newX = event.getRawX();
854 final float newY = event.getRawY();
855
Christopher Tatea53146c2010-09-07 11:57:52 -0700856 switch (event.getAction()) {
857 case MotionEvent.ACTION_DOWN: {
858 if (DEBUG_DRAG) {
859 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
860 }
861 } break;
862
863 case MotionEvent.ACTION_MOVE: {
864 synchronized (mWindowMap) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700865 // move the surface and tell the involved window(s) where we are
Christopher Tatea53146c2010-09-07 11:57:52 -0700866 mDragState.notifyMoveLw(newX, newY);
867 }
868 } break;
869
870 case MotionEvent.ACTION_UP: {
871 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
872 + newX + "," + newY);
873 synchronized (mWindowMap) {
Chris Tated4533f142010-10-19 15:15:08 -0700874 endDrag = mDragState.notifyDropLw(newX, newY);
Christopher Tatea53146c2010-09-07 11:57:52 -0700875 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700876 } break;
877
878 case MotionEvent.ACTION_CANCEL: {
879 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
880 endDrag = true;
881 } break;
882 }
883
884 if (endDrag) {
885 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
886 // tell all the windows that the drag has ended
Chris Tate59943592010-10-11 20:33:44 -0700887 synchronized (mWindowMap) {
Chris Tated4533f142010-10-19 15:15:08 -0700888 mDragState.endDragLw();
Chris Tate59943592010-10-11 20:33:44 -0700889 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700890 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700891
892 handled = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700893 }
894 } catch (Exception e) {
895 Slog.e(TAG, "Exception caught by drag handleMotion", e);
896 } finally {
Jeff Brown3915bb82010-11-05 15:02:16 -0700897 finishedCallback.finished(handled);
Christopher Tatea53146c2010-09-07 11:57:52 -0700898 }
899 }
900 };
901
902 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800903 * Whether the UI is currently running in touch mode (not showing
904 * navigational focus because the user is directly pressing the screen).
905 */
906 boolean mInTouchMode = false;
907
908 private ViewServer mViewServer;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700909 private ArrayList<WindowChangeListener> mWindowChangeListeners =
910 new ArrayList<WindowChangeListener>();
911 private boolean mWindowsChanged = false;
912
913 public interface WindowChangeListener {
914 public void windowsChanged();
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -0700915 public void focusChanged();
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700916 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800917
Dianne Hackbornc485a602009-03-24 22:39:49 -0700918 final Configuration mTempConfiguration = new Configuration();
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700919 int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700920
921 // The frame use to limit the size of the app running in compatibility mode.
922 Rect mCompatibleScreenFrame = new Rect();
923 // The surface used to fill the outer rim of the app running in compatibility mode.
924 Surface mBackgroundFillerSurface = null;
925 boolean mBackgroundFillerShown = false;
926
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800927 public static WindowManagerService main(Context context,
928 PowerManagerService pm, boolean haveInputMethods) {
929 WMThread thr = new WMThread(context, pm, haveInputMethods);
930 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700931
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800932 synchronized (thr) {
933 while (thr.mService == null) {
934 try {
935 thr.wait();
936 } catch (InterruptedException e) {
937 }
938 }
939 }
Romain Guy06882f82009-06-10 13:36:04 -0700940
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800941 return thr.mService;
942 }
Romain Guy06882f82009-06-10 13:36:04 -0700943
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800944 static class WMThread extends Thread {
945 WindowManagerService mService;
Romain Guy06882f82009-06-10 13:36:04 -0700946
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800947 private final Context mContext;
948 private final PowerManagerService mPM;
949 private final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700950
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800951 public WMThread(Context context, PowerManagerService pm,
952 boolean haveInputMethods) {
953 super("WindowManager");
954 mContext = context;
955 mPM = pm;
956 mHaveInputMethods = haveInputMethods;
957 }
Romain Guy06882f82009-06-10 13:36:04 -0700958
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959 public void run() {
960 Looper.prepare();
961 WindowManagerService s = new WindowManagerService(mContext, mPM,
962 mHaveInputMethods);
963 android.os.Process.setThreadPriority(
964 android.os.Process.THREAD_PRIORITY_DISPLAY);
Christopher Tate160edb32010-06-30 17:46:30 -0700965 android.os.Process.setCanSelfBackground(false);
Romain Guy06882f82009-06-10 13:36:04 -0700966
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 synchronized (this) {
968 mService = s;
969 notifyAll();
970 }
Romain Guy06882f82009-06-10 13:36:04 -0700971
Brad Fitzpatrickec062f62010-11-03 09:56:54 -0700972 // For debug builds, log event loop stalls to dropbox for analysis.
973 if (StrictMode.conditionallyEnableDebugLogging()) {
974 Slog.i(TAG, "Enabled StrictMode logging for WMThread's Looper");
975 }
976
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800977 Looper.loop();
978 }
979 }
980
981 static class PolicyThread extends Thread {
982 private final WindowManagerPolicy mPolicy;
983 private final WindowManagerService mService;
984 private final Context mContext;
985 private final PowerManagerService mPM;
986 boolean mRunning = false;
Romain Guy06882f82009-06-10 13:36:04 -0700987
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800988 public PolicyThread(WindowManagerPolicy policy,
989 WindowManagerService service, Context context,
990 PowerManagerService pm) {
991 super("WindowManagerPolicy");
992 mPolicy = policy;
993 mService = service;
994 mContext = context;
995 mPM = pm;
996 }
Romain Guy06882f82009-06-10 13:36:04 -0700997
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800998 public void run() {
999 Looper.prepare();
Dianne Hackbornac3587d2010-03-11 11:12:11 -08001000 WindowManagerPolicyThread.set(this, Looper.myLooper());
1001
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001002 //Looper.myLooper().setMessageLogging(new LogPrinter(
Joe Onorato8a9b2202010-02-26 18:56:32 -08001003 // Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001004 android.os.Process.setThreadPriority(
1005 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001006 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007 mPolicy.init(mContext, mService, mPM);
Romain Guy06882f82009-06-10 13:36:04 -07001008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001009 synchronized (this) {
1010 mRunning = true;
1011 notifyAll();
1012 }
Romain Guy06882f82009-06-10 13:36:04 -07001013
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001014 // For debug builds, log event loop stalls to dropbox for analysis.
1015 if (StrictMode.conditionallyEnableDebugLogging()) {
1016 Slog.i(TAG, "Enabled StrictMode for PolicyThread's Looper");
1017 }
1018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001019 Looper.loop();
1020 }
1021 }
1022
1023 private WindowManagerService(Context context, PowerManagerService pm,
1024 boolean haveInputMethods) {
1025 mContext = context;
1026 mHaveInputMethods = haveInputMethods;
1027 mLimitedAlphaCompositing = context.getResources().getBoolean(
1028 com.android.internal.R.bool.config_sf_limitedAlpha);
Romain Guy06882f82009-06-10 13:36:04 -07001029
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001030 mPowerManager = pm;
1031 mPowerManager.setPolicy(mPolicy);
1032 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
1033 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
1034 "SCREEN_FROZEN");
1035 mScreenFrozenLock.setReferenceCounted(false);
1036
1037 mActivityManager = ActivityManagerNative.getDefault();
1038 mBatteryStats = BatteryStatsService.getService();
1039
1040 // Get persisted window scale setting
1041 mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
1042 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
1043 mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
1044 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Romain Guy06882f82009-06-10 13:36:04 -07001045
Jim Miller284b62e2010-06-08 14:27:42 -07001046 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
1047 IntentFilter filter = new IntentFilter();
1048 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
1049 mContext.registerReceiver(mBroadcastReceiver, filter);
1050
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001051 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
1052 "KEEP_SCREEN_ON_FLAG");
1053 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001054
Jeff Browne33348b2010-07-15 23:54:05 -07001055 mInputManager = new InputManager(context, this);
Romain Guy06882f82009-06-10 13:36:04 -07001056
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001057 PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
1058 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -07001059
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001060 synchronized (thr) {
1061 while (!thr.mRunning) {
1062 try {
1063 thr.wait();
1064 } catch (InterruptedException e) {
1065 }
1066 }
1067 }
Romain Guy06882f82009-06-10 13:36:04 -07001068
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001069 mInputManager.start();
Romain Guy06882f82009-06-10 13:36:04 -07001070
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001071 // Add ourself to the Watchdog monitors.
1072 Watchdog.getInstance().addMonitor(this);
1073 }
1074
1075 @Override
1076 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1077 throws RemoteException {
1078 try {
1079 return super.onTransact(code, data, reply, flags);
1080 } catch (RuntimeException e) {
1081 // The window manager only throws security exceptions, so let's
1082 // log all others.
1083 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001084 Slog.e(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001085 }
1086 throw e;
1087 }
1088 }
1089
Jeff Browne33348b2010-07-15 23:54:05 -07001090 private void placeWindowAfter(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001091 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001092 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001093 TAG, "Adding window " + window + " at "
1094 + (i+1) + " of " + mWindows.size() + " (after " + pos + ")");
1095 mWindows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001096 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001097 }
1098
Jeff Browne33348b2010-07-15 23:54:05 -07001099 private void placeWindowBefore(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001100 final int i = mWindows.indexOf(pos);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001101 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001102 TAG, "Adding window " + window + " at "
1103 + i + " of " + mWindows.size() + " (before " + pos + ")");
1104 mWindows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001105 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001106 }
1107
1108 //This method finds out the index of a window that has the same app token as
1109 //win. used for z ordering the windows in mWindows
1110 private int findIdxBasedOnAppTokens(WindowState win) {
1111 //use a local variable to cache mWindows
Jeff Browne33348b2010-07-15 23:54:05 -07001112 ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001113 int jmax = localmWindows.size();
1114 if(jmax == 0) {
1115 return -1;
1116 }
1117 for(int j = (jmax-1); j >= 0; j--) {
Jeff Browne33348b2010-07-15 23:54:05 -07001118 WindowState wentry = localmWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001119 if(wentry.mAppToken == win.mAppToken) {
1120 return j;
1121 }
1122 }
1123 return -1;
1124 }
Romain Guy06882f82009-06-10 13:36:04 -07001125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001126 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
1127 final IWindow client = win.mClient;
1128 final WindowToken token = win.mToken;
Jeff Browne33348b2010-07-15 23:54:05 -07001129 final ArrayList<WindowState> localmWindows = mWindows;
Romain Guy06882f82009-06-10 13:36:04 -07001130
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001131 final int N = localmWindows.size();
1132 final WindowState attached = win.mAttachedWindow;
1133 int i;
1134 if (attached == null) {
1135 int tokenWindowsPos = token.windows.size();
1136 if (token.appWindowToken != null) {
1137 int index = tokenWindowsPos-1;
1138 if (index >= 0) {
1139 // If this application has existing windows, we
1140 // simply place the new window on top of them... but
1141 // keep the starting window on top.
1142 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
1143 // Base windows go behind everything else.
1144 placeWindowBefore(token.windows.get(0), win);
1145 tokenWindowsPos = 0;
1146 } else {
1147 AppWindowToken atoken = win.mAppToken;
1148 if (atoken != null &&
1149 token.windows.get(index) == atoken.startingWindow) {
1150 placeWindowBefore(token.windows.get(index), win);
1151 tokenWindowsPos--;
1152 } else {
1153 int newIdx = findIdxBasedOnAppTokens(win);
1154 if(newIdx != -1) {
Romain Guy06882f82009-06-10 13:36:04 -07001155 //there is a window above this one associated with the same
1156 //apptoken note that the window could be a floating window
1157 //that was created later or a window at the top of the list of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001158 //windows associated with this token.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001159 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001160 TAG, "Adding window " + win + " at "
1161 + (newIdx+1) + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001162 localmWindows.add(newIdx+1, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001163 mWindowsChanged = true;
Romain Guy06882f82009-06-10 13:36:04 -07001164 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001165 }
1166 }
1167 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001168 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001169 TAG, "Figuring out where to add app window "
1170 + client.asBinder() + " (token=" + token + ")");
1171 // Figure out where the window should go, based on the
1172 // order of applications.
1173 final int NA = mAppTokens.size();
Jeff Browne33348b2010-07-15 23:54:05 -07001174 WindowState pos = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001175 for (i=NA-1; i>=0; i--) {
1176 AppWindowToken t = mAppTokens.get(i);
1177 if (t == token) {
1178 i--;
1179 break;
1180 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001181
Dianne Hackborna8f60182009-09-01 19:01:50 -07001182 // We haven't reached the token yet; if this token
1183 // is not going to the bottom and has windows, we can
1184 // use it as an anchor for when we do reach the token.
1185 if (!t.sendingToBottom && t.windows.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001186 pos = t.windows.get(0);
1187 }
1188 }
1189 // We now know the index into the apps. If we found
1190 // an app window above, that gives us the position; else
1191 // we need to look some more.
1192 if (pos != null) {
1193 // Move behind any windows attached to this one.
Jeff Browne33348b2010-07-15 23:54:05 -07001194 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001195 if (atoken != null) {
1196 final int NC = atoken.windows.size();
1197 if (NC > 0) {
1198 WindowState bottom = atoken.windows.get(0);
1199 if (bottom.mSubLayer < 0) {
1200 pos = bottom;
1201 }
1202 }
1203 }
1204 placeWindowBefore(pos, win);
1205 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -07001206 // Continue looking down until we find the first
1207 // token that has windows.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001208 while (i >= 0) {
1209 AppWindowToken t = mAppTokens.get(i);
1210 final int NW = t.windows.size();
1211 if (NW > 0) {
1212 pos = t.windows.get(NW-1);
1213 break;
1214 }
1215 i--;
1216 }
1217 if (pos != null) {
1218 // Move in front of any windows attached to this
1219 // one.
Jeff Browne33348b2010-07-15 23:54:05 -07001220 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001221 if (atoken != null) {
1222 final int NC = atoken.windows.size();
1223 if (NC > 0) {
1224 WindowState top = atoken.windows.get(NC-1);
1225 if (top.mSubLayer >= 0) {
1226 pos = top;
1227 }
1228 }
1229 }
1230 placeWindowAfter(pos, win);
1231 } else {
1232 // Just search for the start of this layer.
1233 final int myLayer = win.mBaseLayer;
1234 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07001235 WindowState w = localmWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001236 if (w.mBaseLayer > myLayer) {
1237 break;
1238 }
1239 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001240 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001241 TAG, "Adding window " + win + " at "
1242 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001243 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001244 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001245 }
1246 }
1247 }
1248 } else {
1249 // Figure out where window should go, based on layer.
1250 final int myLayer = win.mBaseLayer;
1251 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07001252 if (localmWindows.get(i).mBaseLayer <= myLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001253 i++;
1254 break;
1255 }
1256 }
1257 if (i < 0) i = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001258 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001259 TAG, "Adding window " + win + " at "
1260 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001261 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001262 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001263 }
1264 if (addToToken) {
1265 token.windows.add(tokenWindowsPos, win);
1266 }
1267
1268 } else {
1269 // Figure out this window's ordering relative to the window
1270 // it is attached to.
1271 final int NA = token.windows.size();
1272 final int sublayer = win.mSubLayer;
1273 int largestSublayer = Integer.MIN_VALUE;
1274 WindowState windowWithLargestSublayer = null;
1275 for (i=0; i<NA; i++) {
1276 WindowState w = token.windows.get(i);
1277 final int wSublayer = w.mSubLayer;
1278 if (wSublayer >= largestSublayer) {
1279 largestSublayer = wSublayer;
1280 windowWithLargestSublayer = w;
1281 }
1282 if (sublayer < 0) {
1283 // For negative sublayers, we go below all windows
1284 // in the same sublayer.
1285 if (wSublayer >= sublayer) {
1286 if (addToToken) {
1287 token.windows.add(i, win);
1288 }
1289 placeWindowBefore(
1290 wSublayer >= 0 ? attached : w, win);
1291 break;
1292 }
1293 } else {
1294 // For positive sublayers, we go above all windows
1295 // in the same sublayer.
1296 if (wSublayer > sublayer) {
1297 if (addToToken) {
1298 token.windows.add(i, win);
1299 }
1300 placeWindowBefore(w, win);
1301 break;
1302 }
1303 }
1304 }
1305 if (i >= NA) {
1306 if (addToToken) {
1307 token.windows.add(win);
1308 }
1309 if (sublayer < 0) {
1310 placeWindowBefore(attached, win);
1311 } else {
1312 placeWindowAfter(largestSublayer >= 0
1313 ? windowWithLargestSublayer
1314 : attached,
1315 win);
1316 }
1317 }
1318 }
Romain Guy06882f82009-06-10 13:36:04 -07001319
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001320 if (win.mAppToken != null && addToToken) {
1321 win.mAppToken.allAppWindows.add(win);
1322 }
1323 }
Romain Guy06882f82009-06-10 13:36:04 -07001324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001325 static boolean canBeImeTarget(WindowState w) {
1326 final int fl = w.mAttrs.flags
1327 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
1328 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) {
1329 return w.isVisibleOrAdding();
1330 }
1331 return false;
1332 }
Romain Guy06882f82009-06-10 13:36:04 -07001333
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001334 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
Jeff Browne33348b2010-07-15 23:54:05 -07001335 final ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001336 final int N = localmWindows.size();
1337 WindowState w = null;
1338 int i = N;
1339 while (i > 0) {
1340 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001341 w = localmWindows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -07001342
Joe Onorato8a9b2202010-02-26 18:56:32 -08001343 //Slog.i(TAG, "Checking window @" + i + " " + w + " fl=0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001344 // + Integer.toHexString(w.mAttrs.flags));
1345 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001346 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -07001347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001348 // Yet more tricksyness! If this window is a "starting"
1349 // window, we do actually want to be on top of it, but
1350 // it is not -really- where input will go. So if the caller
1351 // is not actually looking to move the IME, look down below
1352 // for a real window to target...
1353 if (!willMove
1354 && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
1355 && i > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001356 WindowState wb = localmWindows.get(i-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001357 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1358 i--;
1359 w = wb;
1360 }
1361 }
1362 break;
1363 }
1364 }
Romain Guy06882f82009-06-10 13:36:04 -07001365
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001366 // Now, a special case -- if the last target's window is in the
1367 // process of exiting, and is above the new target, keep on the
1368 // last target to avoid flicker. Consider for example a Dialog with
1369 // the IME shown: when the Dialog is dismissed, we want to keep
1370 // the IME above it until it is completely gone so it doesn't drop
1371 // behind the dialog or its full-screen scrim.
1372 if (mInputMethodTarget != null && w != null
1373 && mInputMethodTarget.isDisplayedLw()
1374 && mInputMethodTarget.mExiting) {
1375 if (mInputMethodTarget.mAnimLayer > w.mAnimLayer) {
1376 w = mInputMethodTarget;
1377 i = localmWindows.indexOf(w);
1378 }
1379 }
Romain Guy06882f82009-06-10 13:36:04 -07001380
Joe Onorato8a9b2202010-02-26 18:56:32 -08001381 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001382 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -07001383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001384 if (willMove && w != null) {
1385 final WindowState curTarget = mInputMethodTarget;
1386 if (curTarget != null && curTarget.mAppToken != null) {
Romain Guy06882f82009-06-10 13:36:04 -07001387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001388 // Now some fun for dealing with window animations that
1389 // modify the Z order. We need to look at all windows below
1390 // the current target that are in this app, finding the highest
1391 // visible one in layering.
1392 AppWindowToken token = curTarget.mAppToken;
1393 WindowState highestTarget = null;
1394 int highestPos = 0;
1395 if (token.animating || token.animation != null) {
1396 int pos = 0;
1397 pos = localmWindows.indexOf(curTarget);
1398 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001399 WindowState win = localmWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001400 if (win.mAppToken != token) {
1401 break;
1402 }
1403 if (!win.mRemoved) {
1404 if (highestTarget == null || win.mAnimLayer >
1405 highestTarget.mAnimLayer) {
1406 highestTarget = win;
1407 highestPos = pos;
1408 }
1409 }
1410 pos--;
1411 }
1412 }
Romain Guy06882f82009-06-10 13:36:04 -07001413
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001414 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001415 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001416 + mNextAppTransition + " " + highestTarget
1417 + " animating=" + highestTarget.isAnimating()
1418 + " layer=" + highestTarget.mAnimLayer
1419 + " new layer=" + w.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001420
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001421 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001422 // If we are currently setting up for an animation,
1423 // hold everything until we can find out what will happen.
1424 mInputMethodTargetWaitingAnim = true;
1425 mInputMethodTarget = highestTarget;
1426 return highestPos + 1;
1427 } else if (highestTarget.isAnimating() &&
1428 highestTarget.mAnimLayer > w.mAnimLayer) {
1429 // If the window we are currently targeting is involved
1430 // with an animation, and it is on top of the next target
1431 // we will be over, then hold off on moving until
1432 // that is done.
1433 mInputMethodTarget = highestTarget;
1434 return highestPos + 1;
1435 }
1436 }
1437 }
1438 }
Romain Guy06882f82009-06-10 13:36:04 -07001439
Joe Onorato8a9b2202010-02-26 18:56:32 -08001440 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001441 if (w != null) {
1442 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001443 if (DEBUG_INPUT_METHOD) {
1444 RuntimeException e = null;
1445 if (!HIDE_STACK_CRAWLS) {
1446 e = new RuntimeException();
1447 e.fillInStackTrace();
1448 }
1449 Slog.w(TAG, "Moving IM target from "
1450 + mInputMethodTarget + " to " + w, e);
1451 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001452 mInputMethodTarget = w;
1453 if (w.mAppToken != null) {
1454 setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment);
1455 } else {
1456 setInputMethodAnimLayerAdjustment(0);
1457 }
1458 }
1459 return i+1;
1460 }
1461 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001462 if (DEBUG_INPUT_METHOD) {
1463 RuntimeException e = null;
1464 if (!HIDE_STACK_CRAWLS) {
1465 e = new RuntimeException();
1466 e.fillInStackTrace();
1467 }
1468 Slog.w(TAG, "Moving IM target from "
1469 + mInputMethodTarget + " to null", e);
1470 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001471 mInputMethodTarget = null;
1472 setInputMethodAnimLayerAdjustment(0);
1473 }
1474 return -1;
1475 }
Romain Guy06882f82009-06-10 13:36:04 -07001476
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001477 void addInputMethodWindowToListLocked(WindowState win) {
1478 int pos = findDesiredInputMethodWindowIndexLocked(true);
1479 if (pos >= 0) {
1480 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001481 if (DEBUG_WINDOW_MOVEMENT) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001482 TAG, "Adding input method window " + win + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001483 mWindows.add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001484 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001485 moveInputMethodDialogsLocked(pos+1);
1486 return;
1487 }
1488 win.mTargetAppToken = null;
1489 addWindowToListInOrderLocked(win, true);
1490 moveInputMethodDialogsLocked(pos);
1491 }
Romain Guy06882f82009-06-10 13:36:04 -07001492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001493 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001494 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001495 mInputMethodAnimLayerAdjustment = adj;
1496 WindowState imw = mInputMethodWindow;
1497 if (imw != null) {
1498 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001499 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001500 + " anim layer: " + imw.mAnimLayer);
1501 int wi = imw.mChildWindows.size();
1502 while (wi > 0) {
1503 wi--;
Jeff Browne33348b2010-07-15 23:54:05 -07001504 WindowState cw = imw.mChildWindows.get(wi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 cw.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001506 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001507 + " anim layer: " + cw.mAnimLayer);
1508 }
1509 }
1510 int di = mInputMethodDialogs.size();
1511 while (di > 0) {
1512 di --;
1513 imw = mInputMethodDialogs.get(di);
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 }
1518 }
Romain Guy06882f82009-06-10 13:36:04 -07001519
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
1521 int wpos = mWindows.indexOf(win);
1522 if (wpos >= 0) {
1523 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001524 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001525 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001526 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001527 int NC = win.mChildWindows.size();
1528 while (NC > 0) {
1529 NC--;
Jeff Browne33348b2010-07-15 23:54:05 -07001530 WindowState cw = win.mChildWindows.get(NC);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001531 int cpos = mWindows.indexOf(cw);
1532 if (cpos >= 0) {
1533 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001534 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001535 + cpos + ": " + cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001536 mWindows.remove(cpos);
1537 }
1538 }
1539 }
1540 return interestingPos;
1541 }
Romain Guy06882f82009-06-10 13:36:04 -07001542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001543 private void reAddWindowToListInOrderLocked(WindowState win) {
1544 addWindowToListInOrderLocked(win, false);
1545 // This is a hack to get all of the child windows added as well
1546 // at the right position. Child windows should be rare and
1547 // this case should be rare, so it shouldn't be that big a deal.
1548 int wpos = mWindows.indexOf(win);
1549 if (wpos >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001550 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001551 + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001552 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001553 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001554 reAddWindowLocked(wpos, win);
1555 }
1556 }
Romain Guy06882f82009-06-10 13:36:04 -07001557
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001558 void logWindowList(String prefix) {
1559 int N = mWindows.size();
1560 while (N > 0) {
1561 N--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001562 Slog.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 }
1564 }
Romain Guy06882f82009-06-10 13:36:04 -07001565
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001566 void moveInputMethodDialogsLocked(int pos) {
1567 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001568
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001569 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001570 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001571 for (int i=0; i<N; i++) {
1572 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1573 }
1574 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001575 Slog.v(TAG, "Window list w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001576 logWindowList(" ");
1577 }
Romain Guy06882f82009-06-10 13:36:04 -07001578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001579 if (pos >= 0) {
1580 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
1581 if (pos < mWindows.size()) {
Jeff Browne33348b2010-07-15 23:54:05 -07001582 WindowState wp = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001583 if (wp == mInputMethodWindow) {
1584 pos++;
1585 }
1586 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001587 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001588 for (int i=0; i<N; i++) {
1589 WindowState win = dialogs.get(i);
1590 win.mTargetAppToken = targetAppToken;
1591 pos = reAddWindowLocked(pos, win);
1592 }
1593 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001594 Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001595 logWindowList(" ");
1596 }
1597 return;
1598 }
1599 for (int i=0; i<N; i++) {
1600 WindowState win = dialogs.get(i);
1601 win.mTargetAppToken = null;
1602 reAddWindowToListInOrderLocked(win);
1603 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001604 Slog.v(TAG, "No IM target, final list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001605 logWindowList(" ");
1606 }
1607 }
1608 }
Romain Guy06882f82009-06-10 13:36:04 -07001609
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001610 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1611 final WindowState imWin = mInputMethodWindow;
1612 final int DN = mInputMethodDialogs.size();
1613 if (imWin == null && DN == 0) {
1614 return false;
1615 }
Romain Guy06882f82009-06-10 13:36:04 -07001616
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001617 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1618 if (imPos >= 0) {
1619 // In this case, the input method windows are to be placed
1620 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001621
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001622 // First check to see if the input method windows are already
1623 // located here, and contiguous.
1624 final int N = mWindows.size();
1625 WindowState firstImWin = imPos < N
Jeff Browne33348b2010-07-15 23:54:05 -07001626 ? mWindows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001628 // Figure out the actual input method window that should be
1629 // at the bottom of their stack.
1630 WindowState baseImWin = imWin != null
1631 ? imWin : mInputMethodDialogs.get(0);
1632 if (baseImWin.mChildWindows.size() > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001633 WindowState cw = baseImWin.mChildWindows.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001634 if (cw.mSubLayer < 0) baseImWin = cw;
1635 }
Romain Guy06882f82009-06-10 13:36:04 -07001636
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001637 if (firstImWin == baseImWin) {
1638 // The windows haven't moved... but are they still contiguous?
1639 // First find the top IM window.
1640 int pos = imPos+1;
1641 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001642 if (!(mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001643 break;
1644 }
1645 pos++;
1646 }
1647 pos++;
1648 // Now there should be no more input method windows above.
1649 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001650 if ((mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001651 break;
1652 }
1653 pos++;
1654 }
1655 if (pos >= N) {
1656 // All is good!
1657 return false;
1658 }
1659 }
Romain Guy06882f82009-06-10 13:36:04 -07001660
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001661 if (imWin != null) {
1662 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001663 Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001664 logWindowList(" ");
1665 }
1666 imPos = tmpRemoveWindowLocked(imPos, imWin);
1667 if (DEBUG_INPUT_METHOD) {
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001668 Slog.v(TAG, "List after removing with new pos " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001669 logWindowList(" ");
1670 }
1671 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1672 reAddWindowLocked(imPos, imWin);
1673 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001674 Slog.v(TAG, "List after moving IM to " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001675 logWindowList(" ");
1676 }
1677 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1678 } else {
1679 moveInputMethodDialogsLocked(imPos);
1680 }
Romain Guy06882f82009-06-10 13:36:04 -07001681
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001682 } else {
1683 // In this case, the input method windows go in a fixed layer,
1684 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001686 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001687 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001688 tmpRemoveWindowLocked(0, imWin);
1689 imWin.mTargetAppToken = null;
1690 reAddWindowToListInOrderLocked(imWin);
1691 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001692 Slog.v(TAG, "List with no IM target:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001693 logWindowList(" ");
1694 }
1695 if (DN > 0) moveInputMethodDialogsLocked(-1);;
1696 } else {
1697 moveInputMethodDialogsLocked(-1);;
1698 }
Romain Guy06882f82009-06-10 13:36:04 -07001699
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001700 }
Romain Guy06882f82009-06-10 13:36:04 -07001701
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001702 if (needAssignLayers) {
1703 assignLayersLocked();
1704 }
Romain Guy06882f82009-06-10 13:36:04 -07001705
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001706 return true;
1707 }
Romain Guy06882f82009-06-10 13:36:04 -07001708
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001709 void adjustInputMethodDialogsLocked() {
1710 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1711 }
Romain Guy06882f82009-06-10 13:36:04 -07001712
Dianne Hackborn25994b42009-09-04 14:21:19 -07001713 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001714 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001715 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1716 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
1717 ? wallpaperTarget.mAppToken.animation : null)
1718 + " upper=" + mUpperWallpaperTarget
1719 + " lower=" + mLowerWallpaperTarget);
1720 return (wallpaperTarget != null
1721 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
1722 && wallpaperTarget.mAppToken.animation != null)))
1723 || mUpperWallpaperTarget != null
1724 || mLowerWallpaperTarget != null;
1725 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001726
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001727 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1728 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001729
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001730 int adjustWallpaperWindowsLocked() {
1731 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001732
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001733 final int dw = mDisplay.getWidth();
1734 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001735
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001736 // First find top-most window that has asked to be on top of the
1737 // wallpaper; all wallpapers go behind it.
Jeff Browne33348b2010-07-15 23:54:05 -07001738 final ArrayList<WindowState> localmWindows = mWindows;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001739 int N = localmWindows.size();
1740 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001741 WindowState foundW = null;
1742 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001743 WindowState topCurW = null;
1744 int topCurI = 0;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001745 int windowDetachedI = -1;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001746 int i = N;
1747 while (i > 0) {
1748 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001749 w = localmWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001750 if ((w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER)) {
1751 if (topCurW == null) {
1752 topCurW = w;
1753 topCurI = i;
1754 }
1755 continue;
1756 }
1757 topCurW = null;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001758 if (w != mWindowDetachedWallpaper && w.mAppToken != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001759 // If this window's app token is hidden and not animating,
1760 // it is of no interest to us.
1761 if (w.mAppToken.hidden && w.mAppToken.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001762 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001763 "Skipping not hidden or animating token: " + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001764 continue;
1765 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001766 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001767 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": readyfordisplay="
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001768 + w.isReadyForDisplay() + " drawpending=" + w.mDrawPending
1769 + " commitdrawpending=" + w.mCommitDrawPending);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001770 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07001771 && (mWallpaperTarget == w
1772 || (!w.mDrawPending && !w.mCommitDrawPending))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001773 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001774 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001775 foundW = w;
1776 foundI = i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001777 if (w == mWallpaperTarget && ((w.mAppToken != null
1778 && w.mAppToken.animation != null)
1779 || w.mAnimation != null)) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001780 // The current wallpaper target is animating, so we'll
1781 // look behind it for another possible target and figure
1782 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001783 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001784 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001785 continue;
1786 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001787 break;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001788 } else if (w == mWindowDetachedWallpaper) {
1789 windowDetachedI = i;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001790 }
1791 }
1792
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001793 if (foundW == null && windowDetachedI >= 0) {
1794 if (DEBUG_WALLPAPER) Slog.v(TAG,
1795 "Found animating detached wallpaper activity: #" + i + "=" + w);
1796 foundW = w;
1797 foundI = windowDetachedI;
1798 }
1799
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001800 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001801 // If we are currently waiting for an app transition, and either
1802 // the current target or the next target are involved with it,
1803 // then hold off on doing anything with the wallpaper.
1804 // Note that we are checking here for just whether the target
1805 // is part of an app token... which is potentially overly aggressive
1806 // (the app token may not be involved in the transition), but good
1807 // enough (we'll just wait until whatever transition is pending
1808 // executes).
1809 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001810 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001811 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001812 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001813 }
1814 if (foundW != null && foundW.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001815 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001816 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001817 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001818 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001819 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001820
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001821 if (mWallpaperTarget != foundW) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001822 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001823 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001824 + " oldTarget: " + mWallpaperTarget);
1825 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001826
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001827 mLowerWallpaperTarget = null;
1828 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001829
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001830 WindowState oldW = mWallpaperTarget;
1831 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001832
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001833 // Now what is happening... if the current and new targets are
1834 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001835 if (foundW != null && oldW != null) {
1836 boolean oldAnim = oldW.mAnimation != null
1837 || (oldW.mAppToken != null && oldW.mAppToken.animation != null);
1838 boolean foundAnim = foundW.mAnimation != null
1839 || (foundW.mAppToken != null && foundW.mAppToken.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001840 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001841 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001842 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001843 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001844 if (foundAnim && oldAnim) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001845 int oldI = localmWindows.indexOf(oldW);
1846 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001847 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001848 }
1849 if (oldI >= 0) {
1850 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001851 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001852 + "=" + oldW + "; new#" + foundI
1853 + "=" + foundW);
1854 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001855
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001856 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001857 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001858 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001859 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001860 }
1861 mWallpaperTarget = oldW;
1862 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001863
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001864 // Now set the upper and lower wallpaper targets
1865 // correctly, and make sure that we are positioning
1866 // the wallpaper below the lower.
1867 if (foundI > oldI) {
1868 // The new target is on top of the old one.
1869 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001870 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001871 }
1872 mUpperWallpaperTarget = foundW;
1873 mLowerWallpaperTarget = oldW;
1874 foundW = oldW;
1875 foundI = oldI;
1876 } else {
1877 // The new target is below the old one.
1878 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001879 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001880 }
1881 mUpperWallpaperTarget = oldW;
1882 mLowerWallpaperTarget = foundW;
1883 }
1884 }
1885 }
1886 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001887
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001888 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001889 // Is it time to stop animating?
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001890 boolean lowerAnimating = mLowerWallpaperTarget.mAnimation != null
1891 || (mLowerWallpaperTarget.mAppToken != null
1892 && mLowerWallpaperTarget.mAppToken.animation != null);
1893 boolean upperAnimating = mUpperWallpaperTarget.mAnimation != null
1894 || (mUpperWallpaperTarget.mAppToken != null
1895 && mUpperWallpaperTarget.mAppToken.animation != null);
1896 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001897 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001898 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001899 }
1900 mLowerWallpaperTarget = null;
1901 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001902 }
1903 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001904
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001905 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001906 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001907 // The window is visible to the compositor... but is it visible
1908 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001909 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001910 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001911
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001912 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001913 // its layer adjustment. Only do this if we are not transfering
1914 // between two wallpaper targets.
1915 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001916 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001917 ? foundW.mAppToken.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001918
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001919 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1920 * TYPE_LAYER_MULTIPLIER
1921 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001922
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001923 // Now w is the window we are supposed to be behind... but we
1924 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001925 // AND any starting window associated with it, AND below the
1926 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001927 while (foundI > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001928 WindowState wb = localmWindows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001929 if (wb.mBaseLayer < maxLayer &&
1930 wb.mAttachedWindow != foundW &&
Pal Szasz73dc2592010-09-03 11:46:26 +02001931 wb.mAttachedWindow != foundW.mAttachedWindow &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001932 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001933 wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001934 // This window is not related to the previous one in any
1935 // interesting way, so stop here.
1936 break;
1937 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001938 foundW = wb;
1939 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001940 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001941 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001942 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001943 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001944
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001945 if (foundW == null && topCurW != null) {
1946 // There is no wallpaper target, so it goes at the bottom.
1947 // We will assume it is the same place as last time, if known.
1948 foundW = topCurW;
1949 foundI = topCurI+1;
1950 } else {
1951 // Okay i is the position immediately above the wallpaper. Look at
1952 // what is below it for later.
Jeff Browne33348b2010-07-15 23:54:05 -07001953 foundW = foundI > 0 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001954 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001955
Dianne Hackborn284ac932009-08-28 10:34:25 -07001956 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001957 if (mWallpaperTarget.mWallpaperX >= 0) {
1958 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001959 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001960 }
1961 if (mWallpaperTarget.mWallpaperY >= 0) {
1962 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001963 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001964 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001965 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001966
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001967 // Start stepping backwards from here, ensuring that our wallpaper windows
1968 // are correctly placed.
1969 int curTokenIndex = mWallpaperTokens.size();
1970 while (curTokenIndex > 0) {
1971 curTokenIndex--;
1972 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001973 if (token.hidden == visible) {
1974 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1975 token.hidden = !visible;
1976 // Need to do a layout to ensure the wallpaper now has the
1977 // correct size.
1978 mLayoutNeeded = true;
1979 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001980
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001981 int curWallpaperIndex = token.windows.size();
1982 while (curWallpaperIndex > 0) {
1983 curWallpaperIndex--;
1984 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001985
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001986 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001987 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001988 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001989
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001990 // First, make sure the client has the current visibility
1991 // state.
1992 if (wallpaper.mWallpaperVisible != visible) {
1993 wallpaper.mWallpaperVisible = visible;
1994 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001995 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001996 "Setting visibility of wallpaper " + wallpaper
1997 + ": " + visible);
1998 wallpaper.mClient.dispatchAppVisibility(visible);
1999 } catch (RemoteException e) {
2000 }
2001 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002002
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002003 wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002004 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002005 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002006
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002007 // First, if this window is at the current index, then all
2008 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002009 if (wallpaper == foundW) {
2010 foundI--;
2011 foundW = foundI > 0
Jeff Browne33348b2010-07-15 23:54:05 -07002012 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002013 continue;
2014 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002015
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002016 // The window didn't match... the current wallpaper window,
2017 // wherever it is, is in the wrong place, so make sure it is
2018 // not in the list.
2019 int oldIndex = localmWindows.indexOf(wallpaper);
2020 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002021 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07002022 + oldIndex + ": " + wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002023 localmWindows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002024 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002025 if (oldIndex < foundI) {
2026 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002027 }
2028 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002029
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002030 // Now stick it in.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002031 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07002032 "Moving wallpaper " + wallpaper
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002033 + " from " + oldIndex + " to " + foundI);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002034
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002035 localmWindows.add(foundI, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002036 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002037 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002038 }
2039 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002040
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002041 return changed;
2042 }
2043
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002044 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002045 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002046 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002047 mWallpaperAnimLayerAdjustment = adj;
2048 int curTokenIndex = mWallpaperTokens.size();
2049 while (curTokenIndex > 0) {
2050 curTokenIndex--;
2051 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2052 int curWallpaperIndex = token.windows.size();
2053 while (curWallpaperIndex > 0) {
2054 curWallpaperIndex--;
2055 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2056 wallpaper.mAnimLayer = wallpaper.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002057 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002058 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002059 }
2060 }
2061 }
2062
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002063 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
2064 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002065 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002066 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002067 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002068 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002069 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
2070 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
2071 changed = wallpaperWin.mXOffset != offset;
2072 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002073 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002074 + wallpaperWin + " x: " + offset);
2075 wallpaperWin.mXOffset = offset;
2076 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002077 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002078 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002079 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002080 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002081 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002082
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002083 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002084 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002085 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
2086 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
2087 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002088 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002089 + wallpaperWin + " y: " + offset);
2090 changed = true;
2091 wallpaperWin.mYOffset = offset;
2092 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002093 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002094 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002095 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002096 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002097 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002098
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07002099 if (rawChanged) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002100 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002101 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002102 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
2103 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002104 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002105 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002106 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002107 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002108 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
2109 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002110 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002111 if (mWaitingOnWallpaper != null) {
2112 long start = SystemClock.uptimeMillis();
2113 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
2114 < start) {
2115 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002116 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07002117 "Waiting for offset complete...");
2118 mWindowMap.wait(WALLPAPER_TIMEOUT);
2119 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002120 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002121 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07002122 if ((start+WALLPAPER_TIMEOUT)
2123 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002124 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07002125 + wallpaperWin);
2126 mLastWallpaperTimeoutTime = start;
2127 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002128 }
Dianne Hackborn75804932009-10-20 20:15:20 -07002129 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002130 }
2131 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07002132 } catch (RemoteException e) {
2133 }
2134 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002135
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002136 return changed;
2137 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002138
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002139 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07002140 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002141 if (mWaitingOnWallpaper != null &&
2142 mWaitingOnWallpaper.mClient.asBinder() == window) {
2143 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07002144 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002145 }
2146 }
2147 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002148
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002149 boolean updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002150 final int dw = mDisplay.getWidth();
2151 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002152
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002153 boolean changed = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002154
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002155 WindowState target = mWallpaperTarget;
2156 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002157 if (target.mWallpaperX >= 0) {
2158 mLastWallpaperX = target.mWallpaperX;
2159 } else if (changingTarget.mWallpaperX >= 0) {
2160 mLastWallpaperX = changingTarget.mWallpaperX;
2161 }
2162 if (target.mWallpaperY >= 0) {
2163 mLastWallpaperY = target.mWallpaperY;
2164 } else if (changingTarget.mWallpaperY >= 0) {
2165 mLastWallpaperY = changingTarget.mWallpaperY;
2166 }
2167 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002168
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002169 int curTokenIndex = mWallpaperTokens.size();
2170 while (curTokenIndex > 0) {
2171 curTokenIndex--;
2172 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2173 int curWallpaperIndex = token.windows.size();
2174 while (curWallpaperIndex > 0) {
2175 curWallpaperIndex--;
2176 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2177 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
2178 wallpaper.computeShownFrameLocked();
2179 changed = true;
2180 // We only want to be synchronous with one wallpaper.
2181 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002182 }
2183 }
2184 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002185
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002186 return changed;
2187 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002188
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002189 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07002190 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002191 final int dw = mDisplay.getWidth();
2192 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002193
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002194 int curTokenIndex = mWallpaperTokens.size();
2195 while (curTokenIndex > 0) {
2196 curTokenIndex--;
2197 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002198 if (token.hidden == visible) {
2199 token.hidden = !visible;
2200 // Need to do a layout to ensure the wallpaper now has the
2201 // correct size.
2202 mLayoutNeeded = true;
2203 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002204
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002205 int curWallpaperIndex = token.windows.size();
2206 while (curWallpaperIndex > 0) {
2207 curWallpaperIndex--;
2208 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2209 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002210 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002211 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002212
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002213 if (wallpaper.mWallpaperVisible != visible) {
2214 wallpaper.mWallpaperVisible = visible;
2215 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002216 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07002217 "Updating visibility of wallpaper " + wallpaper
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002218 + ": " + visible);
2219 wallpaper.mClient.dispatchAppVisibility(visible);
2220 } catch (RemoteException e) {
2221 }
2222 }
2223 }
2224 }
2225 }
Dianne Hackborn90d2db32010-02-11 22:19:06 -08002226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002227 public int addWindow(Session session, IWindow client,
2228 WindowManager.LayoutParams attrs, int viewVisibility,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002229 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002230 int res = mPolicy.checkAddPermission(attrs);
2231 if (res != WindowManagerImpl.ADD_OKAY) {
2232 return res;
2233 }
Romain Guy06882f82009-06-10 13:36:04 -07002234
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002235 boolean reportNewConfig = false;
2236 WindowState attachedWindow = null;
2237 WindowState win = null;
Dianne Hackborn5132b372010-07-29 12:51:35 -07002238 long origId;
Romain Guy06882f82009-06-10 13:36:04 -07002239
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002240 synchronized(mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002241 if (mDisplay == null) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07002242 throw new IllegalStateException("Display has not been initialialized");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002243 }
Romain Guy06882f82009-06-10 13:36:04 -07002244
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002245 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002246 Slog.w(TAG, "Window " + client + " is already added");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002247 return WindowManagerImpl.ADD_DUPLICATE_ADD;
2248 }
2249
2250 if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002251 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002252 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002253 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002254 + attrs.token + ". Aborting.");
2255 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2256 }
2257 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
2258 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002259 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002260 + attrs.token + ". Aborting.");
2261 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
2262 }
2263 }
2264
2265 boolean addToken = false;
2266 WindowToken token = mTokenMap.get(attrs.token);
2267 if (token == null) {
2268 if (attrs.type >= FIRST_APPLICATION_WINDOW
2269 && attrs.type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002270 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002271 + attrs.token + ". Aborting.");
2272 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2273 }
2274 if (attrs.type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002275 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002276 + attrs.token + ". Aborting.");
2277 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2278 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002279 if (attrs.type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002280 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002281 + attrs.token + ". Aborting.");
2282 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2283 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002284 token = new WindowToken(attrs.token, -1, false);
2285 addToken = true;
2286 } else if (attrs.type >= FIRST_APPLICATION_WINDOW
2287 && attrs.type <= LAST_APPLICATION_WINDOW) {
2288 AppWindowToken atoken = token.appWindowToken;
2289 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002290 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002291 + token + ". Aborting.");
2292 return WindowManagerImpl.ADD_NOT_APP_TOKEN;
2293 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002294 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002295 + token + ". Aborting.");
2296 return WindowManagerImpl.ADD_APP_EXITING;
2297 }
2298 if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
2299 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002300 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002301 TAG, "**** NO NEED TO START: " + attrs.getTitle());
2302 return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
2303 }
2304 } else if (attrs.type == TYPE_INPUT_METHOD) {
2305 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002306 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002307 + attrs.token + ". Aborting.");
2308 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2309 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002310 } else if (attrs.type == TYPE_WALLPAPER) {
2311 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002312 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002313 + attrs.token + ". Aborting.");
2314 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2315 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002316 }
2317
2318 win = new WindowState(session, client, token,
2319 attachedWindow, attrs, viewVisibility);
2320 if (win.mDeathRecipient == null) {
2321 // Client has apparently died, so there is no reason to
2322 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002323 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002324 + " that is dead, aborting.");
2325 return WindowManagerImpl.ADD_APP_EXITING;
2326 }
2327
2328 mPolicy.adjustWindowParamsLw(win.mAttrs);
Romain Guy06882f82009-06-10 13:36:04 -07002329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002330 res = mPolicy.prepareAddWindowLw(win, attrs);
2331 if (res != WindowManagerImpl.ADD_OKAY) {
2332 return res;
2333 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002334
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002335 if (outInputChannel != null) {
2336 String name = win.makeInputChannelName();
2337 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
2338 win.mInputChannel = inputChannels[0];
2339 inputChannels[1].transferToBinderOutParameter(outInputChannel);
2340
Jeff Brown928e0542011-01-10 11:17:36 -08002341 mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002342 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002343
2344 // From now on, no exceptions or errors allowed!
2345
2346 res = WindowManagerImpl.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002347
Dianne Hackborn5132b372010-07-29 12:51:35 -07002348 origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002349
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002350 if (addToken) {
2351 mTokenMap.put(attrs.token, token);
2352 mTokenList.add(token);
2353 }
2354 win.attach();
2355 mWindowMap.put(client.asBinder(), win);
2356
2357 if (attrs.type == TYPE_APPLICATION_STARTING &&
2358 token.appWindowToken != null) {
2359 token.appWindowToken.startingWindow = win;
2360 }
2361
2362 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002363
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002364 if (attrs.type == TYPE_INPUT_METHOD) {
2365 mInputMethodWindow = win;
2366 addInputMethodWindowToListLocked(win);
2367 imMayMove = false;
2368 } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
2369 mInputMethodDialogs.add(win);
2370 addWindowToListInOrderLocked(win, true);
2371 adjustInputMethodDialogsLocked();
2372 imMayMove = false;
2373 } else {
2374 addWindowToListInOrderLocked(win, true);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002375 if (attrs.type == TYPE_WALLPAPER) {
2376 mLastWallpaperTimeoutTime = 0;
2377 adjustWallpaperWindowsLocked();
2378 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002379 adjustWallpaperWindowsLocked();
2380 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002381 }
Romain Guy06882f82009-06-10 13:36:04 -07002382
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002383 win.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002384
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002385 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
Romain Guy06882f82009-06-10 13:36:04 -07002386
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002387 if (mInTouchMode) {
2388 res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
2389 }
2390 if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
2391 res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
2392 }
Romain Guy06882f82009-06-10 13:36:04 -07002393
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002394 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002395 if (win.canReceiveKeys()) {
Jeff Brown349703e2010-06-22 01:27:15 -07002396 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS);
2397 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002398 imMayMove = false;
2399 }
2400 }
Romain Guy06882f82009-06-10 13:36:04 -07002401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002402 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002403 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002404 }
Romain Guy06882f82009-06-10 13:36:04 -07002405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002406 assignLayersLocked();
2407 // Don't do layout here, the window must call
2408 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002409
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002410 //dump();
2411
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002412 if (focusChanged) {
Jeff Brown349703e2010-06-22 01:27:15 -07002413 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002414 }
Jeff Brown349703e2010-06-22 01:27:15 -07002415
Joe Onorato8a9b2202010-02-26 18:56:32 -08002416 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002417 TAG, "New client " + client.asBinder()
2418 + ": window=" + win);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002419
2420 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked()) {
2421 reportNewConfig = true;
2422 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002423 }
2424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002425 if (reportNewConfig) {
2426 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002427 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07002428
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002429 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002430
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002431 return res;
2432 }
Romain Guy06882f82009-06-10 13:36:04 -07002433
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002434 public void removeWindow(Session session, IWindow client) {
2435 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002436 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002437 if (win == null) {
2438 return;
2439 }
2440 removeWindowLocked(session, win);
2441 }
2442 }
Romain Guy06882f82009-06-10 13:36:04 -07002443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002444 public void removeWindowLocked(Session session, WindowState win) {
2445
Joe Onorato8a9b2202010-02-26 18:56:32 -08002446 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002447 TAG, "Remove " + win + " client="
2448 + Integer.toHexString(System.identityHashCode(
2449 win.mClient.asBinder()))
2450 + ", surface=" + win.mSurface);
2451
2452 final long origId = Binder.clearCallingIdentity();
Jeff Brownc5ed5912010-07-14 18:48:53 -07002453
2454 win.disposeInputChannel();
Romain Guy06882f82009-06-10 13:36:04 -07002455
Joe Onorato8a9b2202010-02-26 18:56:32 -08002456 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002457 TAG, "Remove " + win + ": mSurface=" + win.mSurface
2458 + " mExiting=" + win.mExiting
2459 + " isAnimating=" + win.isAnimating()
2460 + " app-animation="
2461 + (win.mAppToken != null ? win.mAppToken.animation : null)
2462 + " inPendingTransaction="
2463 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2464 + " mDisplayFrozen=" + mDisplayFrozen);
2465 // Visibility of the removed window. Will be used later to update orientation later on.
2466 boolean wasVisible = false;
2467 // First, see if we need to run an animation. If we do, we have
2468 // to hold off on removing the window until the animation is done.
2469 // If the display is frozen, just remove immediately, since the
2470 // animation wouldn't be seen.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002471 if (win.mSurface != null && !mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002472 // If we are not currently running the exit animation, we
2473 // need to see about starting one.
2474 if (wasVisible=win.isWinVisibleLw()) {
Romain Guy06882f82009-06-10 13:36:04 -07002475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002476 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2477 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2478 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2479 }
2480 // Try starting an animation.
2481 if (applyAnimationLocked(win, transit, false)) {
2482 win.mExiting = true;
2483 }
2484 }
2485 if (win.mExiting || win.isAnimating()) {
2486 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002487 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002488 win.mExiting = true;
2489 win.mRemoveOnExit = true;
2490 mLayoutNeeded = true;
2491 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
2492 performLayoutAndPlaceSurfacesLocked();
2493 if (win.mAppToken != null) {
2494 win.mAppToken.updateReportedVisibilityLocked();
2495 }
2496 //dump();
2497 Binder.restoreCallingIdentity(origId);
2498 return;
2499 }
2500 }
2501
2502 removeWindowInnerLocked(session, win);
2503 // Removing a visible window will effect the computed orientation
2504 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002505 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002506 != mForcedAppOrientation
2507 && updateOrientationFromAppTokensLocked()) {
2508 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002509 }
2510 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
2511 Binder.restoreCallingIdentity(origId);
2512 }
Romain Guy06882f82009-06-10 13:36:04 -07002513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002514 private void removeWindowInnerLocked(Session session, WindowState win) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002515 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002517 if (mInputMethodTarget == win) {
2518 moveInputMethodWindowsIfNeededLocked(false);
2519 }
Romain Guy06882f82009-06-10 13:36:04 -07002520
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002521 if (false) {
2522 RuntimeException e = new RuntimeException("here");
2523 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002524 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002525 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002526
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002527 mPolicy.removeWindowLw(win);
2528 win.removeLocked();
2529
2530 mWindowMap.remove(win.mClient.asBinder());
2531 mWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002532 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002533 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002534
2535 if (mInputMethodWindow == win) {
2536 mInputMethodWindow = null;
2537 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2538 mInputMethodDialogs.remove(win);
2539 }
Romain Guy06882f82009-06-10 13:36:04 -07002540
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002541 final WindowToken token = win.mToken;
2542 final AppWindowToken atoken = win.mAppToken;
2543 token.windows.remove(win);
2544 if (atoken != null) {
2545 atoken.allAppWindows.remove(win);
2546 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002547 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002548 TAG, "**** Removing window " + win + ": count="
2549 + token.windows.size());
2550 if (token.windows.size() == 0) {
2551 if (!token.explicit) {
2552 mTokenMap.remove(token.token);
2553 mTokenList.remove(token);
2554 } else if (atoken != null) {
2555 atoken.firstWindowDrawn = false;
2556 }
2557 }
2558
2559 if (atoken != null) {
2560 if (atoken.startingWindow == win) {
2561 atoken.startingWindow = null;
2562 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2563 // If this is the last window and we had requested a starting
2564 // transition window, well there is no point now.
2565 atoken.startingData = null;
2566 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2567 // If this is the last window except for a starting transition
2568 // window, we need to get rid of the starting transition.
2569 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002570 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002571 + ": no more real windows");
2572 }
2573 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2574 mH.sendMessage(m);
2575 }
2576 }
Romain Guy06882f82009-06-10 13:36:04 -07002577
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002578 if (win.mAttrs.type == TYPE_WALLPAPER) {
2579 mLastWallpaperTimeoutTime = 0;
2580 adjustWallpaperWindowsLocked();
2581 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002582 adjustWallpaperWindowsLocked();
2583 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002584
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002585 if (!mInLayout) {
2586 assignLayersLocked();
2587 mLayoutNeeded = true;
2588 performLayoutAndPlaceSurfacesLocked();
2589 if (win.mAppToken != null) {
2590 win.mAppToken.updateReportedVisibilityLocked();
2591 }
2592 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07002593
2594 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002595 }
2596
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002597 private static void logSurface(WindowState w, String msg, RuntimeException where) {
2598 String str = " SURFACE " + Integer.toHexString(w.hashCode())
2599 + ": " + msg + " / " + w.mAttrs.getTitle();
2600 if (where != null) {
2601 Slog.i(TAG, str, where);
2602 } else {
2603 Slog.i(TAG, str);
2604 }
2605 }
2606
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002607 private void setTransparentRegionWindow(Session session, IWindow client, Region region) {
2608 long origId = Binder.clearCallingIdentity();
2609 try {
2610 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002611 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002612 if ((w != null) && (w.mSurface != null)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002613 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002614 Surface.openTransaction();
2615 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002616 if (SHOW_TRANSACTIONS) logSurface(w,
2617 "transparentRegionHint=" + region, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002618 w.mSurface.setTransparentRegionHint(region);
2619 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002620 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002621 Surface.closeTransaction();
2622 }
2623 }
2624 }
2625 } finally {
2626 Binder.restoreCallingIdentity(origId);
2627 }
2628 }
2629
2630 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002631 int touchableInsets, Rect contentInsets,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002632 Rect visibleInsets) {
2633 long origId = Binder.clearCallingIdentity();
2634 try {
2635 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002636 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002637 if (w != null) {
2638 w.mGivenInsetsPending = false;
2639 w.mGivenContentInsets.set(contentInsets);
2640 w.mGivenVisibleInsets.set(visibleInsets);
2641 w.mTouchableInsets = touchableInsets;
2642 mLayoutNeeded = true;
2643 performLayoutAndPlaceSurfacesLocked();
2644 }
2645 }
2646 } finally {
2647 Binder.restoreCallingIdentity(origId);
2648 }
2649 }
Romain Guy06882f82009-06-10 13:36:04 -07002650
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002651 public void getWindowDisplayFrame(Session session, IWindow client,
2652 Rect outDisplayFrame) {
2653 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002654 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002655 if (win == null) {
2656 outDisplayFrame.setEmpty();
2657 return;
2658 }
2659 outDisplayFrame.set(win.mDisplayFrame);
2660 }
2661 }
2662
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002663 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2664 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002665 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2666 window.mWallpaperX = x;
2667 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002668 window.mWallpaperXStep = xStep;
2669 window.mWallpaperYStep = yStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002670 if (updateWallpaperOffsetLocked(window, true)) {
2671 performLayoutAndPlaceSurfacesLocked();
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002672 }
2673 }
2674 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002675
Dianne Hackborn75804932009-10-20 20:15:20 -07002676 void wallpaperCommandComplete(IBinder window, Bundle result) {
2677 synchronized (mWindowMap) {
2678 if (mWaitingOnWallpaper != null &&
2679 mWaitingOnWallpaper.mClient.asBinder() == window) {
2680 mWaitingOnWallpaper = null;
2681 mWindowMap.notifyAll();
2682 }
2683 }
2684 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002685
Dianne Hackborn75804932009-10-20 20:15:20 -07002686 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2687 String action, int x, int y, int z, Bundle extras, boolean sync) {
2688 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2689 || window == mUpperWallpaperTarget) {
2690 boolean doWait = sync;
2691 int curTokenIndex = mWallpaperTokens.size();
2692 while (curTokenIndex > 0) {
2693 curTokenIndex--;
2694 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2695 int curWallpaperIndex = token.windows.size();
2696 while (curWallpaperIndex > 0) {
2697 curWallpaperIndex--;
2698 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2699 try {
2700 wallpaper.mClient.dispatchWallpaperCommand(action,
2701 x, y, z, extras, sync);
2702 // We only want to be synchronous with one wallpaper.
2703 sync = false;
2704 } catch (RemoteException e) {
2705 }
2706 }
2707 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002708
Dianne Hackborn75804932009-10-20 20:15:20 -07002709 if (doWait) {
2710 // XXX Need to wait for result.
2711 }
2712 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002713
Dianne Hackborn75804932009-10-20 20:15:20 -07002714 return null;
2715 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002716
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002717 public int relayoutWindow(Session session, IWindow client,
2718 WindowManager.LayoutParams attrs, int requestedWidth,
2719 int requestedHeight, int viewVisibility, boolean insetsPending,
2720 Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002721 Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002722 boolean displayed = false;
2723 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002724 boolean configChanged;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002725 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002726
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002727 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002728 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002729 if (win == null) {
2730 return 0;
2731 }
2732 win.mRequestedWidth = requestedWidth;
2733 win.mRequestedHeight = requestedHeight;
2734
2735 if (attrs != null) {
2736 mPolicy.adjustWindowParamsLw(attrs);
2737 }
Romain Guy06882f82009-06-10 13:36:04 -07002738
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002739 int attrChanges = 0;
2740 int flagChanges = 0;
2741 if (attrs != null) {
2742 flagChanges = win.mAttrs.flags ^= attrs.flags;
2743 attrChanges = win.mAttrs.copyFrom(attrs);
2744 }
2745
Joe Onorato8a9b2202010-02-26 18:56:32 -08002746 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002747
2748 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
2749 win.mAlpha = attrs.alpha;
2750 }
2751
2752 final boolean scaledWindow =
2753 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2754
2755 if (scaledWindow) {
2756 // requested{Width|Height} Surface's physical size
2757 // attrs.{width|height} Size on screen
2758 win.mHScale = (attrs.width != requestedWidth) ?
2759 (attrs.width / (float)requestedWidth) : 1.0f;
2760 win.mVScale = (attrs.height != requestedHeight) ?
2761 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002762 } else {
2763 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002764 }
2765
2766 boolean imMayMove = (flagChanges&(
2767 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
2768 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002770 boolean focusMayChange = win.mViewVisibility != viewVisibility
2771 || ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
2772 || (!win.mRelayoutCalled);
Romain Guy06882f82009-06-10 13:36:04 -07002773
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002774 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2775 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002776
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002777 win.mRelayoutCalled = true;
2778 final int oldVisibility = win.mViewVisibility;
2779 win.mViewVisibility = viewVisibility;
2780 if (viewVisibility == View.VISIBLE &&
2781 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
2782 displayed = !win.isVisibleLw();
2783 if (win.mExiting) {
2784 win.mExiting = false;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07002785 if (win.mAnimation != null) {
2786 win.mAnimation.cancel();
2787 win.mAnimation = null;
2788 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002789 }
2790 if (win.mDestroying) {
2791 win.mDestroying = false;
2792 mDestroySurface.remove(win);
2793 }
2794 if (oldVisibility == View.GONE) {
2795 win.mEnterAnimationPending = true;
2796 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002797 if (displayed) {
2798 if (win.mSurface != null && !win.mDrawPending
2799 && !win.mCommitDrawPending && !mDisplayFrozen
2800 && mPolicy.isScreenOn()) {
2801 applyEnterAnimationLocked(win);
2802 }
2803 if ((win.mAttrs.flags
2804 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2805 if (DEBUG_VISIBILITY) Slog.v(TAG,
2806 "Relayout window turning screen on: " + win);
2807 win.mTurnOnScreen = true;
2808 }
2809 int diff = 0;
2810 if (win.mConfiguration != mCurConfiguration
2811 && (win.mConfiguration == null
2812 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2813 win.mConfiguration = mCurConfiguration;
2814 if (DEBUG_CONFIGURATION) {
2815 Slog.i(TAG, "Window " + win + " visible with new config: "
2816 + win.mConfiguration + " / 0x"
2817 + Integer.toHexString(diff));
2818 }
2819 outConfig.setTo(mCurConfiguration);
2820 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002821 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002822 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2823 // To change the format, we need to re-build the surface.
2824 win.destroySurfaceLocked();
2825 displayed = true;
2826 }
2827 try {
2828 Surface surface = win.createSurfaceLocked();
2829 if (surface != null) {
2830 outSurface.copyFrom(surface);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002831 win.mReportDestroySurface = false;
2832 win.mSurfacePendingDestroy = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002833 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002834 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002835 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002836 // For some reason there isn't a surface. Clear the
2837 // caller's object so they see the same state.
2838 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002839 }
2840 } catch (Exception e) {
Jeff Browne33348b2010-07-15 23:54:05 -07002841 mInputMonitor.updateInputWindowsLw();
2842
Joe Onorato8a9b2202010-02-26 18:56:32 -08002843 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002844 + client + " (" + win.mAttrs.getTitle() + ")",
2845 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002846 Binder.restoreCallingIdentity(origId);
2847 return 0;
2848 }
2849 if (displayed) {
2850 focusMayChange = true;
2851 }
2852 if (win.mAttrs.type == TYPE_INPUT_METHOD
2853 && mInputMethodWindow == null) {
2854 mInputMethodWindow = win;
2855 imMayMove = true;
2856 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002857 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2858 && win.mAppToken != null
2859 && win.mAppToken.startingWindow != null) {
2860 // Special handling of starting window over the base
2861 // window of the app: propagate lock screen flags to it,
2862 // to provide the correct semantics while starting.
2863 final int mask =
2864 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002865 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2866 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002867 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2868 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2869 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002870 } else {
2871 win.mEnterAnimationPending = false;
2872 if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002873 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002874 + ": mExiting=" + win.mExiting
2875 + " mSurfacePendingDestroy=" + win.mSurfacePendingDestroy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002876 // If we are not currently running the exit animation, we
2877 // need to see about starting one.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002878 if (!win.mExiting || win.mSurfacePendingDestroy) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002879 // Try starting an animation; if there isn't one, we
2880 // can destroy the surface right away.
2881 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2882 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2883 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2884 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002885 if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002886 applyAnimationLocked(win, transit, false)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002887 focusMayChange = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002888 win.mExiting = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002889 } else if (win.isAnimating()) {
2890 // Currently in a hide animation... turn this into
2891 // an exit.
2892 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002893 } else if (win == mWallpaperTarget) {
2894 // If the wallpaper is currently behind this
2895 // window, we need to change both of them inside
2896 // of a transaction to avoid artifacts.
2897 win.mExiting = true;
2898 win.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002899 } else {
2900 if (mInputMethodWindow == win) {
2901 mInputMethodWindow = null;
2902 }
2903 win.destroySurfaceLocked();
2904 }
2905 }
2906 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002907
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002908 if (win.mSurface == null || (win.getAttrs().flags
2909 & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
2910 || win.mSurfacePendingDestroy) {
2911 // We are being called from a local process, which
2912 // means outSurface holds its current surface. Ensure the
2913 // surface object is cleared, but we don't want it actually
2914 // destroyed at this point.
2915 win.mSurfacePendingDestroy = false;
2916 outSurface.release();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002917 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002918 } else if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002919 if (DEBUG_VISIBILITY) Slog.i(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002920 "Keeping surface, will report destroy: " + win);
2921 win.mReportDestroySurface = true;
2922 outSurface.copyFrom(win.mSurface);
2923 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002924 }
2925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002926 if (focusMayChange) {
2927 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
2928 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002929 imMayMove = false;
2930 }
2931 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2932 }
Romain Guy06882f82009-06-10 13:36:04 -07002933
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002934 // updateFocusedWindowLocked() already assigned layers so we only need to
2935 // reassign them at this point if the IM window state gets shuffled
2936 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002937
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002938 if (imMayMove) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002939 if (moveInputMethodWindowsIfNeededLocked(false) || displayed) {
2940 // Little hack here -- we -should- be able to rely on the
2941 // function to return true if the IME has moved and needs
2942 // its layer recomputed. However, if the IME was hidden
2943 // and isn't actually moved in the list, its layer may be
2944 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002945 assignLayers = true;
2946 }
2947 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002948 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002949 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002950 assignLayers = true;
2951 }
2952 }
Romain Guy06882f82009-06-10 13:36:04 -07002953
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002954 mLayoutNeeded = true;
2955 win.mGivenInsetsPending = insetsPending;
2956 if (assignLayers) {
2957 assignLayersLocked();
2958 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002959 configChanged = updateOrientationFromAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002960 performLayoutAndPlaceSurfacesLocked();
Dianne Hackborn284ac932009-08-28 10:34:25 -07002961 if (displayed && win.mIsWallpaper) {
2962 updateWallpaperOffsetLocked(win, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002963 mDisplay.getHeight(), false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002964 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002965 if (win.mAppToken != null) {
2966 win.mAppToken.updateReportedVisibilityLocked();
2967 }
2968 outFrame.set(win.mFrame);
2969 outContentInsets.set(win.mContentInsets);
2970 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002971 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002972 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002973 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002974 + ", requestedHeight=" + requestedHeight
2975 + ", viewVisibility=" + viewVisibility
2976 + "\nRelayout returning frame=" + outFrame
2977 + ", surface=" + outSurface);
2978
Joe Onorato8a9b2202010-02-26 18:56:32 -08002979 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002980 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
2981
2982 inTouchMode = mInTouchMode;
Jeff Browne33348b2010-07-15 23:54:05 -07002983
2984 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002985 }
2986
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002987 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002988 sendNewConfiguration();
2989 }
Romain Guy06882f82009-06-10 13:36:04 -07002990
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002991 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002992
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002993 return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
2994 | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
2995 }
2996
2997 public void finishDrawingWindow(Session session, IWindow client) {
2998 final long origId = Binder.clearCallingIdentity();
2999 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003000 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003001 if (win != null && win.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07003002 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
3003 adjustWallpaperWindowsLocked();
3004 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003005 mLayoutNeeded = true;
3006 performLayoutAndPlaceSurfacesLocked();
3007 }
3008 }
3009 Binder.restoreCallingIdentity(origId);
3010 }
3011
3012 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003013 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003014 + (lp != null ? lp.packageName : null)
3015 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
3016 if (lp != null && lp.windowAnimations != 0) {
3017 // If this is a system resource, don't try to load it from the
3018 // application resources. It is nice to avoid loading application
3019 // resources if we can.
3020 String packageName = lp.packageName != null ? lp.packageName : "android";
3021 int resId = lp.windowAnimations;
3022 if ((resId&0xFF000000) == 0x01000000) {
3023 packageName = "android";
3024 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003025 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003026 + packageName);
3027 return AttributeCache.instance().get(packageName, resId,
3028 com.android.internal.R.styleable.WindowAnimation);
3029 }
3030 return null;
3031 }
Romain Guy06882f82009-06-10 13:36:04 -07003032
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003033 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003034 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: params package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003035 + packageName + " resId=0x" + Integer.toHexString(resId));
3036 if (packageName != null) {
3037 if ((resId&0xFF000000) == 0x01000000) {
3038 packageName = "android";
3039 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003040 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003041 + packageName);
3042 return AttributeCache.instance().get(packageName, resId,
3043 com.android.internal.R.styleable.WindowAnimation);
3044 }
3045 return null;
3046 }
3047
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003048 private void applyEnterAnimationLocked(WindowState win) {
3049 int transit = WindowManagerPolicy.TRANSIT_SHOW;
3050 if (win.mEnterAnimationPending) {
3051 win.mEnterAnimationPending = false;
3052 transit = WindowManagerPolicy.TRANSIT_ENTER;
3053 }
3054
3055 applyAnimationLocked(win, transit, true);
3056 }
3057
3058 private boolean applyAnimationLocked(WindowState win,
3059 int transit, boolean isEntrance) {
3060 if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
3061 // If we are trying to apply an animation, but already running
3062 // an animation of the same type, then just leave that one alone.
3063 return true;
3064 }
Romain Guy06882f82009-06-10 13:36:04 -07003065
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003066 // Only apply an animation if the display isn't frozen. If it is
3067 // frozen, there is no reason to animate and it can cause strange
3068 // artifacts when we unfreeze the display if some different animation
3069 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003070 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003071 int anim = mPolicy.selectAnimationLw(win, transit);
3072 int attr = -1;
3073 Animation a = null;
3074 if (anim != 0) {
3075 a = AnimationUtils.loadAnimation(mContext, anim);
3076 } else {
3077 switch (transit) {
3078 case WindowManagerPolicy.TRANSIT_ENTER:
3079 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
3080 break;
3081 case WindowManagerPolicy.TRANSIT_EXIT:
3082 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
3083 break;
3084 case WindowManagerPolicy.TRANSIT_SHOW:
3085 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
3086 break;
3087 case WindowManagerPolicy.TRANSIT_HIDE:
3088 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
3089 break;
3090 }
3091 if (attr >= 0) {
3092 a = loadAnimation(win.mAttrs, attr);
3093 }
3094 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003095 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: win=" + win
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003096 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
3097 + " mAnimation=" + win.mAnimation
3098 + " isEntrance=" + isEntrance);
3099 if (a != null) {
3100 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003101 RuntimeException e = null;
3102 if (!HIDE_STACK_CRAWLS) {
3103 e = new RuntimeException();
3104 e.fillInStackTrace();
3105 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003106 Slog.v(TAG, "Loaded animation " + a + " for " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003107 }
3108 win.setAnimation(a);
3109 win.mAnimationIsEntrance = isEntrance;
3110 }
3111 } else {
3112 win.clearAnimation();
3113 }
3114
3115 return win.mAnimation != null;
3116 }
3117
3118 private Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
3119 int anim = 0;
3120 Context context = mContext;
3121 if (animAttr >= 0) {
3122 AttributeCache.Entry ent = getCachedAnimations(lp);
3123 if (ent != null) {
3124 context = ent.context;
3125 anim = ent.array.getResourceId(animAttr, 0);
3126 }
3127 }
3128 if (anim != 0) {
3129 return AnimationUtils.loadAnimation(context, anim);
3130 }
3131 return null;
3132 }
Romain Guy06882f82009-06-10 13:36:04 -07003133
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003134 private Animation loadAnimation(String packageName, int resId) {
3135 int anim = 0;
3136 Context context = mContext;
3137 if (resId >= 0) {
3138 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
3139 if (ent != null) {
3140 context = ent.context;
3141 anim = resId;
3142 }
3143 }
3144 if (anim != 0) {
3145 return AnimationUtils.loadAnimation(context, anim);
3146 }
3147 return null;
3148 }
3149
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003150 private boolean applyAnimationLocked(AppWindowToken wtoken,
3151 WindowManager.LayoutParams lp, int transit, boolean enter) {
3152 // Only apply an animation if the display isn't frozen. If it is
3153 // frozen, there is no reason to animate and it can cause strange
3154 // artifacts when we unfreeze the display if some different animation
3155 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003156 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003157 Animation a;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07003158 if (lp != null && (lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003159 a = new FadeInOutAnimation(enter);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003160 if (DEBUG_ANIM) Slog.v(TAG,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003161 "applying FadeInOutAnimation for a window in compatibility mode");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003162 } else if (mNextAppTransitionPackage != null) {
3163 a = loadAnimation(mNextAppTransitionPackage, enter ?
3164 mNextAppTransitionEnter : mNextAppTransitionExit);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003165 } else {
3166 int animAttr = 0;
3167 switch (transit) {
3168 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3169 animAttr = enter
3170 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
3171 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
3172 break;
3173 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3174 animAttr = enter
3175 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
3176 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
3177 break;
3178 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
3179 animAttr = enter
3180 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
3181 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
3182 break;
3183 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
3184 animAttr = enter
3185 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
3186 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
3187 break;
3188 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
3189 animAttr = enter
3190 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
3191 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
3192 break;
3193 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
3194 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07003195 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003196 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
3197 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003198 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003199 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003200 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
3201 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003202 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003203 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003204 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003205 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
3206 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
3207 break;
3208 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
3209 animAttr = enter
3210 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
3211 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
3212 break;
3213 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
3214 animAttr = enter
3215 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
3216 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003217 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003218 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003219 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003220 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003221 + " anim=" + a
3222 + " animAttr=0x" + Integer.toHexString(animAttr)
3223 + " transit=" + transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003224 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003225 if (a != null) {
3226 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003227 RuntimeException e = null;
3228 if (!HIDE_STACK_CRAWLS) {
3229 e = new RuntimeException();
3230 e.fillInStackTrace();
3231 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003232 Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003233 }
3234 wtoken.setAnimation(a);
3235 }
3236 } else {
3237 wtoken.clearAnimation();
3238 }
3239
3240 return wtoken.animation != null;
3241 }
3242
3243 // -------------------------------------------------------------
3244 // Application Window Tokens
3245 // -------------------------------------------------------------
3246
3247 public void validateAppTokens(List tokens) {
3248 int v = tokens.size()-1;
3249 int m = mAppTokens.size()-1;
3250 while (v >= 0 && m >= 0) {
3251 AppWindowToken wtoken = mAppTokens.get(m);
3252 if (wtoken.removed) {
3253 m--;
3254 continue;
3255 }
3256 if (tokens.get(v) != wtoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003257 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003258 + " @ " + v + ", internal is " + wtoken.token + " @ " + m);
3259 }
3260 v--;
3261 m--;
3262 }
3263 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003264 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003265 v--;
3266 }
3267 while (m >= 0) {
3268 AppWindowToken wtoken = mAppTokens.get(m);
3269 if (!wtoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003270 Slog.w(TAG, "Invalid internal token: " + wtoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003271 }
3272 m--;
3273 }
3274 }
3275
3276 boolean checkCallingPermission(String permission, String func) {
3277 // Quick check: if the calling permission is me, it's all okay.
3278 if (Binder.getCallingPid() == Process.myPid()) {
3279 return true;
3280 }
Romain Guy06882f82009-06-10 13:36:04 -07003281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003282 if (mContext.checkCallingPermission(permission)
3283 == PackageManager.PERMISSION_GRANTED) {
3284 return true;
3285 }
3286 String msg = "Permission Denial: " + func + " from pid="
3287 + Binder.getCallingPid()
3288 + ", uid=" + Binder.getCallingUid()
3289 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003290 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003291 return false;
3292 }
Romain Guy06882f82009-06-10 13:36:04 -07003293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003294 AppWindowToken findAppWindowToken(IBinder token) {
3295 WindowToken wtoken = mTokenMap.get(token);
3296 if (wtoken == null) {
3297 return null;
3298 }
3299 return wtoken.appWindowToken;
3300 }
Romain Guy06882f82009-06-10 13:36:04 -07003301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003302 public void addWindowToken(IBinder token, int type) {
3303 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3304 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003305 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003306 }
Romain Guy06882f82009-06-10 13:36:04 -07003307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003308 synchronized(mWindowMap) {
3309 WindowToken wtoken = mTokenMap.get(token);
3310 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003311 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003312 return;
3313 }
3314 wtoken = new WindowToken(token, type, true);
3315 mTokenMap.put(token, wtoken);
3316 mTokenList.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003317 if (type == TYPE_WALLPAPER) {
3318 mWallpaperTokens.add(wtoken);
3319 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003320 }
3321 }
Romain Guy06882f82009-06-10 13:36:04 -07003322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003323 public void removeWindowToken(IBinder token) {
3324 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3325 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003326 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003327 }
3328
3329 final long origId = Binder.clearCallingIdentity();
3330 synchronized(mWindowMap) {
3331 WindowToken wtoken = mTokenMap.remove(token);
3332 mTokenList.remove(wtoken);
3333 if (wtoken != null) {
3334 boolean delayed = false;
3335 if (!wtoken.hidden) {
3336 wtoken.hidden = true;
Romain Guy06882f82009-06-10 13:36:04 -07003337
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003338 final int N = wtoken.windows.size();
3339 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003340
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003341 for (int i=0; i<N; i++) {
3342 WindowState win = wtoken.windows.get(i);
3343
3344 if (win.isAnimating()) {
3345 delayed = true;
3346 }
Romain Guy06882f82009-06-10 13:36:04 -07003347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003348 if (win.isVisibleNow()) {
3349 applyAnimationLocked(win,
3350 WindowManagerPolicy.TRANSIT_EXIT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003351 changed = true;
3352 }
3353 }
3354
3355 if (changed) {
3356 mLayoutNeeded = true;
3357 performLayoutAndPlaceSurfacesLocked();
3358 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3359 }
Romain Guy06882f82009-06-10 13:36:04 -07003360
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003361 if (delayed) {
3362 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003363 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3364 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003365 }
3366 }
Romain Guy06882f82009-06-10 13:36:04 -07003367
Jeff Brownc5ed5912010-07-14 18:48:53 -07003368 mInputMonitor.updateInputWindowsLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003369 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003370 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003371 }
3372 }
3373 Binder.restoreCallingIdentity(origId);
3374 }
3375
3376 public void addAppToken(int addPos, IApplicationToken token,
3377 int groupId, int requestedOrientation, boolean fullscreen) {
3378 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3379 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003380 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003381 }
Jeff Brown349703e2010-06-22 01:27:15 -07003382
3383 // Get the dispatching timeout here while we are not holding any locks so that it
3384 // can be cached by the AppWindowToken. The timeout value is used later by the
3385 // input dispatcher in code that does hold locks. If we did not cache the value
3386 // here we would run the chance of introducing a deadlock between the window manager
3387 // (which holds locks while updating the input dispatcher state) and the activity manager
3388 // (which holds locks while querying the application token).
3389 long inputDispatchingTimeoutNanos;
3390 try {
3391 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3392 } catch (RemoteException ex) {
3393 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3394 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3395 }
Romain Guy06882f82009-06-10 13:36:04 -07003396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003397 synchronized(mWindowMap) {
3398 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3399 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003400 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003401 return;
3402 }
3403 wtoken = new AppWindowToken(token);
Jeff Brown349703e2010-06-22 01:27:15 -07003404 wtoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003405 wtoken.groupId = groupId;
3406 wtoken.appFullscreen = fullscreen;
3407 wtoken.requestedOrientation = requestedOrientation;
3408 mAppTokens.add(addPos, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08003409 if (localLOGV) Slog.v(TAG, "Adding new app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003410 mTokenMap.put(token.asBinder(), wtoken);
3411 mTokenList.add(wtoken);
Romain Guy06882f82009-06-10 13:36:04 -07003412
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003413 // Application tokens start out hidden.
3414 wtoken.hidden = true;
3415 wtoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003416
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003417 //dump();
3418 }
3419 }
Romain Guy06882f82009-06-10 13:36:04 -07003420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003421 public void setAppGroupId(IBinder token, int groupId) {
3422 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3423 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003424 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003425 }
3426
3427 synchronized(mWindowMap) {
3428 AppWindowToken wtoken = findAppWindowToken(token);
3429 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003430 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003431 return;
3432 }
3433 wtoken.groupId = groupId;
3434 }
3435 }
Romain Guy06882f82009-06-10 13:36:04 -07003436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003437 public int getOrientationFromWindowsLocked() {
3438 int pos = mWindows.size() - 1;
3439 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07003440 WindowState wtoken = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003441 pos--;
3442 if (wtoken.mAppToken != null) {
3443 // We hit an application window. so the orientation will be determined by the
3444 // app window. No point in continuing further.
3445 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3446 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003447 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003448 continue;
3449 }
3450 int req = wtoken.mAttrs.screenOrientation;
3451 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3452 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3453 continue;
3454 } else {
3455 return req;
3456 }
3457 }
3458 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3459 }
Romain Guy06882f82009-06-10 13:36:04 -07003460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003461 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003462 int pos = mAppTokens.size() - 1;
3463 int curGroup = 0;
3464 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3465 boolean findingBehind = false;
3466 boolean haveGroup = false;
3467 boolean lastFullscreen = false;
3468 while (pos >= 0) {
3469 AppWindowToken wtoken = mAppTokens.get(pos);
3470 pos--;
3471 // if we're about to tear down this window and not seek for
3472 // the behind activity, don't use it for orientation
3473 if (!findingBehind
3474 && (!wtoken.hidden && wtoken.hiddenRequested)) {
3475 continue;
3476 }
3477
3478 if (!haveGroup) {
3479 // We ignore any hidden applications on the top.
3480 if (wtoken.hiddenRequested || wtoken.willBeHidden) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003481 continue;
3482 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003483 haveGroup = true;
3484 curGroup = wtoken.groupId;
3485 lastOrientation = wtoken.requestedOrientation;
3486 } else if (curGroup != wtoken.groupId) {
3487 // If we have hit a new application group, and the bottom
3488 // of the previous group didn't explicitly say to use
3489 // the orientation behind it, and the last app was
3490 // full screen, then we'll stick with the
3491 // user's orientation.
3492 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3493 && lastFullscreen) {
3494 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003495 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003496 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003497 int or = wtoken.requestedOrientation;
3498 // If this application is fullscreen, and didn't explicitly say
3499 // to use the orientation behind it, then just take whatever
3500 // orientation it has and ignores whatever is under it.
3501 lastFullscreen = wtoken.appFullscreen;
3502 if (lastFullscreen
3503 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3504 return or;
3505 }
3506 // If this application has requested an explicit orientation,
3507 // then use it.
Dianne Hackborne5439f22010-10-02 16:53:50 -07003508 if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
3509 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003510 return or;
3511 }
3512 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3513 }
3514 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003515 }
Romain Guy06882f82009-06-10 13:36:04 -07003516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003517 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003518 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003519 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3520 "updateOrientationFromAppTokens()")) {
3521 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3522 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003523
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003524 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003525 long ident = Binder.clearCallingIdentity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003526
3527 synchronized(mWindowMap) {
3528 if (updateOrientationFromAppTokensLocked()) {
3529 if (freezeThisOneIfNeeded != null) {
3530 AppWindowToken wtoken = findAppWindowToken(
3531 freezeThisOneIfNeeded);
3532 if (wtoken != null) {
3533 startAppFreezingScreenLocked(wtoken,
3534 ActivityInfo.CONFIG_ORIENTATION);
3535 }
3536 }
3537 config = computeNewConfigurationLocked();
3538
3539 } else if (currentConfig != null) {
3540 // No obvious action we need to take, but if our current
Casey Burkhardt0920ba52010-08-03 12:04:19 -07003541 // state mismatches the activity manager's, update it,
3542 // disregarding font scale, which should remain set to
3543 // the value of the previous configuration.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003544 mTempConfiguration.setToDefaults();
Casey Burkhardt0920ba52010-08-03 12:04:19 -07003545 mTempConfiguration.fontScale = currentConfig.fontScale;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003546 if (computeNewConfigurationLocked(mTempConfiguration)) {
3547 if (currentConfig.diff(mTempConfiguration) != 0) {
3548 mWaitingForConfig = true;
3549 mLayoutNeeded = true;
3550 startFreezingDisplayLocked();
3551 config = new Configuration(mTempConfiguration);
3552 }
3553 }
3554 }
3555 }
3556
Dianne Hackborncfaef692009-06-15 14:24:44 -07003557 Binder.restoreCallingIdentity(ident);
3558 return config;
3559 }
3560
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003561 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003562 * Determine the new desired orientation of the display, returning
3563 * a non-null new Configuration if it has changed from the current
3564 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3565 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3566 * SCREEN. This will typically be done for you if you call
3567 * sendNewConfiguration().
3568 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003569 * The orientation is computed from non-application windows first. If none of
3570 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003571 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003572 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3573 * android.os.IBinder)
3574 */
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003575 boolean updateOrientationFromAppTokensLocked() {
Christopher Tateb696aee2010-04-02 19:08:30 -07003576 if (mDisplayFrozen) {
3577 // If the display is frozen, some activities may be in the middle
3578 // of restarting, and thus have removed their old window. If the
3579 // window has the flag to hide the lock screen, then the lock screen
3580 // can re-appear and inflict its own orientation on us. Keep the
3581 // orientation stable until this all settles down.
3582 return false;
3583 }
3584
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003585 boolean changed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003586 long ident = Binder.clearCallingIdentity();
3587 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003588 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003589
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003590 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003591 mForcedAppOrientation = req;
3592 //send a message to Policy indicating orientation change to take
3593 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003594 mPolicy.setCurrentOrientationLw(req);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003595 if (setRotationUncheckedLocked(WindowManagerPolicy.USE_LAST_ROTATION,
3596 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE)) {
3597 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003598 }
3599 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003600
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003601 return changed;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003602 } finally {
3603 Binder.restoreCallingIdentity(ident);
3604 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003605 }
Romain Guy06882f82009-06-10 13:36:04 -07003606
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003607 int computeForcedAppOrientationLocked() {
3608 int req = getOrientationFromWindowsLocked();
3609 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3610 req = getOrientationFromAppTokensLocked();
3611 }
3612 return req;
3613 }
Romain Guy06882f82009-06-10 13:36:04 -07003614
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003615 public void setNewConfiguration(Configuration config) {
3616 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3617 "setNewConfiguration()")) {
3618 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3619 }
3620
3621 synchronized(mWindowMap) {
3622 mCurConfiguration = new Configuration(config);
3623 mWaitingForConfig = false;
3624 performLayoutAndPlaceSurfacesLocked();
3625 }
3626 }
3627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003628 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3629 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3630 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003631 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003632 }
Romain Guy06882f82009-06-10 13:36:04 -07003633
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003634 synchronized(mWindowMap) {
3635 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3636 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003637 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003638 return;
3639 }
Romain Guy06882f82009-06-10 13:36:04 -07003640
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003641 wtoken.requestedOrientation = requestedOrientation;
3642 }
3643 }
Romain Guy06882f82009-06-10 13:36:04 -07003644
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003645 public int getAppOrientation(IApplicationToken token) {
3646 synchronized(mWindowMap) {
3647 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3648 if (wtoken == null) {
3649 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3650 }
Romain Guy06882f82009-06-10 13:36:04 -07003651
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003652 return wtoken.requestedOrientation;
3653 }
3654 }
Romain Guy06882f82009-06-10 13:36:04 -07003655
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003656 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3657 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3658 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003659 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003660 }
3661
3662 synchronized(mWindowMap) {
3663 boolean changed = false;
3664 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003665 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003666 changed = mFocusedApp != null;
3667 mFocusedApp = null;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003668 if (changed) {
3669 mInputMonitor.setFocusedAppLw(null);
Jeff Brown349703e2010-06-22 01:27:15 -07003670 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003671 } else {
3672 AppWindowToken newFocus = findAppWindowToken(token);
3673 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003674 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003675 return;
3676 }
3677 changed = mFocusedApp != newFocus;
3678 mFocusedApp = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003679 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003680 if (changed) {
3681 mInputMonitor.setFocusedAppLw(newFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07003682 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003683 }
3684
3685 if (moveFocusNow && changed) {
3686 final long origId = Binder.clearCallingIdentity();
3687 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
3688 Binder.restoreCallingIdentity(origId);
3689 }
3690 }
3691 }
3692
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003693 public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003694 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3695 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003696 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003697 }
Romain Guy06882f82009-06-10 13:36:04 -07003698
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003699 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003700 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003701 TAG, "Prepare app transition: transit=" + transit
3702 + " mNextAppTransition=" + mNextAppTransition);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003703 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003704 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
3705 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003706 mNextAppTransition = transit;
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003707 } else if (!alwaysKeepCurrent) {
3708 if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
3709 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
3710 // Opening a new task always supersedes a close for the anim.
3711 mNextAppTransition = transit;
3712 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
3713 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
3714 // Opening a new activity always supersedes a close for the anim.
3715 mNextAppTransition = transit;
3716 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003717 }
3718 mAppTransitionReady = false;
3719 mAppTransitionTimeout = false;
3720 mStartingIconInTransition = false;
3721 mSkipAppTransitionAnimation = false;
3722 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
3723 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
3724 5000);
3725 }
3726 }
3727 }
3728
3729 public int getPendingAppTransition() {
3730 return mNextAppTransition;
3731 }
Romain Guy06882f82009-06-10 13:36:04 -07003732
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003733 public void overridePendingAppTransition(String packageName,
3734 int enterAnim, int exitAnim) {
Dianne Hackborn8b571a82009-09-25 16:09:43 -07003735 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003736 mNextAppTransitionPackage = packageName;
3737 mNextAppTransitionEnter = enterAnim;
3738 mNextAppTransitionExit = exitAnim;
3739 }
3740 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003741
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003742 public void executeAppTransition() {
3743 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3744 "executeAppTransition()")) {
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) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003749 if (DEBUG_APP_TRANSITIONS) {
3750 RuntimeException e = new RuntimeException("here");
3751 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003752 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003753 + mNextAppTransition, e);
3754 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003755 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003756 mAppTransitionReady = true;
3757 final long origId = Binder.clearCallingIdentity();
3758 performLayoutAndPlaceSurfacesLocked();
3759 Binder.restoreCallingIdentity(origId);
3760 }
3761 }
3762 }
3763
3764 public void setAppStartingWindow(IBinder token, String pkg,
3765 int theme, CharSequence nonLocalizedLabel, int labelRes, int icon,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003766 int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003767 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3768 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003769 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003770 }
3771
3772 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003773 if (DEBUG_STARTING_WINDOW) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003774 TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
3775 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003776
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003777 AppWindowToken wtoken = findAppWindowToken(token);
3778 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003779 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003780 return;
3781 }
3782
3783 // If the display is frozen, we won't do anything until the
3784 // actual window is displayed so there is no reason to put in
3785 // the starting window.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003786 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003787 return;
3788 }
Romain Guy06882f82009-06-10 13:36:04 -07003789
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003790 if (wtoken.startingData != null) {
3791 return;
3792 }
Romain Guy06882f82009-06-10 13:36:04 -07003793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003794 if (transferFrom != null) {
3795 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3796 if (ttoken != null) {
3797 WindowState startingWindow = ttoken.startingWindow;
3798 if (startingWindow != null) {
3799 if (mStartingIconInTransition) {
3800 // In this case, the starting icon has already
3801 // been displayed, so start letting windows get
3802 // shown immediately without any more transitions.
3803 mSkipAppTransitionAnimation = true;
3804 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003805 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003806 "Moving existing starting from " + ttoken
3807 + " to " + wtoken);
3808 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003809
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003810 // Transfer the starting window over to the new
3811 // token.
3812 wtoken.startingData = ttoken.startingData;
3813 wtoken.startingView = ttoken.startingView;
3814 wtoken.startingWindow = startingWindow;
3815 ttoken.startingData = null;
3816 ttoken.startingView = null;
3817 ttoken.startingWindow = null;
3818 ttoken.startingMoved = true;
3819 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003820 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003821 startingWindow.mAppToken = wtoken;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003822 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003823 "Removing starting window: " + startingWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003824 mWindows.remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07003825 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003826 ttoken.windows.remove(startingWindow);
3827 ttoken.allAppWindows.remove(startingWindow);
3828 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003830 // Propagate other interesting state between the
3831 // tokens. If the old token is displayed, we should
3832 // immediately force the new one to be displayed. If
3833 // it is animating, we need to move that animation to
3834 // the new one.
3835 if (ttoken.allDrawn) {
3836 wtoken.allDrawn = true;
3837 }
3838 if (ttoken.firstWindowDrawn) {
3839 wtoken.firstWindowDrawn = true;
3840 }
3841 if (!ttoken.hidden) {
3842 wtoken.hidden = false;
3843 wtoken.hiddenRequested = false;
3844 wtoken.willBeHidden = false;
3845 }
3846 if (wtoken.clientHidden != ttoken.clientHidden) {
3847 wtoken.clientHidden = ttoken.clientHidden;
3848 wtoken.sendAppVisibilityToClients();
3849 }
3850 if (ttoken.animation != null) {
3851 wtoken.animation = ttoken.animation;
3852 wtoken.animating = ttoken.animating;
3853 wtoken.animLayerAdjustment = ttoken.animLayerAdjustment;
3854 ttoken.animation = null;
3855 ttoken.animLayerAdjustment = 0;
3856 wtoken.updateLayers();
3857 ttoken.updateLayers();
3858 }
Romain Guy06882f82009-06-10 13:36:04 -07003859
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003860 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003861 mLayoutNeeded = true;
3862 performLayoutAndPlaceSurfacesLocked();
3863 Binder.restoreCallingIdentity(origId);
3864 return;
3865 } else if (ttoken.startingData != null) {
3866 // The previous app was getting ready to show a
3867 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08003868 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003869 "Moving pending starting from " + ttoken
3870 + " to " + wtoken);
3871 wtoken.startingData = ttoken.startingData;
3872 ttoken.startingData = null;
3873 ttoken.startingMoved = true;
3874 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3875 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3876 // want to process the message ASAP, before any other queued
3877 // messages.
3878 mH.sendMessageAtFrontOfQueue(m);
3879 return;
3880 }
3881 }
3882 }
3883
3884 // There is no existing starting window, and the caller doesn't
3885 // want us to create one, so that's it!
3886 if (!createIfNeeded) {
3887 return;
3888 }
Romain Guy06882f82009-06-10 13:36:04 -07003889
Dianne Hackborn284ac932009-08-28 10:34:25 -07003890 // If this is a translucent or wallpaper window, then don't
3891 // show a starting window -- the current effect (a full-screen
3892 // opaque starting window that fades away to the real contents
3893 // when it is ready) does not work for this.
3894 if (theme != 0) {
3895 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
3896 com.android.internal.R.styleable.Window);
3897 if (ent.array.getBoolean(
3898 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
3899 return;
3900 }
3901 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07003902 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
3903 return;
3904 }
3905 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07003906 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
3907 return;
3908 }
3909 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003910
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003911 mStartingIconInTransition = true;
3912 wtoken.startingData = new StartingData(
3913 pkg, theme, nonLocalizedLabel,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003914 labelRes, icon, windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003915 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3916 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3917 // want to process the message ASAP, before any other queued
3918 // messages.
3919 mH.sendMessageAtFrontOfQueue(m);
3920 }
3921 }
3922
3923 public void setAppWillBeHidden(IBinder token) {
3924 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3925 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003926 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003927 }
3928
3929 AppWindowToken wtoken;
3930
3931 synchronized(mWindowMap) {
3932 wtoken = findAppWindowToken(token);
3933 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003934 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 -08003935 return;
3936 }
3937 wtoken.willBeHidden = true;
3938 }
3939 }
Romain Guy06882f82009-06-10 13:36:04 -07003940
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003941 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
3942 boolean visible, int transit, boolean performLayout) {
3943 boolean delayed = false;
3944
3945 if (wtoken.clientHidden == visible) {
3946 wtoken.clientHidden = !visible;
3947 wtoken.sendAppVisibilityToClients();
3948 }
Romain Guy06882f82009-06-10 13:36:04 -07003949
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003950 wtoken.willBeHidden = false;
3951 if (wtoken.hidden == visible) {
3952 final int N = wtoken.allAppWindows.size();
3953 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003954 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003955 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
3956 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07003957
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003958 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07003959
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003960 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003961 if (wtoken.animation == sDummyAnimation) {
3962 wtoken.animation = null;
3963 }
3964 applyAnimationLocked(wtoken, lp, transit, visible);
3965 changed = true;
3966 if (wtoken.animation != null) {
3967 delayed = runningAppAnimation = true;
3968 }
3969 }
Romain Guy06882f82009-06-10 13:36:04 -07003970
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003971 for (int i=0; i<N; i++) {
3972 WindowState win = wtoken.allAppWindows.get(i);
3973 if (win == wtoken.startingWindow) {
3974 continue;
3975 }
3976
3977 if (win.isAnimating()) {
3978 delayed = true;
3979 }
Romain Guy06882f82009-06-10 13:36:04 -07003980
Joe Onorato8a9b2202010-02-26 18:56:32 -08003981 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003982 //win.dump(" ");
3983 if (visible) {
3984 if (!win.isVisibleNow()) {
3985 if (!runningAppAnimation) {
3986 applyAnimationLocked(win,
3987 WindowManagerPolicy.TRANSIT_ENTER, true);
3988 }
3989 changed = true;
3990 }
3991 } else if (win.isVisibleNow()) {
3992 if (!runningAppAnimation) {
3993 applyAnimationLocked(win,
3994 WindowManagerPolicy.TRANSIT_EXIT, false);
3995 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003996 changed = true;
3997 }
3998 }
3999
4000 wtoken.hidden = wtoken.hiddenRequested = !visible;
4001 if (!visible) {
4002 unsetAppFreezingScreenLocked(wtoken, true, true);
4003 } else {
4004 // If we are being set visible, and the starting window is
4005 // not yet displayed, then make sure it doesn't get displayed.
4006 WindowState swin = wtoken.startingWindow;
4007 if (swin != null && (swin.mDrawPending
4008 || swin.mCommitDrawPending)) {
4009 swin.mPolicyVisibility = false;
4010 swin.mPolicyVisibilityAfterAnim = false;
4011 }
4012 }
Romain Guy06882f82009-06-10 13:36:04 -07004013
Joe Onorato8a9b2202010-02-26 18:56:32 -08004014 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004015 + ": hidden=" + wtoken.hidden + " hiddenRequested="
4016 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07004017
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004018 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004019 mLayoutNeeded = true;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004020 if (performLayout) {
4021 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
4022 performLayoutAndPlaceSurfacesLocked();
Jeff Browne33348b2010-07-15 23:54:05 -07004023 } else {
4024 mInputMonitor.updateInputWindowsLw();
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004025 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004026 }
4027 }
4028
4029 if (wtoken.animation != null) {
4030 delayed = true;
4031 }
Romain Guy06882f82009-06-10 13:36:04 -07004032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004033 return delayed;
4034 }
4035
4036 public void setAppVisibility(IBinder token, boolean visible) {
4037 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4038 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004039 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004040 }
4041
4042 AppWindowToken wtoken;
4043
4044 synchronized(mWindowMap) {
4045 wtoken = findAppWindowToken(token);
4046 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004047 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004048 return;
4049 }
4050
4051 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004052 RuntimeException e = null;
4053 if (!HIDE_STACK_CRAWLS) {
4054 e = new RuntimeException();
4055 e.fillInStackTrace();
4056 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004057 Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004058 + "): mNextAppTransition=" + mNextAppTransition
4059 + " hidden=" + wtoken.hidden
4060 + " hiddenRequested=" + wtoken.hiddenRequested, e);
4061 }
Romain Guy06882f82009-06-10 13:36:04 -07004062
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004063 // If we are preparing an app transition, then delay changing
4064 // the visibility of this token until we execute that transition.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08004065 if (!mDisplayFrozen && mPolicy.isScreenOn()
4066 && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004067 // Already in requested state, don't do anything more.
4068 if (wtoken.hiddenRequested != visible) {
4069 return;
4070 }
4071 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07004072
Joe Onorato8a9b2202010-02-26 18:56:32 -08004073 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004074 TAG, "Setting dummy animation on: " + wtoken);
4075 wtoken.setDummyAnimation();
4076 mOpeningApps.remove(wtoken);
4077 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004078 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004079 wtoken.inPendingTransaction = true;
4080 if (visible) {
4081 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004082 wtoken.startingDisplayed = false;
4083 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004084
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004085 // If the token is currently hidden (should be the
4086 // common case), then we need to set up to wait for
4087 // its windows to be ready.
4088 if (wtoken.hidden) {
4089 wtoken.allDrawn = false;
4090 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004091
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004092 if (wtoken.clientHidden) {
4093 // In the case where we are making an app visible
4094 // but holding off for a transition, we still need
4095 // to tell the client to make its windows visible so
4096 // they get drawn. Otherwise, we will wait on
4097 // performing the transition until all windows have
4098 // been drawn, they never will be, and we are sad.
4099 wtoken.clientHidden = false;
4100 wtoken.sendAppVisibilityToClients();
4101 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004102 }
4103 } else {
4104 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004105
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004106 // If the token is currently visible (should be the
4107 // common case), then set up to wait for it to be hidden.
4108 if (!wtoken.hidden) {
4109 wtoken.waitingToHide = true;
4110 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004111 }
4112 return;
4113 }
Romain Guy06882f82009-06-10 13:36:04 -07004114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004115 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004116 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004117 wtoken.updateReportedVisibilityLocked();
4118 Binder.restoreCallingIdentity(origId);
4119 }
4120 }
4121
4122 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
4123 boolean unfreezeSurfaceNow, boolean force) {
4124 if (wtoken.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004125 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004126 + " force=" + force);
4127 final int N = wtoken.allAppWindows.size();
4128 boolean unfrozeWindows = false;
4129 for (int i=0; i<N; i++) {
4130 WindowState w = wtoken.allAppWindows.get(i);
4131 if (w.mAppFreezing) {
4132 w.mAppFreezing = false;
4133 if (w.mSurface != null && !w.mOrientationChanging) {
4134 w.mOrientationChanging = true;
4135 }
4136 unfrozeWindows = true;
4137 }
4138 }
4139 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004140 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004141 wtoken.freezingScreen = false;
4142 mAppsFreezingScreen--;
4143 }
4144 if (unfreezeSurfaceNow) {
4145 if (unfrozeWindows) {
4146 mLayoutNeeded = true;
4147 performLayoutAndPlaceSurfacesLocked();
4148 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004149 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004150 }
4151 }
4152 }
Romain Guy06882f82009-06-10 13:36:04 -07004153
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004154 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
4155 int configChanges) {
4156 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004157 RuntimeException e = null;
4158 if (!HIDE_STACK_CRAWLS) {
4159 e = new RuntimeException();
4160 e.fillInStackTrace();
4161 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004162 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004163 + ": hidden=" + wtoken.hidden + " freezing="
4164 + wtoken.freezingScreen, e);
4165 }
4166 if (!wtoken.hiddenRequested) {
4167 if (!wtoken.freezingScreen) {
4168 wtoken.freezingScreen = true;
4169 mAppsFreezingScreen++;
4170 if (mAppsFreezingScreen == 1) {
4171 startFreezingDisplayLocked();
4172 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
4173 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
4174 5000);
4175 }
4176 }
4177 final int N = wtoken.allAppWindows.size();
4178 for (int i=0; i<N; i++) {
4179 WindowState w = wtoken.allAppWindows.get(i);
4180 w.mAppFreezing = true;
4181 }
4182 }
4183 }
Romain Guy06882f82009-06-10 13:36:04 -07004184
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004185 public void startAppFreezingScreen(IBinder token, int configChanges) {
4186 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4187 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004188 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004189 }
4190
4191 synchronized(mWindowMap) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08004192 if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOn()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004193 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004194 return;
4195 }
Romain Guy06882f82009-06-10 13:36:04 -07004196
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004197 AppWindowToken wtoken = findAppWindowToken(token);
4198 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004199 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004200 return;
4201 }
4202 final long origId = Binder.clearCallingIdentity();
4203 startAppFreezingScreenLocked(wtoken, configChanges);
4204 Binder.restoreCallingIdentity(origId);
4205 }
4206 }
Romain Guy06882f82009-06-10 13:36:04 -07004207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004208 public void stopAppFreezingScreen(IBinder token, boolean force) {
4209 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4210 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004211 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004212 }
4213
4214 synchronized(mWindowMap) {
4215 AppWindowToken wtoken = findAppWindowToken(token);
4216 if (wtoken == null || wtoken.appToken == null) {
4217 return;
4218 }
4219 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004220 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004221 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.freezingScreen);
4222 unsetAppFreezingScreenLocked(wtoken, true, force);
4223 Binder.restoreCallingIdentity(origId);
4224 }
4225 }
Romain Guy06882f82009-06-10 13:36:04 -07004226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004227 public void removeAppToken(IBinder token) {
4228 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4229 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004230 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004231 }
4232
4233 AppWindowToken wtoken = null;
4234 AppWindowToken startingToken = null;
4235 boolean delayed = false;
4236
4237 final long origId = Binder.clearCallingIdentity();
4238 synchronized(mWindowMap) {
4239 WindowToken basewtoken = mTokenMap.remove(token);
4240 mTokenList.remove(basewtoken);
4241 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004242 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004243 delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004244 wtoken.inPendingTransaction = false;
4245 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004246 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004247 if (mClosingApps.contains(wtoken)) {
4248 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004249 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004250 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004251 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004252 delayed = true;
4253 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004254 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004255 TAG, "Removing app " + wtoken + " delayed=" + delayed
4256 + " animation=" + wtoken.animation
4257 + " animating=" + wtoken.animating);
4258 if (delayed) {
4259 // set the token aside because it has an active animation to be finished
4260 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004261 } else {
4262 // Make sure there is no animation running on this token,
4263 // so any windows associated with it will be removed as
4264 // soon as their animations are complete
4265 wtoken.animation = null;
4266 wtoken.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004267 }
4268 mAppTokens.remove(wtoken);
4269 wtoken.removed = true;
4270 if (wtoken.startingData != null) {
4271 startingToken = wtoken;
4272 }
4273 unsetAppFreezingScreenLocked(wtoken, true, true);
4274 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004275 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004276 mFocusedApp = null;
4277 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004278 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004279 }
4280 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004281 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004282 }
Romain Guy06882f82009-06-10 13:36:04 -07004283
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004284 if (!delayed && wtoken != null) {
4285 wtoken.updateReportedVisibilityLocked();
4286 }
4287 }
4288 Binder.restoreCallingIdentity(origId);
4289
4290 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004291 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004292 + startingToken + ": app token removed");
4293 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
4294 mH.sendMessage(m);
4295 }
4296 }
4297
4298 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
4299 final int NW = token.windows.size();
4300 for (int i=0; i<NW; i++) {
4301 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004302 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004303 mWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004304 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004305 int j = win.mChildWindows.size();
4306 while (j > 0) {
4307 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004308 WindowState cwin = win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004309 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004310 "Tmp removing child window " + cwin);
4311 mWindows.remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004312 }
4313 }
4314 return NW > 0;
4315 }
4316
4317 void dumpAppTokensLocked() {
4318 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004319 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004320 }
4321 }
Romain Guy06882f82009-06-10 13:36:04 -07004322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004323 void dumpWindowsLocked() {
4324 for (int i=mWindows.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004325 Slog.v(TAG, " #" + i + ": " + mWindows.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004326 }
4327 }
Romain Guy06882f82009-06-10 13:36:04 -07004328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004329 private int findWindowOffsetLocked(int tokenPos) {
4330 final int NW = mWindows.size();
4331
4332 if (tokenPos >= mAppTokens.size()) {
4333 int i = NW;
4334 while (i > 0) {
4335 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07004336 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004337 if (win.getAppToken() != null) {
4338 return i+1;
4339 }
4340 }
4341 }
4342
4343 while (tokenPos > 0) {
4344 // Find the first app token below the new position that has
4345 // a window displayed.
4346 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004347 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004348 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004349 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004350 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07004351 "Skipping token -- currently sending to bottom");
4352 tokenPos--;
4353 continue;
4354 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004355 int i = wtoken.windows.size();
4356 while (i > 0) {
4357 i--;
4358 WindowState win = wtoken.windows.get(i);
4359 int j = win.mChildWindows.size();
4360 while (j > 0) {
4361 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004362 WindowState cwin = win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004363 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004364 for (int pos=NW-1; pos>=0; pos--) {
4365 if (mWindows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004366 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004367 "Found child win @" + (pos+1));
4368 return pos+1;
4369 }
4370 }
4371 }
4372 }
4373 for (int pos=NW-1; pos>=0; pos--) {
4374 if (mWindows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004375 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004376 return pos+1;
4377 }
4378 }
4379 }
4380 tokenPos--;
4381 }
4382
4383 return 0;
4384 }
4385
4386 private final int reAddWindowLocked(int index, WindowState win) {
4387 final int NCW = win.mChildWindows.size();
4388 boolean added = false;
4389 for (int j=0; j<NCW; j++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004390 WindowState cwin = win.mChildWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004391 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004392 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004393 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004394 mWindows.add(index, win);
4395 index++;
4396 added = true;
4397 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004398 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004399 + index + ": " + cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004400 mWindows.add(index, cwin);
4401 index++;
4402 }
4403 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004404 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004405 + index + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004406 mWindows.add(index, win);
4407 index++;
4408 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004409 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004410 return index;
4411 }
Romain Guy06882f82009-06-10 13:36:04 -07004412
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004413 private final int reAddAppWindowsLocked(int index, WindowToken token) {
4414 final int NW = token.windows.size();
4415 for (int i=0; i<NW; i++) {
4416 index = reAddWindowLocked(index, token.windows.get(i));
4417 }
4418 return index;
4419 }
4420
4421 public void moveAppToken(int index, IBinder token) {
4422 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4423 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004424 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004425 }
4426
4427 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004428 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004429 if (DEBUG_REORDER) dumpAppTokensLocked();
4430 final AppWindowToken wtoken = findAppWindowToken(token);
4431 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004432 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004433 + token + " (" + wtoken + ")");
4434 return;
4435 }
4436 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004437 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004438 if (DEBUG_REORDER) dumpAppTokensLocked();
Romain Guy06882f82009-06-10 13:36:04 -07004439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004440 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004441 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004442 if (DEBUG_REORDER) dumpWindowsLocked();
4443 if (tmpRemoveAppWindowsLocked(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004444 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004445 if (DEBUG_REORDER) dumpWindowsLocked();
4446 reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004447 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004448 if (DEBUG_REORDER) dumpWindowsLocked();
4449 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004450 mLayoutNeeded = true;
4451 performLayoutAndPlaceSurfacesLocked();
4452 }
4453 Binder.restoreCallingIdentity(origId);
4454 }
4455 }
4456
4457 private void removeAppTokensLocked(List<IBinder> tokens) {
4458 // XXX This should be done more efficiently!
4459 // (take advantage of the fact that both lists should be
4460 // ordered in the same way.)
4461 int N = tokens.size();
4462 for (int i=0; i<N; i++) {
4463 IBinder token = tokens.get(i);
4464 final AppWindowToken wtoken = findAppWindowToken(token);
4465 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004466 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004467 + token + " (" + wtoken + ")");
4468 i--;
4469 N--;
4470 }
4471 }
4472 }
4473
Dianne Hackborna8f60182009-09-01 19:01:50 -07004474 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
4475 boolean updateFocusAndLayout) {
4476 // First remove all of the windows from the list.
4477 tmpRemoveAppWindowsLocked(wtoken);
4478
4479 // Where to start adding?
4480 int pos = findWindowOffsetLocked(tokenPos);
4481
4482 // And now add them back at the correct place.
4483 pos = reAddAppWindowsLocked(pos, wtoken);
4484
4485 if (updateFocusAndLayout) {
4486 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4487 assignLayersLocked();
4488 }
4489 mLayoutNeeded = true;
4490 performLayoutAndPlaceSurfacesLocked();
4491 }
4492 }
4493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004494 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
4495 // First remove all of the windows from the list.
4496 final int N = tokens.size();
4497 int i;
4498 for (i=0; i<N; i++) {
4499 WindowToken token = mTokenMap.get(tokens.get(i));
4500 if (token != null) {
4501 tmpRemoveAppWindowsLocked(token);
4502 }
4503 }
4504
4505 // Where to start adding?
4506 int pos = findWindowOffsetLocked(tokenPos);
4507
4508 // And now add them back at the correct place.
4509 for (i=0; i<N; i++) {
4510 WindowToken token = mTokenMap.get(tokens.get(i));
4511 if (token != null) {
4512 pos = reAddAppWindowsLocked(pos, token);
4513 }
4514 }
4515
Dianne Hackborna8f60182009-09-01 19:01:50 -07004516 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
4517 assignLayersLocked();
4518 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004519 mLayoutNeeded = true;
4520 performLayoutAndPlaceSurfacesLocked();
4521
4522 //dump();
4523 }
4524
4525 public void moveAppTokensToTop(List<IBinder> tokens) {
4526 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4527 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004528 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004529 }
4530
4531 final long origId = Binder.clearCallingIdentity();
4532 synchronized(mWindowMap) {
4533 removeAppTokensLocked(tokens);
4534 final int N = tokens.size();
4535 for (int i=0; i<N; i++) {
4536 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4537 if (wt != null) {
4538 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004539 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004540 mToTopApps.remove(wt);
4541 mToBottomApps.remove(wt);
4542 mToTopApps.add(wt);
4543 wt.sendingToBottom = false;
4544 wt.sendingToTop = true;
4545 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004546 }
4547 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004548
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004549 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004550 moveAppWindowsLocked(tokens, mAppTokens.size());
4551 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004552 }
4553 Binder.restoreCallingIdentity(origId);
4554 }
4555
4556 public void moveAppTokensToBottom(List<IBinder> tokens) {
4557 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4558 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004559 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004560 }
4561
4562 final long origId = Binder.clearCallingIdentity();
4563 synchronized(mWindowMap) {
4564 removeAppTokensLocked(tokens);
4565 final int N = tokens.size();
4566 int pos = 0;
4567 for (int i=0; i<N; i++) {
4568 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4569 if (wt != null) {
4570 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004571 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004572 mToTopApps.remove(wt);
4573 mToBottomApps.remove(wt);
4574 mToBottomApps.add(i, wt);
4575 wt.sendingToTop = false;
4576 wt.sendingToBottom = true;
4577 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004578 pos++;
4579 }
4580 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004581
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004582 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004583 moveAppWindowsLocked(tokens, 0);
4584 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004585 }
4586 Binder.restoreCallingIdentity(origId);
4587 }
4588
4589 // -------------------------------------------------------------
4590 // Misc IWindowSession methods
4591 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004592
Jim Miller284b62e2010-06-08 14:27:42 -07004593 private boolean shouldAllowDisableKeyguard()
Jim Millerd6b57052010-06-07 17:52:42 -07004594 {
Jim Miller284b62e2010-06-08 14:27:42 -07004595 // We fail safe and prevent disabling keyguard in the unlikely event this gets
4596 // called before DevicePolicyManagerService has started.
4597 if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
4598 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
4599 Context.DEVICE_POLICY_SERVICE);
4600 if (dpm != null) {
4601 mAllowDisableKeyguard = dpm.getPasswordQuality(null)
4602 == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
4603 ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
4604 }
Jim Millerd6b57052010-06-07 17:52:42 -07004605 }
Jim Miller284b62e2010-06-08 14:27:42 -07004606 return mAllowDisableKeyguard == ALLOW_DISABLE_YES;
Jim Millerd6b57052010-06-07 17:52:42 -07004607 }
4608
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004609 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004610 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004611 != PackageManager.PERMISSION_GRANTED) {
4612 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4613 }
Jim Millerd6b57052010-06-07 17:52:42 -07004614
Jim Miller284b62e2010-06-08 14:27:42 -07004615 synchronized (mKeyguardTokenWatcher) {
4616 mKeyguardTokenWatcher.acquire(token, tag);
Mike Lockwooddd884682009-10-11 16:57:08 -04004617 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004618 }
4619
4620 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004621 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004622 != PackageManager.PERMISSION_GRANTED) {
4623 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4624 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004625
Jim Miller284b62e2010-06-08 14:27:42 -07004626 synchronized (mKeyguardTokenWatcher) {
4627 mKeyguardTokenWatcher.release(token);
Jim Millerd6b57052010-06-07 17:52:42 -07004628
Jim Miller284b62e2010-06-08 14:27:42 -07004629 if (!mKeyguardTokenWatcher.isAcquired()) {
4630 // If we are the last one to reenable the keyguard wait until
4631 // we have actually finished reenabling until returning.
4632 // It is possible that reenableKeyguard() can be called before
4633 // the previous disableKeyguard() is handled, in which case
4634 // neither mKeyguardTokenWatcher.acquired() or released() would
4635 // be called. In that case mKeyguardDisabled will be false here
4636 // and we have nothing to wait for.
4637 while (mKeyguardDisabled) {
4638 try {
4639 mKeyguardTokenWatcher.wait();
4640 } catch (InterruptedException e) {
4641 Thread.currentThread().interrupt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004642 }
4643 }
4644 }
4645 }
4646 }
4647
4648 /**
4649 * @see android.app.KeyguardManager#exitKeyguardSecurely
4650 */
4651 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004652 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004653 != PackageManager.PERMISSION_GRANTED) {
4654 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4655 }
4656 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
4657 public void onKeyguardExitResult(boolean success) {
4658 try {
4659 callback.onKeyguardExitResult(success);
4660 } catch (RemoteException e) {
4661 // Client has died, we don't care.
4662 }
4663 }
4664 });
4665 }
4666
4667 public boolean inKeyguardRestrictedInputMode() {
4668 return mPolicy.inKeyguardRestrictedKeyInputMode();
4669 }
Romain Guy06882f82009-06-10 13:36:04 -07004670
Dianne Hackbornffa42482009-09-23 22:20:11 -07004671 public void closeSystemDialogs(String reason) {
4672 synchronized(mWindowMap) {
4673 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07004674 WindowState w = mWindows.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07004675 if (w.mSurface != null) {
4676 try {
4677 w.mClient.closeSystemDialogs(reason);
4678 } catch (RemoteException e) {
4679 }
4680 }
4681 }
4682 }
4683 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004684
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004685 static float fixScale(float scale) {
4686 if (scale < 0) scale = 0;
4687 else if (scale > 20) scale = 20;
4688 return Math.abs(scale);
4689 }
Romain Guy06882f82009-06-10 13:36:04 -07004690
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004691 public void setAnimationScale(int which, float scale) {
4692 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4693 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004694 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004695 }
4696
4697 if (scale < 0) scale = 0;
4698 else if (scale > 20) scale = 20;
4699 scale = Math.abs(scale);
4700 switch (which) {
4701 case 0: mWindowAnimationScale = fixScale(scale); break;
4702 case 1: mTransitionAnimationScale = fixScale(scale); break;
4703 }
Romain Guy06882f82009-06-10 13:36:04 -07004704
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004705 // Persist setting
4706 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4707 }
Romain Guy06882f82009-06-10 13:36:04 -07004708
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004709 public void setAnimationScales(float[] scales) {
4710 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4711 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004712 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004713 }
4714
4715 if (scales != null) {
4716 if (scales.length >= 1) {
4717 mWindowAnimationScale = fixScale(scales[0]);
4718 }
4719 if (scales.length >= 2) {
4720 mTransitionAnimationScale = fixScale(scales[1]);
4721 }
4722 }
Romain Guy06882f82009-06-10 13:36:04 -07004723
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004724 // Persist setting
4725 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4726 }
Romain Guy06882f82009-06-10 13:36:04 -07004727
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004728 public float getAnimationScale(int which) {
4729 switch (which) {
4730 case 0: return mWindowAnimationScale;
4731 case 1: return mTransitionAnimationScale;
4732 }
4733 return 0;
4734 }
Romain Guy06882f82009-06-10 13:36:04 -07004735
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004736 public float[] getAnimationScales() {
4737 return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
4738 }
Romain Guy06882f82009-06-10 13:36:04 -07004739
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004740 public int getSwitchState(int sw) {
4741 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4742 "getSwitchState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004743 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004744 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004745 return mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004746 }
Romain Guy06882f82009-06-10 13:36:04 -07004747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004748 public int getSwitchStateForDevice(int devid, int sw) {
4749 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4750 "getSwitchStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004751 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004752 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004753 return mInputManager.getSwitchState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004754 }
Romain Guy06882f82009-06-10 13:36:04 -07004755
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004756 public int getScancodeState(int sw) {
4757 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4758 "getScancodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004759 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004760 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004761 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004762 }
Romain Guy06882f82009-06-10 13:36:04 -07004763
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004764 public int getScancodeStateForDevice(int devid, int sw) {
4765 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4766 "getScancodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004767 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004768 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004769 return mInputManager.getScanCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004770 }
Romain Guy06882f82009-06-10 13:36:04 -07004771
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004772 public int getTrackballScancodeState(int sw) {
4773 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4774 "getTrackballScancodeState()")) {
4775 throw new SecurityException("Requires READ_INPUT_STATE permission");
4776 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004777 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004778 }
4779
4780 public int getDPadScancodeState(int sw) {
4781 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4782 "getDPadScancodeState()")) {
4783 throw new SecurityException("Requires READ_INPUT_STATE permission");
4784 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004785 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004786 }
4787
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004788 public int getKeycodeState(int sw) {
4789 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4790 "getKeycodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004791 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004792 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004793 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004794 }
Romain Guy06882f82009-06-10 13:36:04 -07004795
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004796 public int getKeycodeStateForDevice(int devid, int sw) {
4797 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4798 "getKeycodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004799 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004800 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004801 return mInputManager.getKeyCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004802 }
Romain Guy06882f82009-06-10 13:36:04 -07004803
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004804 public int getTrackballKeycodeState(int sw) {
4805 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4806 "getTrackballKeycodeState()")) {
4807 throw new SecurityException("Requires READ_INPUT_STATE permission");
4808 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004809 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004810 }
4811
4812 public int getDPadKeycodeState(int sw) {
4813 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4814 "getDPadKeycodeState()")) {
4815 throw new SecurityException("Requires READ_INPUT_STATE permission");
4816 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004817 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004818 }
Jeff Browna41ca772010-08-11 14:46:32 -07004819
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004820 public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
Jeff Brown6d0fec22010-07-23 21:28:06 -07004821 return mInputManager.hasKeys(-1, InputDevice.SOURCE_ANY, keycodes, keyExists);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004822 }
Romain Guy06882f82009-06-10 13:36:04 -07004823
Jeff Browna41ca772010-08-11 14:46:32 -07004824 public InputChannel monitorInput(String inputChannelName) {
4825 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4826 "monitorInput()")) {
4827 throw new SecurityException("Requires READ_INPUT_STATE permission");
4828 }
4829 return mInputManager.monitorInput(inputChannelName);
4830 }
4831
Jeff Brown8d608662010-08-30 03:02:23 -07004832 public InputDevice getInputDevice(int deviceId) {
4833 return mInputManager.getInputDevice(deviceId);
4834 }
4835
4836 public int[] getInputDeviceIds() {
4837 return mInputManager.getInputDeviceIds();
4838 }
4839
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004840 public void enableScreenAfterBoot() {
4841 synchronized(mWindowMap) {
4842 if (mSystemBooted) {
4843 return;
4844 }
4845 mSystemBooted = true;
4846 }
Romain Guy06882f82009-06-10 13:36:04 -07004847
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004848 performEnableScreen();
4849 }
Romain Guy06882f82009-06-10 13:36:04 -07004850
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004851 public void enableScreenIfNeededLocked() {
4852 if (mDisplayEnabled) {
4853 return;
4854 }
4855 if (!mSystemBooted) {
4856 return;
4857 }
4858 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
4859 }
Romain Guy06882f82009-06-10 13:36:04 -07004860
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004861 public void performEnableScreen() {
4862 synchronized(mWindowMap) {
4863 if (mDisplayEnabled) {
4864 return;
4865 }
4866 if (!mSystemBooted) {
4867 return;
4868 }
Romain Guy06882f82009-06-10 13:36:04 -07004869
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004870 // Don't enable the screen until all existing windows
4871 // have been drawn.
4872 final int N = mWindows.size();
4873 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004874 WindowState w = mWindows.get(i);
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08004875 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004876 return;
4877 }
4878 }
Romain Guy06882f82009-06-10 13:36:04 -07004879
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004880 mDisplayEnabled = true;
4881 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004882 Slog.i(TAG, "ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004883 StringWriter sw = new StringWriter();
4884 PrintWriter pw = new PrintWriter(sw);
4885 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004886 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004887 }
4888 try {
4889 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
4890 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004891 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004892 Parcel data = Parcel.obtain();
4893 data.writeInterfaceToken("android.ui.ISurfaceComposer");
4894 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
4895 data, null, 0);
4896 data.recycle();
4897 }
4898 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004899 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004900 }
4901 }
Romain Guy06882f82009-06-10 13:36:04 -07004902
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004903 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07004904
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004905 // Make sure the last requested orientation has been applied.
Dianne Hackborn321ae682009-03-27 16:16:03 -07004906 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
4907 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004908 }
Romain Guy06882f82009-06-10 13:36:04 -07004909
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004910 public void setInTouchMode(boolean mode) {
4911 synchronized(mWindowMap) {
4912 mInTouchMode = mode;
4913 }
4914 }
4915
Brad Fitzpatrick68044332010-11-22 18:19:48 -08004916 // TODO: more accounting of which pid(s) turned it on, keep count,
4917 // only allow disables from pids which have count on, etc.
4918 public void showStrictModeViolation(boolean on) {
4919 int pid = Binder.getCallingPid();
4920 synchronized(mWindowMap) {
4921 // Ignoring requests to enable the red border from clients
4922 // which aren't on screen. (e.g. Broadcast Receivers in
4923 // the background..)
4924 if (on) {
4925 boolean isVisible = false;
4926 for (WindowState ws : mWindows) {
4927 if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
4928 isVisible = true;
4929 break;
4930 }
4931 }
4932 if (!isVisible) {
4933 return;
4934 }
4935 }
4936
4937 Surface.openTransaction();
4938 if (mStrictModeFlash == null) {
4939 mStrictModeFlash = new StrictModeFlash(mDisplay, mFxSession);
4940 }
4941 mStrictModeFlash.setVisibility(on);
4942 Surface.closeTransaction();
4943 }
4944 }
4945
Brad Fitzpatrickc1a968a2010-11-24 08:56:40 -08004946 public void setStrictModeVisualIndicatorPreference(String value) {
4947 SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
4948 }
4949
Dianne Hackbornd2835932010-12-13 16:28:46 -08004950 public Bitmap screenshotApplications(IBinder appToken, int maxWidth, int maxHeight) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004951 if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
4952 "screenshotApplications()")) {
4953 throw new SecurityException("Requires READ_FRAME_BUFFER permission");
4954 }
4955
4956 Bitmap rawss;
4957
Dianne Hackbornd2835932010-12-13 16:28:46 -08004958 int maxLayer = 0;
4959 boolean foundApp;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004960 final Rect frame = new Rect();
4961
4962 float scale;
4963 int sw, sh, dw, dh;
4964 int rot;
4965
4966 synchronized(mWindowMap) {
4967 long ident = Binder.clearCallingIdentity();
4968
4969 int aboveAppLayer = mPolicy.windowTypeToLayerLw(
4970 WindowManager.LayoutParams.TYPE_APPLICATION) * TYPE_LAYER_MULTIPLIER
4971 + TYPE_LAYER_OFFSET;
4972 aboveAppLayer += TYPE_LAYER_MULTIPLIER;
4973
4974 // Figure out the part of the screen that is actually the app.
4975 for (int i=0; i<mWindows.size(); i++) {
4976 WindowState ws = mWindows.get(i);
4977 if (ws.mSurface == null) {
4978 continue;
4979 }
4980 if (ws.mLayer >= aboveAppLayer) {
4981 break;
4982 }
Dianne Hackbornd2835932010-12-13 16:28:46 -08004983 if (appToken != null && (ws.mAppToken == null
4984 || ws.mAppToken.token != appToken)) {
4985 continue;
4986 }
4987 if (maxLayer < ws.mAnimLayer) {
4988 maxLayer = ws.mAnimLayer;
4989 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004990 final Rect wf = ws.mFrame;
4991 final Rect cr = ws.mContentInsets;
4992 int left = wf.left + cr.left;
4993 int top = wf.top + cr.top;
4994 int right = wf.right - cr.right;
4995 int bottom = wf.bottom - cr.bottom;
4996 frame.union(left, top, right, bottom);
4997 }
4998 Binder.restoreCallingIdentity(ident);
4999
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005000 if (frame.isEmpty() || maxLayer == 0) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005001 return null;
5002 }
5003
5004 // The screenshot API does not apply the current screen rotation.
5005 rot = mDisplay.getRotation();
5006 int fw = frame.width();
5007 int fh = frame.height();
5008
5009 // First try reducing to fit in x dimension.
5010 scale = maxWidth/(float)fw;
5011 sw = maxWidth;
5012 sh = (int)(fh*scale);
5013 if (sh > maxHeight) {
5014 // y dimension became too long; constrain by that.
5015 scale = maxHeight/(float)fh;
5016 sw = (int)(fw*scale);
5017 sh = maxHeight;
5018 }
5019
5020 // The screen shot will contain the entire screen.
5021 dw = (int)(mDisplay.getWidth()*scale);
5022 dh = (int)(mDisplay.getHeight()*scale);
5023 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
5024 int tmp = dw;
5025 dw = dh;
5026 dh = tmp;
5027 rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
5028 }
Dianne Hackbornd2835932010-12-13 16:28:46 -08005029 rawss = Surface.screenshot(dw, dh, 0, maxLayer);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005030 }
5031
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005032 if (rawss == null) {
Dianne Hackborn88b03bd2010-12-16 11:15:18 -08005033 Log.w(TAG, "Failure taking screenshot for (" + dw + "x" + dh
5034 + ") to layer " + maxLayer);
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005035 return null;
5036 }
5037
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005038 Bitmap bm = Bitmap.createBitmap(sw, sh, rawss.getConfig());
5039 Matrix matrix = new Matrix();
5040 ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
5041 matrix.postTranslate(-(int)(frame.left*scale), -(int)(frame.top*scale));
5042 Canvas canvas = new Canvas(bm);
5043 canvas.drawBitmap(rawss, matrix, null);
5044
5045 rawss.recycle();
5046 return bm;
5047 }
5048
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005049 public void freezeRotation() {
5050 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
5051 "setRotation()")) {
5052 throw new SecurityException("Requires SET_ORIENTATION permission");
5053 }
5054
5055 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED, mRotation);
5056 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
5057 }
5058
5059 public void thawRotation() {
5060 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
5061 "setRotation()")) {
5062 throw new SecurityException("Requires SET_ORIENTATION permission");
5063 }
5064
5065 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 0);
5066 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
5067 }
5068
Romain Guy06882f82009-06-10 13:36:04 -07005069 public void setRotation(int rotation,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005070 boolean alwaysSendConfiguration, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005071 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005072 "setRotation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005073 throw new SecurityException("Requires SET_ORIENTATION permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005074 }
5075
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005076 setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005077 }
Romain Guy06882f82009-06-10 13:36:04 -07005078
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005079 public void setRotationUnchecked(int rotation,
5080 boolean alwaysSendConfiguration, int animFlags) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005081 if(DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005082 "alwaysSendConfiguration set to "+alwaysSendConfiguration);
Romain Guy06882f82009-06-10 13:36:04 -07005083
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005084 long origId = Binder.clearCallingIdentity();
5085 boolean changed;
5086 synchronized(mWindowMap) {
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005087 changed = setRotationUncheckedLocked(rotation, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005088 }
Romain Guy06882f82009-06-10 13:36:04 -07005089
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005090 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005091 sendNewConfiguration();
5092 }
Romain Guy06882f82009-06-10 13:36:04 -07005093
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005094 Binder.restoreCallingIdentity(origId);
5095 }
Romain Guy06882f82009-06-10 13:36:04 -07005096
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005097 /**
5098 * Apply a new rotation to the screen, respecting the requests of
5099 * applications. Use WindowManagerPolicy.USE_LAST_ROTATION to simply
5100 * re-evaluate the desired rotation.
5101 *
5102 * Returns null if the rotation has been changed. In this case YOU
5103 * MUST CALL setNewConfiguration() TO UNFREEZE THE SCREEN.
5104 */
Dianne Hackborn1e880db2009-03-27 16:04:08 -07005105 public boolean setRotationUncheckedLocked(int rotation, int animFlags) {
Christopher Tateccd24de2011-01-12 15:02:55 -08005106 if (mDragState != null) {
5107 // Potential rotation during a drag. Don't do the rotation now, but make
5108 // a note to perform the rotation later.
5109 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation during drag");
5110 mDragState.setDeferredRotation(rotation, animFlags);
5111 return false;
5112 }
5113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005114 boolean changed;
5115 if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
5116 rotation = mRequestedRotation;
5117 } else {
5118 mRequestedRotation = rotation;
Dianne Hackborn321ae682009-03-27 16:16:03 -07005119 mLastRotationFlags = animFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005120 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005121 if (DEBUG_ORIENTATION) Slog.v(TAG, "Overwriting rotation value from " + rotation);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07005122 rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005123 mRotation, mDisplayEnabled);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005124 if (DEBUG_ORIENTATION) Slog.v(TAG, "new rotation is set to " + rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005125 changed = mDisplayEnabled && mRotation != rotation;
Romain Guy06882f82009-06-10 13:36:04 -07005126
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005127 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005128 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005129 "Rotation changed to " + rotation
5130 + " from " + mRotation
5131 + " (forceApp=" + mForcedAppOrientation
5132 + ", req=" + mRequestedRotation + ")");
5133 mRotation = rotation;
5134 mWindowsFreezingScreen = true;
5135 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
5136 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
5137 2000);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005138 mWaitingForConfig = true;
5139 mLayoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005140 startFreezingDisplayLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08005141 Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005142 mInputManager.setDisplayOrientation(0, rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005143 if (mDisplayEnabled) {
Dianne Hackborna1111872010-11-23 20:55:11 -08005144 if (CUSTOM_SCREEN_ROTATION) {
5145 Surface.freezeDisplay(0);
5146 Surface.openTransaction();
5147 if (mScreenRotationAnimation != null) {
5148 mScreenRotationAnimation.setRotation(rotation);
5149 }
5150 Surface.closeTransaction();
5151 Surface.setOrientation(0, rotation, animFlags);
5152 Surface.unfreezeDisplay(0);
5153 } else {
5154 Surface.setOrientation(0, rotation, animFlags);
5155 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005156 }
5157 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07005158 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005159 if (w.mSurface != null) {
5160 w.mOrientationChanging = true;
5161 }
5162 }
5163 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
5164 try {
5165 mRotationWatchers.get(i).onRotationChanged(rotation);
5166 } catch (RemoteException e) {
5167 }
5168 }
5169 } //end if changed
Romain Guy06882f82009-06-10 13:36:04 -07005170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005171 return changed;
5172 }
Romain Guy06882f82009-06-10 13:36:04 -07005173
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005174 public int getRotation() {
5175 return mRotation;
5176 }
5177
5178 public int watchRotation(IRotationWatcher watcher) {
5179 final IBinder watcherBinder = watcher.asBinder();
5180 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
5181 public void binderDied() {
5182 synchronized (mWindowMap) {
5183 for (int i=0; i<mRotationWatchers.size(); i++) {
5184 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07005185 IRotationWatcher removed = mRotationWatchers.remove(i);
5186 if (removed != null) {
5187 removed.asBinder().unlinkToDeath(this, 0);
5188 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005189 i--;
5190 }
5191 }
5192 }
5193 }
5194 };
Romain Guy06882f82009-06-10 13:36:04 -07005195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005196 synchronized (mWindowMap) {
5197 try {
5198 watcher.asBinder().linkToDeath(dr, 0);
5199 mRotationWatchers.add(watcher);
5200 } catch (RemoteException e) {
5201 // Client died, no cleanup needed.
5202 }
Romain Guy06882f82009-06-10 13:36:04 -07005203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005204 return mRotation;
5205 }
5206 }
5207
5208 /**
5209 * Starts the view server on the specified port.
5210 *
5211 * @param port The port to listener to.
5212 *
5213 * @return True if the server was successfully started, false otherwise.
5214 *
5215 * @see com.android.server.ViewServer
5216 * @see com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT
5217 */
5218 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07005219 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005220 return false;
5221 }
5222
5223 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
5224 return false;
5225 }
5226
5227 if (port < 1024) {
5228 return false;
5229 }
5230
5231 if (mViewServer != null) {
5232 if (!mViewServer.isRunning()) {
5233 try {
5234 return mViewServer.start();
5235 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005236 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005237 }
5238 }
5239 return false;
5240 }
5241
5242 try {
5243 mViewServer = new ViewServer(this, port);
5244 return mViewServer.start();
5245 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005246 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005247 }
5248 return false;
5249 }
5250
Romain Guy06882f82009-06-10 13:36:04 -07005251 private boolean isSystemSecure() {
5252 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
5253 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5254 }
5255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005256 /**
5257 * Stops the view server if it exists.
5258 *
5259 * @return True if the server stopped, false if it wasn't started or
5260 * couldn't be stopped.
5261 *
5262 * @see com.android.server.ViewServer
5263 */
5264 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07005265 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005266 return false;
5267 }
5268
5269 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
5270 return false;
5271 }
5272
5273 if (mViewServer != null) {
5274 return mViewServer.stop();
5275 }
5276 return false;
5277 }
5278
5279 /**
5280 * Indicates whether the view server is running.
5281 *
5282 * @return True if the server is running, false otherwise.
5283 *
5284 * @see com.android.server.ViewServer
5285 */
5286 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07005287 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005288 return false;
5289 }
5290
5291 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
5292 return false;
5293 }
5294
5295 return mViewServer != null && mViewServer.isRunning();
5296 }
5297
5298 /**
5299 * Lists all availble windows in the system. The listing is written in the
5300 * specified Socket's output stream with the following syntax:
5301 * windowHashCodeInHexadecimal windowName
5302 * Each line of the ouput represents a different window.
5303 *
5304 * @param client The remote client to send the listing to.
5305 * @return False if an error occured, true otherwise.
5306 */
5307 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07005308 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005309 return false;
5310 }
5311
5312 boolean result = true;
5313
Jeff Browne33348b2010-07-15 23:54:05 -07005314 WindowState[] windows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005315 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005316 //noinspection unchecked
Jeff Browne33348b2010-07-15 23:54:05 -07005317 windows = mWindows.toArray(new WindowState[mWindows.size()]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005318 }
5319
5320 BufferedWriter out = null;
5321
5322 // Any uncaught exception will crash the system process
5323 try {
5324 OutputStream clientStream = client.getOutputStream();
5325 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5326
5327 final int count = windows.length;
5328 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005329 final WindowState w = windows[i];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005330 out.write(Integer.toHexString(System.identityHashCode(w)));
5331 out.write(' ');
5332 out.append(w.mAttrs.getTitle());
5333 out.write('\n');
5334 }
5335
5336 out.write("DONE.\n");
5337 out.flush();
5338 } catch (Exception e) {
5339 result = false;
5340 } finally {
5341 if (out != null) {
5342 try {
5343 out.close();
5344 } catch (IOException e) {
5345 result = false;
5346 }
5347 }
5348 }
5349
5350 return result;
5351 }
5352
5353 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07005354 * Returns the focused window in the following format:
5355 * windowHashCodeInHexadecimal windowName
5356 *
5357 * @param client The remote client to send the listing to.
5358 * @return False if an error occurred, true otherwise.
5359 */
5360 boolean viewServerGetFocusedWindow(Socket client) {
5361 if (isSystemSecure()) {
5362 return false;
5363 }
5364
5365 boolean result = true;
5366
5367 WindowState focusedWindow = getFocusedWindow();
5368
5369 BufferedWriter out = null;
5370
5371 // Any uncaught exception will crash the system process
5372 try {
5373 OutputStream clientStream = client.getOutputStream();
5374 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5375
5376 if(focusedWindow != null) {
5377 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
5378 out.write(' ');
5379 out.append(focusedWindow.mAttrs.getTitle());
5380 }
5381 out.write('\n');
5382 out.flush();
5383 } catch (Exception e) {
5384 result = false;
5385 } finally {
5386 if (out != null) {
5387 try {
5388 out.close();
5389 } catch (IOException e) {
5390 result = false;
5391 }
5392 }
5393 }
5394
5395 return result;
5396 }
5397
5398 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005399 * Sends a command to a target window. The result of the command, if any, will be
5400 * written in the output stream of the specified socket.
5401 *
5402 * The parameters must follow this syntax:
5403 * windowHashcode extra
5404 *
5405 * Where XX is the length in characeters of the windowTitle.
5406 *
5407 * The first parameter is the target window. The window with the specified hashcode
5408 * will be the target. If no target can be found, nothing happens. The extra parameters
5409 * will be delivered to the target window and as parameters to the command itself.
5410 *
5411 * @param client The remote client to sent the result, if any, to.
5412 * @param command The command to execute.
5413 * @param parameters The command parameters.
5414 *
5415 * @return True if the command was successfully delivered, false otherwise. This does
5416 * not indicate whether the command itself was successful.
5417 */
5418 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07005419 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005420 return false;
5421 }
5422
5423 boolean success = true;
5424 Parcel data = null;
5425 Parcel reply = null;
5426
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005427 BufferedWriter out = null;
5428
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005429 // Any uncaught exception will crash the system process
5430 try {
5431 // Find the hashcode of the window
5432 int index = parameters.indexOf(' ');
5433 if (index == -1) {
5434 index = parameters.length();
5435 }
5436 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08005437 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005438
5439 // Extract the command's parameter after the window description
5440 if (index < parameters.length()) {
5441 parameters = parameters.substring(index + 1);
5442 } else {
5443 parameters = "";
5444 }
5445
5446 final WindowManagerService.WindowState window = findWindow(hashCode);
5447 if (window == null) {
5448 return false;
5449 }
5450
5451 data = Parcel.obtain();
5452 data.writeInterfaceToken("android.view.IWindow");
5453 data.writeString(command);
5454 data.writeString(parameters);
5455 data.writeInt(1);
5456 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
5457
5458 reply = Parcel.obtain();
5459
5460 final IBinder binder = window.mClient.asBinder();
5461 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
5462 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
5463
5464 reply.readException();
5465
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005466 if (!client.isOutputShutdown()) {
5467 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
5468 out.write("DONE\n");
5469 out.flush();
5470 }
5471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005472 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005473 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005474 success = false;
5475 } finally {
5476 if (data != null) {
5477 data.recycle();
5478 }
5479 if (reply != null) {
5480 reply.recycle();
5481 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005482 if (out != null) {
5483 try {
5484 out.close();
5485 } catch (IOException e) {
5486
5487 }
5488 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005489 }
5490
5491 return success;
5492 }
5493
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07005494 public void addWindowChangeListener(WindowChangeListener listener) {
5495 synchronized(mWindowMap) {
5496 mWindowChangeListeners.add(listener);
5497 }
5498 }
5499
5500 public void removeWindowChangeListener(WindowChangeListener listener) {
5501 synchronized(mWindowMap) {
5502 mWindowChangeListeners.remove(listener);
5503 }
5504 }
5505
5506 private void notifyWindowsChanged() {
5507 WindowChangeListener[] windowChangeListeners;
5508 synchronized(mWindowMap) {
5509 if(mWindowChangeListeners.isEmpty()) {
5510 return;
5511 }
5512 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5513 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5514 }
5515 int N = windowChangeListeners.length;
5516 for(int i = 0; i < N; i++) {
5517 windowChangeListeners[i].windowsChanged();
5518 }
5519 }
5520
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07005521 private void notifyFocusChanged() {
5522 WindowChangeListener[] windowChangeListeners;
5523 synchronized(mWindowMap) {
5524 if(mWindowChangeListeners.isEmpty()) {
5525 return;
5526 }
5527 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5528 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5529 }
5530 int N = windowChangeListeners.length;
5531 for(int i = 0; i < N; i++) {
5532 windowChangeListeners[i].focusChanged();
5533 }
5534 }
5535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005536 private WindowState findWindow(int hashCode) {
5537 if (hashCode == -1) {
5538 return getFocusedWindow();
5539 }
5540
5541 synchronized (mWindowMap) {
Jeff Browne33348b2010-07-15 23:54:05 -07005542 final ArrayList<WindowState> windows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005543 final int count = windows.size();
5544
5545 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005546 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005547 if (System.identityHashCode(w) == hashCode) {
5548 return w;
5549 }
5550 }
5551 }
5552
5553 return null;
5554 }
5555
5556 /*
5557 * Instruct the Activity Manager to fetch the current configuration and broadcast
5558 * that to config-changed listeners if appropriate.
5559 */
5560 void sendNewConfiguration() {
5561 try {
5562 mActivityManager.updateConfiguration(null);
5563 } catch (RemoteException e) {
5564 }
5565 }
Romain Guy06882f82009-06-10 13:36:04 -07005566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005567 public Configuration computeNewConfiguration() {
5568 synchronized (mWindowMap) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07005569 return computeNewConfigurationLocked();
5570 }
5571 }
Romain Guy06882f82009-06-10 13:36:04 -07005572
Dianne Hackbornc485a602009-03-24 22:39:49 -07005573 Configuration computeNewConfigurationLocked() {
5574 Configuration config = new Configuration();
5575 if (!computeNewConfigurationLocked(config)) {
5576 return null;
5577 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07005578 return config;
5579 }
Romain Guy06882f82009-06-10 13:36:04 -07005580
Dianne Hackbornc485a602009-03-24 22:39:49 -07005581 boolean computeNewConfigurationLocked(Configuration config) {
5582 if (mDisplay == null) {
5583 return false;
5584 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005585
5586 mInputManager.getInputConfiguration(config);
Christopher Tateb696aee2010-04-02 19:08:30 -07005587
5588 // Use the effective "visual" dimensions based on current rotation
5589 final boolean rotated = (mRotation == Surface.ROTATION_90
5590 || mRotation == Surface.ROTATION_270);
5591 final int dw = rotated ? mInitialDisplayHeight : mInitialDisplayWidth;
5592 final int dh = rotated ? mInitialDisplayWidth : mInitialDisplayHeight;
5593
Dianne Hackbornc485a602009-03-24 22:39:49 -07005594 int orientation = Configuration.ORIENTATION_SQUARE;
5595 if (dw < dh) {
5596 orientation = Configuration.ORIENTATION_PORTRAIT;
5597 } else if (dw > dh) {
5598 orientation = Configuration.ORIENTATION_LANDSCAPE;
5599 }
5600 config.orientation = orientation;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005601
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005602 DisplayMetrics dm = new DisplayMetrics();
5603 mDisplay.getMetrics(dm);
5604 CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame);
5605
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005606 if (mScreenLayout == Configuration.SCREENLAYOUT_SIZE_UNDEFINED) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07005607 // Note we only do this once because at this point we don't
5608 // expect the screen to change in this way at runtime, and want
5609 // to avoid all of this computation for every config change.
Dianne Hackborn723738c2009-06-25 19:48:04 -07005610 int longSize = dw;
5611 int shortSize = dh;
5612 if (longSize < shortSize) {
5613 int tmp = longSize;
5614 longSize = shortSize;
5615 shortSize = tmp;
5616 }
5617 longSize = (int)(longSize/dm.density);
5618 shortSize = (int)(shortSize/dm.density);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005619
Dianne Hackborn723738c2009-06-25 19:48:04 -07005620 // These semi-magic numbers define our compatibility modes for
5621 // applications with different screens. Don't change unless you
5622 // make sure to test lots and lots of apps!
5623 if (longSize < 470) {
5624 // This is shorter than an HVGA normal density screen (which
5625 // is 480 pixels on its long side).
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005626 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL
5627 | Configuration.SCREENLAYOUT_LONG_NO;
Dianne Hackborn723738c2009-06-25 19:48:04 -07005628 } else {
Dianne Hackborn14cee9f2010-04-23 17:51:26 -07005629 // What size is this screen screen?
5630 if (longSize >= 800 && shortSize >= 600) {
5631 // SVGA or larger screens at medium density are the point
5632 // at which we consider it to be an extra large screen.
5633 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE;
Dianne Hackbornb51dc0f2010-10-21 15:34:47 -07005634 } else if (longSize >= 530 && shortSize >= 400) {
5635 // SVGA or larger screens at high density are the point
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005636 // at which we consider it to be a large screen.
5637 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
5638 } else {
5639 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005640
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005641 // If this screen is wider than normal HVGA, or taller
5642 // than FWVGA, then for old apps we want to run in size
5643 // compatibility mode.
5644 if (shortSize > 321 || longSize > 570) {
5645 mScreenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
5646 }
5647 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005648
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005649 // Is this a long screen?
5650 if (((longSize*3)/5) >= (shortSize-1)) {
5651 // Anything wider than WVGA (5:3) is considering to be long.
5652 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_YES;
5653 } else {
5654 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_NO;
5655 }
Dianne Hackborn723738c2009-06-25 19:48:04 -07005656 }
5657 }
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005658 config.screenLayout = mScreenLayout;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005659
Dianne Hackbornc485a602009-03-24 22:39:49 -07005660 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
5661 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
5662 mPolicy.adjustConfigurationLw(config);
5663 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005664 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005665
5666 // -------------------------------------------------------------
5667 // Drag and drop
5668 // -------------------------------------------------------------
5669
5670 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
Christopher Tate02d2b3b2011-01-10 20:43:53 -08005671 int flags, int width, int height, Surface outSurface) {
Christopher Tatea53146c2010-09-07 11:57:52 -07005672 if (DEBUG_DRAG) {
5673 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
Christopher Tate02d2b3b2011-01-10 20:43:53 -08005674 + " flags=" + Integer.toHexString(flags) + " win=" + window
Christopher Tatea53146c2010-09-07 11:57:52 -07005675 + " asbinder=" + window.asBinder());
5676 }
5677
5678 final int callerPid = Binder.getCallingPid();
5679 final long origId = Binder.clearCallingIdentity();
5680 IBinder token = null;
5681
5682 try {
5683 synchronized (mWindowMap) {
5684 try {
Christopher Tatea53146c2010-09-07 11:57:52 -07005685 if (mDragState == null) {
5686 Surface surface = new Surface(session, callerPid, "drag surface", 0,
5687 width, height, PixelFormat.TRANSLUCENT, Surface.HIDDEN);
5688 outSurface.copyFrom(surface);
Chris Tate7b362e42010-11-04 16:02:52 -07005689 final IBinder winBinder = window.asBinder();
Christopher Tatea53146c2010-09-07 11:57:52 -07005690 token = new Binder();
Christopher Tate02d2b3b2011-01-10 20:43:53 -08005691 // TODO: preserve flags param in DragState
5692 mDragState = new DragState(token, surface, 0, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07005693 mDragState.mSurface = surface;
Christopher Tatea53146c2010-09-07 11:57:52 -07005694 token = mDragState.mToken = new Binder();
5695
5696 // 5 second timeout for this window to actually begin the drag
Chris Tate7b362e42010-11-04 16:02:52 -07005697 mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
5698 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07005699 mH.sendMessageDelayed(msg, 5000);
5700 } else {
5701 Slog.w(TAG, "Drag already in progress");
5702 }
5703 } catch (Surface.OutOfResourcesException e) {
5704 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
5705 if (mDragState != null) {
5706 mDragState.reset();
5707 mDragState = null;
5708 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005709 }
5710 }
5711 } finally {
5712 Binder.restoreCallingIdentity(origId);
5713 }
5714
5715 return token;
5716 }
5717
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005718 // -------------------------------------------------------------
5719 // Input Events and Focus Management
5720 // -------------------------------------------------------------
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005721
Jeff Brown349703e2010-06-22 01:27:15 -07005722 InputMonitor mInputMonitor = new InputMonitor();
5723
5724 /* Tracks the progress of input dispatch and ensures that input dispatch state
5725 * is kept in sync with changes in window focus, visibility, registration, and
5726 * other relevant Window Manager state transitions. */
5727 final class InputMonitor {
5728 // Current window with input focus for keys and other non-touch events. May be null.
5729 private WindowState mInputFocus;
5730
5731 // When true, prevents input dispatch from proceeding until set to false again.
5732 private boolean mInputDispatchFrozen;
5733
5734 // When true, input dispatch proceeds normally. Otherwise all events are dropped.
5735 private boolean mInputDispatchEnabled = true;
5736
5737 // Temporary list of windows information to provide to the input dispatcher.
5738 private InputWindowList mTempInputWindows = new InputWindowList();
5739
5740 // Temporary input application object to provide to the input dispatcher.
5741 private InputApplication mTempInputApplication = new InputApplication();
5742
5743 /* Notifies the window manager about a broken input channel.
5744 *
5745 * Called by the InputManager.
5746 */
Jeff Brown928e0542011-01-10 11:17:36 -08005747 public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle) {
5748 if (inputWindowHandle == null) {
5749 return;
5750 }
5751
Jeff Brown349703e2010-06-22 01:27:15 -07005752 synchronized (mWindowMap) {
Jeff Brown928e0542011-01-10 11:17:36 -08005753 WindowState windowState = (WindowState) inputWindowHandle.windowState;
Jeff Brown349703e2010-06-22 01:27:15 -07005754 Slog.i(TAG, "WINDOW DIED " + windowState);
5755 removeWindowLocked(windowState.mSession, windowState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005756 }
5757 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005758
Jeff Brown519e0242010-09-15 15:18:56 -07005759 /* Notifies the window manager about an application that is not responding.
Jeff Brownb88102f2010-09-08 11:49:43 -07005760 * Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch.
Jeff Brown349703e2010-06-22 01:27:15 -07005761 *
5762 * Called by the InputManager.
5763 */
Jeff Brown928e0542011-01-10 11:17:36 -08005764 public long notifyANR(InputApplicationHandle inputApplicationHandle,
5765 InputWindowHandle inputWindowHandle) {
Jeff Brown519e0242010-09-15 15:18:56 -07005766 AppWindowToken appWindowToken = null;
Jeff Brown928e0542011-01-10 11:17:36 -08005767 if (inputWindowHandle != null) {
Jeff Brown519e0242010-09-15 15:18:56 -07005768 synchronized (mWindowMap) {
Jeff Brown928e0542011-01-10 11:17:36 -08005769 WindowState windowState = (WindowState) inputWindowHandle.windowState;
Jeff Brown519e0242010-09-15 15:18:56 -07005770 if (windowState != null) {
5771 Slog.i(TAG, "Input event dispatching timed out sending to "
5772 + windowState.mAttrs.getTitle());
5773 appWindowToken = windowState.mAppToken;
5774 }
Jeff Brown349703e2010-06-22 01:27:15 -07005775 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005776 }
5777
Jeff Brown928e0542011-01-10 11:17:36 -08005778 if (appWindowToken == null && inputApplicationHandle != null) {
5779 appWindowToken = inputApplicationHandle.appWindowToken;
Jeff Brown519e0242010-09-15 15:18:56 -07005780 Slog.i(TAG, "Input event dispatching timed out sending to application "
5781 + appWindowToken.stringName);
5782 }
Jeff Brown349703e2010-06-22 01:27:15 -07005783
Jeff Brown519e0242010-09-15 15:18:56 -07005784 if (appWindowToken != null && appWindowToken.appToken != null) {
Jeff Brown349703e2010-06-22 01:27:15 -07005785 try {
5786 // Notify the activity manager about the timeout and let it decide whether
5787 // to abort dispatching or keep waiting.
Jeff Brown519e0242010-09-15 15:18:56 -07005788 boolean abort = appWindowToken.appToken.keyDispatchingTimedOut();
Jeff Brown349703e2010-06-22 01:27:15 -07005789 if (! abort) {
5790 // The activity manager declined to abort dispatching.
5791 // Wait a bit longer and timeout again later.
Jeff Brown519e0242010-09-15 15:18:56 -07005792 return appWindowToken.inputDispatchingTimeoutNanos;
Jeff Brown7fbdc842010-06-17 20:52:56 -07005793 }
Jeff Brown349703e2010-06-22 01:27:15 -07005794 } catch (RemoteException ex) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07005795 }
5796 }
Jeff Brownb88102f2010-09-08 11:49:43 -07005797 return 0; // abort dispatching
Jeff Brown7fbdc842010-06-17 20:52:56 -07005798 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005799
Chris Tatea32dcf72010-10-14 12:13:50 -07005800 private void addDragInputWindowLw(InputWindowList windowList) {
Christopher Tatea53146c2010-09-07 11:57:52 -07005801 final InputWindow inputWindow = windowList.add();
5802 inputWindow.inputChannel = mDragState.mServerChannel;
5803 inputWindow.name = "drag";
5804 inputWindow.layoutParamsFlags = 0;
5805 inputWindow.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
5806 inputWindow.dispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
5807 inputWindow.visible = true;
5808 inputWindow.canReceiveKeys = false;
5809 inputWindow.hasFocus = true;
5810 inputWindow.hasWallpaper = false;
5811 inputWindow.paused = false;
Chris Tatea32dcf72010-10-14 12:13:50 -07005812 inputWindow.layer = mDragState.getDragLayerLw();
Christopher Tatea53146c2010-09-07 11:57:52 -07005813 inputWindow.ownerPid = Process.myPid();
5814 inputWindow.ownerUid = Process.myUid();
5815
5816 // The drag window covers the entire display
5817 inputWindow.frameLeft = 0;
5818 inputWindow.frameTop = 0;
5819 inputWindow.frameRight = mDisplay.getWidth();
5820 inputWindow.frameBottom = mDisplay.getHeight();
Christopher Tate2c095f32010-10-04 14:13:40 -07005821
Christopher Tatea53146c2010-09-07 11:57:52 -07005822 inputWindow.visibleFrameLeft = inputWindow.frameLeft;
5823 inputWindow.visibleFrameTop = inputWindow.frameTop;
5824 inputWindow.visibleFrameRight = inputWindow.frameRight;
5825 inputWindow.visibleFrameBottom = inputWindow.frameBottom;
5826
5827 inputWindow.touchableAreaLeft = inputWindow.frameLeft;
5828 inputWindow.touchableAreaTop = inputWindow.frameTop;
5829 inputWindow.touchableAreaRight = inputWindow.frameRight;
5830 inputWindow.touchableAreaBottom = inputWindow.frameBottom;
5831 }
5832
Jeff Brown349703e2010-06-22 01:27:15 -07005833 /* Updates the cached window information provided to the input dispatcher. */
5834 public void updateInputWindowsLw() {
5835 // Populate the input window list with information about all of the windows that
5836 // could potentially receive input.
5837 // As an optimization, we could try to prune the list of windows but this turns
5838 // out to be difficult because only the native code knows for sure which window
5839 // currently has touch focus.
Jeff Browne33348b2010-07-15 23:54:05 -07005840 final ArrayList<WindowState> windows = mWindows;
Christopher Tatea53146c2010-09-07 11:57:52 -07005841
5842 // If there's a drag in flight, provide a pseudowindow to catch drag input
5843 final boolean inDrag = (mDragState != null);
5844 if (inDrag) {
5845 if (DEBUG_DRAG) {
5846 Log.d(TAG, "Inserting drag window");
5847 }
Chris Tatea32dcf72010-10-14 12:13:50 -07005848 addDragInputWindowLw(mTempInputWindows);
Christopher Tatea53146c2010-09-07 11:57:52 -07005849 }
5850
Jeff Brown7fbdc842010-06-17 20:52:56 -07005851 final int N = windows.size();
Jeff Brown349703e2010-06-22 01:27:15 -07005852 for (int i = N - 1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07005853 final WindowState child = windows.get(i);
Jeff Brownc5ed5912010-07-14 18:48:53 -07005854 if (child.mInputChannel == null || child.mRemoved) {
Jeff Brown349703e2010-06-22 01:27:15 -07005855 // Skip this window because it cannot possibly receive input.
Jeff Brown7fbdc842010-06-17 20:52:56 -07005856 continue;
5857 }
5858
Jeff Brown349703e2010-06-22 01:27:15 -07005859 final int flags = child.mAttrs.flags;
5860 final int type = child.mAttrs.type;
5861
5862 final boolean hasFocus = (child == mInputFocus);
5863 final boolean isVisible = child.isVisibleLw();
5864 final boolean hasWallpaper = (child == mWallpaperTarget)
5865 && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);
Christopher Tatea53146c2010-09-07 11:57:52 -07005866
5867 // If there's a drag in progress and 'child' is a potential drop target,
5868 // make sure it's been told about the drag
5869 if (inDrag && isVisible) {
5870 mDragState.sendDragStartedIfNeededLw(child);
5871 }
5872
Jeff Brown349703e2010-06-22 01:27:15 -07005873 // Add a window to our list of input windows.
5874 final InputWindow inputWindow = mTempInputWindows.add();
Jeff Brown928e0542011-01-10 11:17:36 -08005875 inputWindow.inputWindowHandle = child.mInputWindowHandle;
Jeff Brown349703e2010-06-22 01:27:15 -07005876 inputWindow.inputChannel = child.mInputChannel;
Jeff Brown519e0242010-09-15 15:18:56 -07005877 inputWindow.name = child.toString();
Jeff Brown349703e2010-06-22 01:27:15 -07005878 inputWindow.layoutParamsFlags = flags;
5879 inputWindow.layoutParamsType = type;
5880 inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
5881 inputWindow.visible = isVisible;
Jeff Brown519e0242010-09-15 15:18:56 -07005882 inputWindow.canReceiveKeys = child.canReceiveKeys();
Jeff Brown349703e2010-06-22 01:27:15 -07005883 inputWindow.hasFocus = hasFocus;
5884 inputWindow.hasWallpaper = hasWallpaper;
5885 inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;
Jeff Brown519e0242010-09-15 15:18:56 -07005886 inputWindow.layer = child.mLayer;
Jeff Brown349703e2010-06-22 01:27:15 -07005887 inputWindow.ownerPid = child.mSession.mPid;
5888 inputWindow.ownerUid = child.mSession.mUid;
5889
5890 final Rect frame = child.mFrame;
5891 inputWindow.frameLeft = frame.left;
5892 inputWindow.frameTop = frame.top;
Jeff Brown85a31762010-09-01 17:01:00 -07005893 inputWindow.frameRight = frame.right;
5894 inputWindow.frameBottom = frame.bottom;
5895
5896 final Rect visibleFrame = child.mVisibleFrame;
5897 inputWindow.visibleFrameLeft = visibleFrame.left;
5898 inputWindow.visibleFrameTop = visibleFrame.top;
5899 inputWindow.visibleFrameRight = visibleFrame.right;
5900 inputWindow.visibleFrameBottom = visibleFrame.bottom;
Jeff Brown349703e2010-06-22 01:27:15 -07005901
5902 switch (child.mTouchableInsets) {
5903 default:
5904 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
5905 inputWindow.touchableAreaLeft = frame.left;
5906 inputWindow.touchableAreaTop = frame.top;
5907 inputWindow.touchableAreaRight = frame.right;
5908 inputWindow.touchableAreaBottom = frame.bottom;
5909 break;
5910
5911 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: {
5912 Rect inset = child.mGivenContentInsets;
5913 inputWindow.touchableAreaLeft = frame.left + inset.left;
5914 inputWindow.touchableAreaTop = frame.top + inset.top;
5915 inputWindow.touchableAreaRight = frame.right - inset.right;
5916 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
5917 break;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005918 }
Jeff Brown349703e2010-06-22 01:27:15 -07005919
5920 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: {
5921 Rect inset = child.mGivenVisibleInsets;
5922 inputWindow.touchableAreaLeft = frame.left + inset.left;
5923 inputWindow.touchableAreaTop = frame.top + inset.top;
5924 inputWindow.touchableAreaRight = frame.right - inset.right;
5925 inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005926 break;
5927 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005928 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005929 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07005930
Jeff Brown349703e2010-06-22 01:27:15 -07005931 // Send windows to native code.
5932 mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005933
Jeff Brown349703e2010-06-22 01:27:15 -07005934 // Clear the list in preparation for the next round.
5935 // Also avoids keeping InputChannel objects referenced unnecessarily.
5936 mTempInputWindows.clear();
5937 }
5938
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005939 /* Notifies that the lid switch changed state. */
5940 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
5941 mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
5942 }
5943
Jeff Brown349703e2010-06-22 01:27:15 -07005944 /* Provides an opportunity for the window manager policy to intercept early key
5945 * processing as soon as the key has been read from the device. */
Jeff Brown1f245102010-11-18 20:53:46 -08005946 public int interceptKeyBeforeQueueing(
5947 KeyEvent event, int policyFlags, boolean isScreenOn) {
5948 return mPolicy.interceptKeyBeforeQueueing(event, policyFlags, isScreenOn);
Jeff Brown349703e2010-06-22 01:27:15 -07005949 }
5950
5951 /* Provides an opportunity for the window manager policy to process a key before
5952 * ordinary dispatch. */
Jeff Brown1f245102010-11-18 20:53:46 -08005953 public boolean interceptKeyBeforeDispatching(
Jeff Brown928e0542011-01-10 11:17:36 -08005954 InputWindowHandle focus, KeyEvent event, int policyFlags) {
5955 WindowState windowState = (WindowState) focus.windowState;
Jeff Brown1f245102010-11-18 20:53:46 -08005956 return mPolicy.interceptKeyBeforeDispatching(windowState, event, policyFlags);
Jeff Brown349703e2010-06-22 01:27:15 -07005957 }
5958
Jeff Brown3915bb82010-11-05 15:02:16 -07005959 /* Provides an opportunity for the window manager policy to process a key that
5960 * the application did not handle. */
Jeff Brown49ed71d2010-12-06 17:13:33 -08005961 public KeyEvent dispatchUnhandledKey(
Jeff Brown928e0542011-01-10 11:17:36 -08005962 InputWindowHandle focus, KeyEvent event, int policyFlags) {
5963 WindowState windowState = (WindowState) focus.windowState;
Jeff Brown1f245102010-11-18 20:53:46 -08005964 return mPolicy.dispatchUnhandledKey(windowState, event, policyFlags);
Jeff Brown3915bb82010-11-05 15:02:16 -07005965 }
5966
Jeff Brown349703e2010-06-22 01:27:15 -07005967 /* Called when the current input focus changes.
5968 * Layer assignment is assumed to be complete by the time this is called.
5969 */
5970 public void setInputFocusLw(WindowState newWindow) {
5971 if (DEBUG_INPUT) {
5972 Slog.d(TAG, "Input focus has changed to " + newWindow);
5973 }
5974
5975 if (newWindow != mInputFocus) {
5976 if (newWindow != null && newWindow.canReceiveKeys()) {
Jeff Brown349703e2010-06-22 01:27:15 -07005977 // Displaying a window implicitly causes dispatching to be unpaused.
5978 // This is to protect against bugs if someone pauses dispatching but
5979 // forgets to resume.
5980 newWindow.mToken.paused = false;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005981 }
Jeff Brown349703e2010-06-22 01:27:15 -07005982
5983 mInputFocus = newWindow;
5984 updateInputWindowsLw();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07005985 }
5986 }
5987
Jeff Brown349703e2010-06-22 01:27:15 -07005988 public void setFocusedAppLw(AppWindowToken newApp) {
5989 // Focused app has changed.
5990 if (newApp == null) {
5991 mInputManager.setFocusedApplication(null);
5992 } else {
Jeff Brown928e0542011-01-10 11:17:36 -08005993 mTempInputApplication.inputApplicationHandle = newApp.mInputApplicationHandle;
Jeff Brown349703e2010-06-22 01:27:15 -07005994 mTempInputApplication.name = newApp.toString();
5995 mTempInputApplication.dispatchingTimeoutNanos =
5996 newApp.inputDispatchingTimeoutNanos;
Jeff Brown928e0542011-01-10 11:17:36 -08005997
Jeff Brown349703e2010-06-22 01:27:15 -07005998 mInputManager.setFocusedApplication(mTempInputApplication);
Jeff Brown928e0542011-01-10 11:17:36 -08005999
6000 mTempInputApplication.recycle();
Jeff Brown349703e2010-06-22 01:27:15 -07006001 }
6002 }
6003
Jeff Brown349703e2010-06-22 01:27:15 -07006004 public void pauseDispatchingLw(WindowToken window) {
6005 if (! window.paused) {
6006 if (DEBUG_INPUT) {
6007 Slog.v(TAG, "Pausing WindowToken " + window);
6008 }
6009
6010 window.paused = true;
6011 updateInputWindowsLw();
6012 }
6013 }
6014
6015 public void resumeDispatchingLw(WindowToken window) {
6016 if (window.paused) {
6017 if (DEBUG_INPUT) {
6018 Slog.v(TAG, "Resuming WindowToken " + window);
6019 }
6020
6021 window.paused = false;
6022 updateInputWindowsLw();
6023 }
6024 }
6025
6026 public void freezeInputDispatchingLw() {
6027 if (! mInputDispatchFrozen) {
6028 if (DEBUG_INPUT) {
6029 Slog.v(TAG, "Freezing input dispatching");
6030 }
6031
6032 mInputDispatchFrozen = true;
6033 updateInputDispatchModeLw();
6034 }
6035 }
6036
6037 public void thawInputDispatchingLw() {
6038 if (mInputDispatchFrozen) {
6039 if (DEBUG_INPUT) {
6040 Slog.v(TAG, "Thawing input dispatching");
6041 }
6042
6043 mInputDispatchFrozen = false;
6044 updateInputDispatchModeLw();
6045 }
6046 }
6047
6048 public void setEventDispatchingLw(boolean enabled) {
6049 if (mInputDispatchEnabled != enabled) {
6050 if (DEBUG_INPUT) {
6051 Slog.v(TAG, "Setting event dispatching to " + enabled);
6052 }
6053
6054 mInputDispatchEnabled = enabled;
6055 updateInputDispatchModeLw();
6056 }
6057 }
6058
6059 private void updateInputDispatchModeLw() {
6060 mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
6061 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006062 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006063
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006064 public void pauseKeyDispatching(IBinder _token) {
6065 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6066 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006067 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006068 }
6069
6070 synchronized (mWindowMap) {
6071 WindowToken token = mTokenMap.get(_token);
6072 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006073 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006074 }
6075 }
6076 }
6077
6078 public void resumeKeyDispatching(IBinder _token) {
6079 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6080 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006081 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006082 }
6083
6084 synchronized (mWindowMap) {
6085 WindowToken token = mTokenMap.get(_token);
6086 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006087 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006088 }
6089 }
6090 }
6091
6092 public void setEventDispatching(boolean enabled) {
6093 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6094 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07006095 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006096 }
6097
6098 synchronized (mWindowMap) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006099 mInputMonitor.setEventDispatchingLw(enabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006100 }
6101 }
Romain Guy06882f82009-06-10 13:36:04 -07006102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006103 /**
6104 * Injects a keystroke event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07006105 * Even when sync is false, this method may block while waiting for current
6106 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07006107 *
6108 * @param ev A motion event describing the keystroke action. (Be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006109 * {@link SystemClock#uptimeMillis()} as the timebase.)
6110 * @param sync If true, wait for the event to be completed before returning to the caller.
6111 * @return Returns true if event was dispatched, false if it was dropped for any reason
6112 */
6113 public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
6114 long downTime = ev.getDownTime();
6115 long eventTime = ev.getEventTime();
6116
6117 int action = ev.getAction();
6118 int code = ev.getKeyCode();
6119 int repeatCount = ev.getRepeatCount();
6120 int metaState = ev.getMetaState();
6121 int deviceId = ev.getDeviceId();
6122 int scancode = ev.getScanCode();
Jeff Brownc5ed5912010-07-14 18:48:53 -07006123 int source = ev.getSource();
Mike Playlec6ded102010-11-29 16:01:03 +00006124 int flags = ev.getFlags();
Jeff Brownc5ed5912010-07-14 18:48:53 -07006125
6126 if (source == InputDevice.SOURCE_UNKNOWN) {
6127 source = InputDevice.SOURCE_KEYBOARD;
6128 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006129
6130 if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
6131 if (downTime == 0) downTime = eventTime;
6132
6133 KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
Jean-Baptiste Queru4a880132010-12-02 15:16:53 -08006134 deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006135
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006136 final int pid = Binder.getCallingPid();
6137 final int uid = Binder.getCallingUid();
6138 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006139
Jeff Brownbbda99d2010-07-28 15:48:59 -07006140 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
6141 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
6142 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
6143 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006144
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006145 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006146 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006147 }
6148
6149 /**
6150 * Inject a pointer (touch) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07006151 * Even when sync is false, this method may block while waiting for current
6152 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07006153 *
6154 * @param ev A motion event describing the pointer (touch) action. (As noted in
6155 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006156 * {@link SystemClock#uptimeMillis()} as the timebase.)
6157 * @param sync If true, wait for the event to be completed before returning to the caller.
6158 * @return Returns true if event was dispatched, false if it was dropped for any reason
6159 */
6160 public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006161 final int pid = Binder.getCallingPid();
6162 final int uid = Binder.getCallingUid();
6163 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006164
Jeff Brownc5ed5912010-07-14 18:48:53 -07006165 MotionEvent newEvent = MotionEvent.obtain(ev);
6166 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
6167 newEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
6168 }
6169
Jeff Brownbbda99d2010-07-28 15:48:59 -07006170 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
6171 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
6172 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
6173 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006174
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006175 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006176 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006177 }
Romain Guy06882f82009-06-10 13:36:04 -07006178
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006179 /**
6180 * Inject a trackball (navigation device) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07006181 * Even when sync is false, this method may block while waiting for current
6182 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07006183 *
6184 * @param ev A motion event describing the trackball action. (As noted in
6185 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006186 * {@link SystemClock#uptimeMillis()} as the timebase.)
6187 * @param sync If true, wait for the event to be completed before returning to the caller.
6188 * @return Returns true if event was dispatched, false if it was dropped for any reason
6189 */
6190 public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006191 final int pid = Binder.getCallingPid();
6192 final int uid = Binder.getCallingUid();
6193 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006194
Jeff Brownc5ed5912010-07-14 18:48:53 -07006195 MotionEvent newEvent = MotionEvent.obtain(ev);
6196 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
6197 newEvent.setSource(InputDevice.SOURCE_TRACKBALL);
6198 }
6199
Jeff Brownbbda99d2010-07-28 15:48:59 -07006200 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
6201 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
6202 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
6203 INJECTION_TIMEOUT_MILLIS);
6204
6205 Binder.restoreCallingIdentity(ident);
6206 return reportInjectionResult(result);
6207 }
6208
6209 /**
6210 * Inject an input event into the UI without waiting for dispatch to commence.
6211 * This variant is useful for fire-and-forget input event injection. It does not
6212 * block any longer than it takes to enqueue the input event.
6213 *
6214 * @param ev An input event. (Be sure to set the input source correctly.)
6215 * @return Returns true if event was dispatched, false if it was dropped for any reason
6216 */
6217 public boolean injectInputEventNoWait(InputEvent ev) {
6218 final int pid = Binder.getCallingPid();
6219 final int uid = Binder.getCallingUid();
6220 final long ident = Binder.clearCallingIdentity();
6221
6222 final int result = mInputManager.injectInputEvent(ev, pid, uid,
6223 InputManager.INPUT_EVENT_INJECTION_SYNC_NONE,
6224 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006225
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07006226 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07006227 return reportInjectionResult(result);
6228 }
6229
6230 private boolean reportInjectionResult(int result) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006231 switch (result) {
6232 case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
6233 Slog.w(TAG, "Input event injection permission denied.");
6234 throw new SecurityException(
6235 "Injecting to another application requires INJECT_EVENTS permission");
6236 case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
Christopher Tate09e85dc2010-08-02 11:54:41 -07006237 //Slog.v(TAG, "Input event injection succeeded.");
Jeff Brown00fa7bd2010-07-02 15:37:36 -07006238 return true;
6239 case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
6240 Slog.w(TAG, "Input event injection timed out.");
6241 return false;
6242 case InputManager.INPUT_EVENT_INJECTION_FAILED:
6243 default:
6244 Slog.w(TAG, "Input event injection failed.");
6245 return false;
Dianne Hackborncfaef692009-06-15 14:24:44 -07006246 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006247 }
Romain Guy06882f82009-06-10 13:36:04 -07006248
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006249 private WindowState getFocusedWindow() {
6250 synchronized (mWindowMap) {
6251 return getFocusedWindowLocked();
6252 }
6253 }
6254
6255 private WindowState getFocusedWindowLocked() {
6256 return mCurrentFocus;
6257 }
Romain Guy06882f82009-06-10 13:36:04 -07006258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006259 public boolean detectSafeMode() {
6260 mSafeMode = mPolicy.detectSafeMode();
6261 return mSafeMode;
6262 }
Romain Guy06882f82009-06-10 13:36:04 -07006263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006264 public void systemReady() {
Dianne Hackborn5132b372010-07-29 12:51:35 -07006265 synchronized(mWindowMap) {
6266 if (mDisplay != null) {
6267 throw new IllegalStateException("Display already initialized");
6268 }
6269 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
6270 mDisplay = wm.getDefaultDisplay();
6271 mInitialDisplayWidth = mDisplay.getWidth();
6272 mInitialDisplayHeight = mDisplay.getHeight();
Dianne Hackborn4c7cc342010-12-16 16:37:39 -08006273 mInputManager.setDisplaySize(0, Display.unmapDisplaySize(mInitialDisplayWidth),
6274 Display.unmapDisplaySize(mInitialDisplayHeight));
Dianne Hackborn5132b372010-07-29 12:51:35 -07006275 }
6276
6277 try {
6278 mActivityManager.updateConfiguration(null);
6279 } catch (RemoteException e) {
6280 }
Dianne Hackborn154db5f2010-07-29 19:15:19 -07006281
6282 mPolicy.systemReady();
Dianne Hackborn5132b372010-07-29 12:51:35 -07006283 }
6284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006285 // -------------------------------------------------------------
6286 // Client Session State
6287 // -------------------------------------------------------------
6288
6289 private final class Session extends IWindowSession.Stub
6290 implements IBinder.DeathRecipient {
6291 final IInputMethodClient mClient;
6292 final IInputContext mInputContext;
6293 final int mUid;
6294 final int mPid;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006295 final String mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006296 SurfaceSession mSurfaceSession;
6297 int mNumWindow = 0;
6298 boolean mClientDead = false;
Romain Guy06882f82009-06-10 13:36:04 -07006299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006300 public Session(IInputMethodClient client, IInputContext inputContext) {
6301 mClient = client;
6302 mInputContext = inputContext;
6303 mUid = Binder.getCallingUid();
6304 mPid = Binder.getCallingPid();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006305 StringBuilder sb = new StringBuilder();
6306 sb.append("Session{");
6307 sb.append(Integer.toHexString(System.identityHashCode(this)));
6308 sb.append(" uid ");
6309 sb.append(mUid);
6310 sb.append("}");
6311 mStringName = sb.toString();
Romain Guy06882f82009-06-10 13:36:04 -07006312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006313 synchronized (mWindowMap) {
6314 if (mInputMethodManager == null && mHaveInputMethods) {
6315 IBinder b = ServiceManager.getService(
6316 Context.INPUT_METHOD_SERVICE);
6317 mInputMethodManager = IInputMethodManager.Stub.asInterface(b);
6318 }
6319 }
6320 long ident = Binder.clearCallingIdentity();
6321 try {
6322 // Note: it is safe to call in to the input method manager
6323 // here because we are not holding our lock.
6324 if (mInputMethodManager != null) {
6325 mInputMethodManager.addClient(client, inputContext,
6326 mUid, mPid);
6327 } else {
6328 client.setUsingInputMethod(false);
6329 }
6330 client.asBinder().linkToDeath(this, 0);
6331 } catch (RemoteException e) {
6332 // The caller has died, so we can just forget about this.
6333 try {
6334 if (mInputMethodManager != null) {
6335 mInputMethodManager.removeClient(client);
6336 }
6337 } catch (RemoteException ee) {
6338 }
6339 } finally {
6340 Binder.restoreCallingIdentity(ident);
6341 }
6342 }
Romain Guy06882f82009-06-10 13:36:04 -07006343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006344 @Override
6345 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
6346 throws RemoteException {
6347 try {
6348 return super.onTransact(code, data, reply, flags);
6349 } catch (RuntimeException e) {
6350 // Log all 'real' exceptions thrown to the caller
6351 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006352 Slog.e(TAG, "Window Session Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006353 }
6354 throw e;
6355 }
6356 }
6357
6358 public void binderDied() {
6359 // Note: it is safe to call in to the input method manager
6360 // here because we are not holding our lock.
6361 try {
6362 if (mInputMethodManager != null) {
6363 mInputMethodManager.removeClient(mClient);
6364 }
6365 } catch (RemoteException e) {
6366 }
6367 synchronized(mWindowMap) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07006368 mClient.asBinder().unlinkToDeath(this, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006369 mClientDead = true;
6370 killSessionLocked();
6371 }
6372 }
6373
6374 public int add(IWindow window, WindowManager.LayoutParams attrs,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006375 int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
6376 return addWindow(this, window, attrs, viewVisibility, outContentInsets,
6377 outInputChannel);
6378 }
6379
6380 public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006381 int viewVisibility, Rect outContentInsets) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006382 return addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006383 }
Romain Guy06882f82009-06-10 13:36:04 -07006384
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006385 public void remove(IWindow window) {
6386 removeWindow(this, window);
6387 }
Romain Guy06882f82009-06-10 13:36:04 -07006388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006389 public int relayout(IWindow window, WindowManager.LayoutParams attrs,
6390 int requestedWidth, int requestedHeight, int viewFlags,
6391 boolean insetsPending, Rect outFrame, Rect outContentInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07006392 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
Dianne Hackbornf123e492010-09-24 11:16:23 -07006393 //Log.d(TAG, ">>>>>> ENTERED relayout from " + Binder.getCallingPid());
6394 int res = relayoutWindow(this, window, attrs,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006395 requestedWidth, requestedHeight, viewFlags, insetsPending,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07006396 outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
Dianne Hackbornf123e492010-09-24 11:16:23 -07006397 //Log.d(TAG, "<<<<<< EXITING relayout to " + Binder.getCallingPid());
6398 return res;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006399 }
Romain Guy06882f82009-06-10 13:36:04 -07006400
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006401 public void setTransparentRegion(IWindow window, Region region) {
6402 setTransparentRegionWindow(this, window, region);
6403 }
Romain Guy06882f82009-06-10 13:36:04 -07006404
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006405 public void setInsets(IWindow window, int touchableInsets,
6406 Rect contentInsets, Rect visibleInsets) {
6407 setInsetsWindow(this, window, touchableInsets, contentInsets,
6408 visibleInsets);
6409 }
Romain Guy06882f82009-06-10 13:36:04 -07006410
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006411 public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
6412 getWindowDisplayFrame(this, window, outDisplayFrame);
6413 }
Romain Guy06882f82009-06-10 13:36:04 -07006414
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006415 public void finishDrawing(IWindow window) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006416 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006417 TAG, "IWindow finishDrawing called for " + window);
6418 finishDrawingWindow(this, window);
6419 }
6420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006421 public void setInTouchMode(boolean mode) {
6422 synchronized(mWindowMap) {
6423 mInTouchMode = mode;
6424 }
6425 }
6426
6427 public boolean getInTouchMode() {
6428 synchronized(mWindowMap) {
6429 return mInTouchMode;
6430 }
6431 }
6432
6433 public boolean performHapticFeedback(IWindow window, int effectId,
6434 boolean always) {
6435 synchronized(mWindowMap) {
6436 long ident = Binder.clearCallingIdentity();
6437 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07006438 return mPolicy.performHapticFeedbackLw(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006439 windowForClientLocked(this, window, true),
6440 effectId, always);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006441 } finally {
6442 Binder.restoreCallingIdentity(ident);
6443 }
6444 }
6445 }
Romain Guy06882f82009-06-10 13:36:04 -07006446
Christopher Tatea53146c2010-09-07 11:57:52 -07006447 /* Drag/drop */
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006448 public IBinder prepareDrag(IWindow window, int flags,
Christopher Tatea53146c2010-09-07 11:57:52 -07006449 int width, int height, Surface outSurface) {
Christopher Tate02d2b3b2011-01-10 20:43:53 -08006450 return prepareDragSurface(window, mSurfaceSession, flags,
Christopher Tatea53146c2010-09-07 11:57:52 -07006451 width, height, outSurface);
6452 }
6453
6454 public boolean performDrag(IWindow window, IBinder dragToken,
6455 float touchX, float touchY, float thumbCenterX, float thumbCenterY,
6456 ClipData data) {
6457 if (DEBUG_DRAG) {
6458 Slog.d(TAG, "perform drag: win=" + window + " data=" + data);
6459 }
6460
6461 synchronized (mWindowMap) {
6462 if (mDragState == null) {
6463 Slog.w(TAG, "No drag prepared");
6464 throw new IllegalStateException("performDrag() without prepareDrag()");
6465 }
6466
6467 if (dragToken != mDragState.mToken) {
6468 Slog.w(TAG, "Performing mismatched drag");
6469 throw new IllegalStateException("performDrag() does not match prepareDrag()");
6470 }
6471
6472 WindowState callingWin = windowForClientLocked(null, window, false);
6473 if (callingWin == null) {
6474 Slog.w(TAG, "Bad requesting window " + window);
6475 return false; // !!! TODO: throw here?
6476 }
6477
6478 // !!! TODO: if input is not still focused on the initiating window, fail
6479 // the drag initiation (e.g. an alarm window popped up just as the application
6480 // called performDrag()
6481
6482 mH.removeMessages(H.DRAG_START_TIMEOUT, window.asBinder());
6483
Christopher Tate2c095f32010-10-04 14:13:40 -07006484 // !!! TODO: extract the current touch (x, y) in screen coordinates. That
6485 // will let us eliminate the (touchX,touchY) parameters from the API.
Christopher Tatea53146c2010-09-07 11:57:52 -07006486
Chris Tateb478f462010-10-15 16:02:26 -07006487 // !!! FIXME: put all this heavy stuff onto the mH looper, as well as
6488 // the actual drag event dispatch stuff in the dragstate
6489
Christopher Tatea53146c2010-09-07 11:57:52 -07006490 mDragState.register();
6491 mInputMonitor.updateInputWindowsLw();
Chris Tateef70a072010-10-22 19:10:34 -07006492 if (!mInputManager.transferTouchFocus(callingWin.mInputChannel,
6493 mDragState.mServerChannel)) {
6494 Slog.e(TAG, "Unable to transfer touch focus");
6495 mDragState.unregister();
6496 mDragState = null;
6497 mInputMonitor.updateInputWindowsLw();
6498 return false;
6499 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006500
6501 mDragState.mData = data;
Chris Tateb478f462010-10-15 16:02:26 -07006502 mDragState.mCurrentX = touchX;
6503 mDragState.mCurrentY = touchY;
Chris Tateb8203e92010-10-12 14:23:21 -07006504 mDragState.broadcastDragStartedLw(touchX, touchY);
Christopher Tatea53146c2010-09-07 11:57:52 -07006505
6506 // remember the thumb offsets for later
6507 mDragState.mThumbOffsetX = thumbCenterX;
6508 mDragState.mThumbOffsetY = thumbCenterY;
6509
6510 // Make the surface visible at the proper location
6511 final Surface surface = mDragState.mSurface;
Chris Tateb478f462010-10-15 16:02:26 -07006512 Surface.openTransaction();
Christopher Tatea53146c2010-09-07 11:57:52 -07006513 try {
6514 surface.setPosition((int)(touchX - thumbCenterX),
6515 (int)(touchY - thumbCenterY));
Chris Tateb478f462010-10-15 16:02:26 -07006516 surface.setAlpha(.7071f);
Chris Tatea32dcf72010-10-14 12:13:50 -07006517 surface.setLayer(mDragState.getDragLayerLw());
Christopher Tatea53146c2010-09-07 11:57:52 -07006518 surface.show();
6519 } finally {
Chris Tateb478f462010-10-15 16:02:26 -07006520 Surface.closeTransaction();
Christopher Tatea53146c2010-09-07 11:57:52 -07006521 }
6522 }
6523
6524 return true; // success!
6525 }
6526
Chris Tated4533f142010-10-19 15:15:08 -07006527 public void reportDropResult(IWindow window, boolean consumed) {
6528 IBinder token = window.asBinder();
6529 if (DEBUG_DRAG) {
6530 Slog.d(TAG, "Drop result=" + consumed + " reported by " + token);
6531 }
6532
6533 synchronized (mWindowMap) {
Christopher Tateccd24de2011-01-12 15:02:55 -08006534 long ident = Binder.clearCallingIdentity();
6535 try {
6536 if (mDragState.mToken != token) {
6537 Slog.w(TAG, "Invalid drop-result claim by " + window);
6538 throw new IllegalStateException("reportDropResult() by non-recipient");
6539 }
6540
6541 // The right window has responded, even if it's no longer around,
6542 // so be sure to halt the timeout even if the later WindowState
6543 // lookup fails.
6544 mH.removeMessages(H.DRAG_END_TIMEOUT, window.asBinder());
6545 WindowState callingWin = windowForClientLocked(null, window, false);
6546 if (callingWin == null) {
6547 Slog.w(TAG, "Bad result-reporting window " + window);
6548 return; // !!! TODO: throw here?
6549 }
6550
6551 mDragState.mDragResult = consumed;
6552 mDragState.endDragLw();
6553 } finally {
6554 Binder.restoreCallingIdentity(ident);
Chris Tated4533f142010-10-19 15:15:08 -07006555 }
Chris Tated4533f142010-10-19 15:15:08 -07006556 }
6557 }
6558
Christopher Tatea53146c2010-09-07 11:57:52 -07006559 public void dragRecipientEntered(IWindow window) {
6560 if (DEBUG_DRAG) {
Chris Tated4533f142010-10-19 15:15:08 -07006561 Slog.d(TAG, "Drag into new candidate view @ " + window.asBinder());
Christopher Tatea53146c2010-09-07 11:57:52 -07006562 }
6563 }
6564
6565 public void dragRecipientExited(IWindow window) {
6566 if (DEBUG_DRAG) {
Chris Tated4533f142010-10-19 15:15:08 -07006567 Slog.d(TAG, "Drag from old candidate view @ " + window.asBinder());
Christopher Tatea53146c2010-09-07 11:57:52 -07006568 }
6569 }
6570
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006571 public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006572 synchronized(mWindowMap) {
6573 long ident = Binder.clearCallingIdentity();
6574 try {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006575 setWindowWallpaperPositionLocked(
6576 windowForClientLocked(this, window, true),
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006577 x, y, xStep, yStep);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006578 } finally {
6579 Binder.restoreCallingIdentity(ident);
6580 }
6581 }
6582 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006583
Dianne Hackborn19382ac2009-09-11 21:13:37 -07006584 public void wallpaperOffsetsComplete(IBinder window) {
6585 WindowManagerService.this.wallpaperOffsetsComplete(window);
6586 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006587
Dianne Hackborn75804932009-10-20 20:15:20 -07006588 public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
6589 int z, Bundle extras, boolean sync) {
6590 synchronized(mWindowMap) {
6591 long ident = Binder.clearCallingIdentity();
6592 try {
6593 return sendWindowWallpaperCommandLocked(
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006594 windowForClientLocked(this, window, true),
Dianne Hackborn75804932009-10-20 20:15:20 -07006595 action, x, y, z, extras, sync);
6596 } finally {
6597 Binder.restoreCallingIdentity(ident);
6598 }
6599 }
6600 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006601
Dianne Hackborn75804932009-10-20 20:15:20 -07006602 public void wallpaperCommandComplete(IBinder window, Bundle result) {
6603 WindowManagerService.this.wallpaperCommandComplete(window, result);
6604 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006606 void windowAddedLocked() {
6607 if (mSurfaceSession == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006608 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006609 TAG, "First window added to " + this + ", creating SurfaceSession");
6610 mSurfaceSession = new SurfaceSession();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006611 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006612 TAG, " NEW SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006613 mSessions.add(this);
6614 }
6615 mNumWindow++;
6616 }
6617
6618 void windowRemovedLocked() {
6619 mNumWindow--;
6620 killSessionLocked();
6621 }
Romain Guy06882f82009-06-10 13:36:04 -07006622
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006623 void killSessionLocked() {
6624 if (mNumWindow <= 0 && mClientDead) {
6625 mSessions.remove(this);
6626 if (mSurfaceSession != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006627 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006628 TAG, "Last window removed from " + this
6629 + ", destroying " + mSurfaceSession);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006630 if (SHOW_TRANSACTIONS) Slog.i(
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006631 TAG, " KILL SURFACE SESSION " + mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006632 try {
6633 mSurfaceSession.kill();
6634 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006635 Slog.w(TAG, "Exception thrown when killing surface session "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006636 + mSurfaceSession + " in session " + this
6637 + ": " + e.toString());
6638 }
6639 mSurfaceSession = null;
6640 }
6641 }
6642 }
Romain Guy06882f82009-06-10 13:36:04 -07006643
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006644 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006645 pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
6646 pw.print(" mClientDead="); pw.print(mClientDead);
6647 pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006648 }
6649
6650 @Override
6651 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006652 return mStringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006653 }
6654 }
6655
6656 // -------------------------------------------------------------
6657 // Client Window State
6658 // -------------------------------------------------------------
6659
6660 private final class WindowState implements WindowManagerPolicy.WindowState {
6661 final Session mSession;
6662 final IWindow mClient;
6663 WindowToken mToken;
The Android Open Source Project10592532009-03-18 17:39:46 -07006664 WindowToken mRootToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006665 AppWindowToken mAppToken;
6666 AppWindowToken mTargetAppToken;
6667 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
6668 final DeathRecipient mDeathRecipient;
6669 final WindowState mAttachedWindow;
Jeff Browne33348b2010-07-15 23:54:05 -07006670 final ArrayList<WindowState> mChildWindows = new ArrayList<WindowState>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006671 final int mBaseLayer;
6672 final int mSubLayer;
6673 final boolean mLayoutAttached;
6674 final boolean mIsImWindow;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006675 final boolean mIsWallpaper;
6676 final boolean mIsFloatingLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006677 int mViewVisibility;
6678 boolean mPolicyVisibility = true;
6679 boolean mPolicyVisibilityAfterAnim = true;
6680 boolean mAppFreezing;
6681 Surface mSurface;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006682 boolean mReportDestroySurface;
6683 boolean mSurfacePendingDestroy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006684 boolean mAttachedHidden; // is our parent window hidden?
6685 boolean mLastHidden; // was this window last hidden?
Dianne Hackborn759a39e2009-08-09 17:20:27 -07006686 boolean mWallpaperVisible; // for wallpaper, what was last vis report?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006687 int mRequestedWidth;
6688 int mRequestedHeight;
6689 int mLastRequestedWidth;
6690 int mLastRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006691 int mLayer;
6692 int mAnimLayer;
6693 int mLastLayer;
6694 boolean mHaveFrame;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07006695 boolean mObscured;
Dianne Hackborn93e462b2009-09-15 22:50:40 -07006696 boolean mTurnOnScreen;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006697
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006698 int mLayoutSeq = -1;
6699
6700 Configuration mConfiguration = null;
6701
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006702 // Actual frame shown on-screen (may be modified by animation)
6703 final Rect mShownFrame = new Rect();
6704 final Rect mLastShownFrame = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006705
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006706 /**
Dianne Hackbornac3587d2010-03-11 11:12:11 -08006707 * Set when we have changed the size of the surface, to know that
6708 * we must tell them application to resize (and thus redraw itself).
6709 */
6710 boolean mSurfaceResized;
6711
6712 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006713 * Insets that determine the actually visible area
6714 */
6715 final Rect mVisibleInsets = new Rect();
6716 final Rect mLastVisibleInsets = new Rect();
6717 boolean mVisibleInsetsChanged;
6718
6719 /**
6720 * Insets that are covered by system windows
6721 */
6722 final Rect mContentInsets = new Rect();
6723 final Rect mLastContentInsets = new Rect();
6724 boolean mContentInsetsChanged;
6725
6726 /**
6727 * Set to true if we are waiting for this window to receive its
6728 * given internal insets before laying out other windows based on it.
6729 */
6730 boolean mGivenInsetsPending;
Romain Guy06882f82009-06-10 13:36:04 -07006731
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006732 /**
6733 * These are the content insets that were given during layout for
6734 * this window, to be applied to windows behind it.
6735 */
6736 final Rect mGivenContentInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006737
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006738 /**
6739 * These are the visible insets that were given during layout for
6740 * this window, to be applied to windows behind it.
6741 */
6742 final Rect mGivenVisibleInsets = new Rect();
Romain Guy06882f82009-06-10 13:36:04 -07006743
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006744 /**
6745 * Flag indicating whether the touchable region should be adjusted by
6746 * the visible insets; if false the area outside the visible insets is
6747 * NOT touchable, so we must use those to adjust the frame during hit
6748 * tests.
6749 */
6750 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
Romain Guy06882f82009-06-10 13:36:04 -07006751
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006752 // Current transformation being applied.
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08006753 boolean mHaveMatrix;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006754 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
6755 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
6756 float mHScale=1, mVScale=1;
6757 float mLastHScale=1, mLastVScale=1;
6758 final Matrix mTmpMatrix = new Matrix();
6759
6760 // "Real" frame that the application sees.
6761 final Rect mFrame = new Rect();
6762 final Rect mLastFrame = new Rect();
6763
6764 final Rect mContainingFrame = new Rect();
6765 final Rect mDisplayFrame = new Rect();
6766 final Rect mContentFrame = new Rect();
Dianne Hackborn1c24e952010-11-23 00:34:30 -08006767 final Rect mParentFrame = new Rect();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006768 final Rect mVisibleFrame = new Rect();
6769
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08006770 boolean mContentChanged;
6771
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006772 float mShownAlpha = 1;
6773 float mAlpha = 1;
6774 float mLastAlpha = 1;
6775
6776 // Set to true if, when the window gets displayed, it should perform
6777 // an enter animation.
6778 boolean mEnterAnimationPending;
6779
6780 // Currently running animation.
6781 boolean mAnimating;
6782 boolean mLocalAnimating;
6783 Animation mAnimation;
6784 boolean mAnimationIsEntrance;
6785 boolean mHasTransformation;
6786 boolean mHasLocalTransformation;
6787 final Transformation mTransformation = new Transformation();
6788
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07006789 // If a window showing a wallpaper: the requested offset for the
6790 // wallpaper; if a wallpaper window: the currently applied offset.
6791 float mWallpaperX = -1;
6792 float mWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08006793
6794 // If a window showing a wallpaper: what fraction of the offset
6795 // range corresponds to a full virtual screen.
6796 float mWallpaperXStep = -1;
6797 float mWallpaperYStep = -1;
6798
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07006799 // Wallpaper windows: pixels offset based on above variables.
6800 int mXOffset;
6801 int mYOffset;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006802
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006803 // This is set after IWindowSession.relayout() has been called at
6804 // least once for the window. It allows us to detect the situation
6805 // where we don't yet have a surface, but should have one soon, so
6806 // we can give the window focus before waiting for the relayout.
6807 boolean mRelayoutCalled;
Romain Guy06882f82009-06-10 13:36:04 -07006808
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006809 // This is set after the Surface has been created but before the
6810 // window has been drawn. During this time the surface is hidden.
6811 boolean mDrawPending;
6812
6813 // This is set after the window has finished drawing for the first
6814 // time but before its surface is shown. The surface will be
6815 // displayed when the next layout is run.
6816 boolean mCommitDrawPending;
6817
6818 // This is set during the time after the window's drawing has been
6819 // committed, and before its surface is actually shown. It is used
6820 // to delay showing the surface until all windows in a token are ready
6821 // to be shown.
6822 boolean mReadyToShow;
Romain Guy06882f82009-06-10 13:36:04 -07006823
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006824 // Set when the window has been shown in the screen the first time.
6825 boolean mHasDrawn;
6826
6827 // Currently running an exit animation?
6828 boolean mExiting;
6829
6830 // Currently on the mDestroySurface list?
6831 boolean mDestroying;
Romain Guy06882f82009-06-10 13:36:04 -07006832
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006833 // Completely remove from window manager after exit animation?
6834 boolean mRemoveOnExit;
6835
6836 // Set when the orientation is changing and this window has not yet
6837 // been updated for the new orientation.
6838 boolean mOrientationChanging;
Romain Guy06882f82009-06-10 13:36:04 -07006839
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006840 // Is this window now (or just being) removed?
6841 boolean mRemoved;
Romain Guy06882f82009-06-10 13:36:04 -07006842
Dianne Hackborn16064f92010-03-25 00:47:24 -07006843 // For debugging, this is the last information given to the surface flinger.
6844 boolean mSurfaceShown;
6845 int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
6846 int mSurfaceLayer;
6847 float mSurfaceAlpha;
6848
Jeff Brown928e0542011-01-10 11:17:36 -08006849 // Input channel and input window handle used by the input dispatcher.
6850 InputWindowHandle mInputWindowHandle;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07006851 InputChannel mInputChannel;
6852
Mattias Petersson1622eee2010-12-21 10:15:11 +01006853 // Used to improve performance of toString()
6854 String mStringNameCache;
6855 CharSequence mLastTitle;
6856 boolean mWasPaused;
6857
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006858 WindowState(Session s, IWindow c, WindowToken token,
6859 WindowState attachedWindow, WindowManager.LayoutParams a,
6860 int viewVisibility) {
6861 mSession = s;
6862 mClient = c;
6863 mToken = token;
6864 mAttrs.copyFrom(a);
6865 mViewVisibility = viewVisibility;
6866 DeathRecipient deathRecipient = new DeathRecipient();
6867 mAlpha = a.alpha;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006868 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006869 TAG, "Window " + this + " client=" + c.asBinder()
6870 + " token=" + token + " (" + mAttrs.token + ")");
6871 try {
6872 c.asBinder().linkToDeath(deathRecipient, 0);
6873 } catch (RemoteException e) {
6874 mDeathRecipient = null;
6875 mAttachedWindow = null;
6876 mLayoutAttached = false;
6877 mIsImWindow = false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006878 mIsWallpaper = false;
6879 mIsFloatingLayer = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006880 mBaseLayer = 0;
6881 mSubLayer = 0;
6882 return;
6883 }
6884 mDeathRecipient = deathRecipient;
Romain Guy06882f82009-06-10 13:36:04 -07006885
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006886 if ((mAttrs.type >= FIRST_SUB_WINDOW &&
6887 mAttrs.type <= LAST_SUB_WINDOW)) {
6888 // The multiplier here is to reserve space for multiple
6889 // windows in the same type layer.
6890 mBaseLayer = mPolicy.windowTypeToLayerLw(
6891 attachedWindow.mAttrs.type) * TYPE_LAYER_MULTIPLIER
6892 + TYPE_LAYER_OFFSET;
6893 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
6894 mAttachedWindow = attachedWindow;
6895 mAttachedWindow.mChildWindows.add(this);
6896 mLayoutAttached = mAttrs.type !=
6897 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
6898 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
6899 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006900 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
6901 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006902 } else {
6903 // The multiplier here is to reserve space for multiple
6904 // windows in the same type layer.
6905 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
6906 * TYPE_LAYER_MULTIPLIER
6907 + TYPE_LAYER_OFFSET;
6908 mSubLayer = 0;
6909 mAttachedWindow = null;
6910 mLayoutAttached = false;
6911 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
6912 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07006913 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
6914 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006915 }
6916
6917 WindowState appWin = this;
6918 while (appWin.mAttachedWindow != null) {
6919 appWin = mAttachedWindow;
6920 }
6921 WindowToken appToken = appWin.mToken;
6922 while (appToken.appWindowToken == null) {
6923 WindowToken parent = mTokenMap.get(appToken.token);
6924 if (parent == null || appToken == parent) {
6925 break;
6926 }
6927 appToken = parent;
6928 }
The Android Open Source Project10592532009-03-18 17:39:46 -07006929 mRootToken = appToken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006930 mAppToken = appToken.appWindowToken;
6931
6932 mSurface = null;
6933 mRequestedWidth = 0;
6934 mRequestedHeight = 0;
6935 mLastRequestedWidth = 0;
6936 mLastRequestedHeight = 0;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07006937 mXOffset = 0;
6938 mYOffset = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006939 mLayer = 0;
6940 mAnimLayer = 0;
6941 mLastLayer = 0;
Jeff Brown928e0542011-01-10 11:17:36 -08006942 mInputWindowHandle = new InputWindowHandle(
6943 mAppToken != null ? mAppToken.mInputApplicationHandle : null, this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006944 }
6945
6946 void attach() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006947 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006948 TAG, "Attaching " + this + " token=" + mToken
6949 + ", list=" + mToken.windows);
6950 mSession.windowAddedLocked();
6951 }
6952
6953 public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
6954 mHaveFrame = true;
6955
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006956 final Rect container = mContainingFrame;
6957 container.set(pf);
6958
6959 final Rect display = mDisplayFrame;
6960 display.set(df);
6961
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07006962 if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006963 container.intersect(mCompatibleScreenFrame);
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07006964 if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
6965 display.intersect(mCompatibleScreenFrame);
6966 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006967 }
6968
6969 final int pw = container.right - container.left;
6970 final int ph = container.bottom - container.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006971
6972 int w,h;
6973 if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
6974 w = mAttrs.width < 0 ? pw : mAttrs.width;
6975 h = mAttrs.height< 0 ? ph : mAttrs.height;
6976 } else {
Romain Guy980a9382010-01-08 15:06:28 -08006977 w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
6978 h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006979 }
Romain Guy06882f82009-06-10 13:36:04 -07006980
Dianne Hackborn1c24e952010-11-23 00:34:30 -08006981 if (!mParentFrame.equals(pf)) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08006982 //Slog.i(TAG, "Window " + this + " content frame from " + mParentFrame
6983 // + " to " + pf);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08006984 mParentFrame.set(pf);
6985 mContentChanged = true;
6986 }
6987
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006988 final Rect content = mContentFrame;
6989 content.set(cf);
Romain Guy06882f82009-06-10 13:36:04 -07006990
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006991 final Rect visible = mVisibleFrame;
6992 visible.set(vf);
Romain Guy06882f82009-06-10 13:36:04 -07006993
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006994 final Rect frame = mFrame;
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07006995 final int fw = frame.width();
6996 final int fh = frame.height();
Romain Guy06882f82009-06-10 13:36:04 -07006997
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006998 //System.out.println("In: w=" + w + " h=" + h + " container=" +
6999 // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
7000
7001 Gravity.apply(mAttrs.gravity, w, h, container,
7002 (int) (mAttrs.x + mAttrs.horizontalMargin * pw),
7003 (int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
7004
7005 //System.out.println("Out: " + mFrame);
7006
7007 // Now make sure the window fits in the overall display.
7008 Gravity.applyDisplay(mAttrs.gravity, df, frame);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007009
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007010 // Make sure the content and visible frames are inside of the
7011 // final window frame.
7012 if (content.left < frame.left) content.left = frame.left;
7013 if (content.top < frame.top) content.top = frame.top;
7014 if (content.right > frame.right) content.right = frame.right;
7015 if (content.bottom > frame.bottom) content.bottom = frame.bottom;
7016 if (visible.left < frame.left) visible.left = frame.left;
7017 if (visible.top < frame.top) visible.top = frame.top;
7018 if (visible.right > frame.right) visible.right = frame.right;
7019 if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007021 final Rect contentInsets = mContentInsets;
7022 contentInsets.left = content.left-frame.left;
7023 contentInsets.top = content.top-frame.top;
7024 contentInsets.right = frame.right-content.right;
7025 contentInsets.bottom = frame.bottom-content.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007027 final Rect visibleInsets = mVisibleInsets;
7028 visibleInsets.left = visible.left-frame.left;
7029 visibleInsets.top = visible.top-frame.top;
7030 visibleInsets.right = frame.right-visible.right;
7031 visibleInsets.bottom = frame.bottom-visible.bottom;
Romain Guy06882f82009-06-10 13:36:04 -07007032
Dianne Hackborn284ac932009-08-28 10:34:25 -07007033 if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
7034 updateWallpaperOffsetLocked(this, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07007035 mDisplay.getHeight(), false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07007036 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007037
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007038 if (localLOGV) {
7039 //if ("com.google.android.youtube".equals(mAttrs.packageName)
7040 // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007041 Slog.v(TAG, "Resolving (mRequestedWidth="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007042 + mRequestedWidth + ", mRequestedheight="
7043 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
7044 + "): frame=" + mFrame.toShortString()
7045 + " ci=" + contentInsets.toShortString()
7046 + " vi=" + visibleInsets.toShortString());
7047 //}
7048 }
7049 }
Romain Guy06882f82009-06-10 13:36:04 -07007050
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007051 public Rect getFrameLw() {
7052 return mFrame;
7053 }
7054
7055 public Rect getShownFrameLw() {
7056 return mShownFrame;
7057 }
7058
7059 public Rect getDisplayFrameLw() {
7060 return mDisplayFrame;
7061 }
7062
7063 public Rect getContentFrameLw() {
7064 return mContentFrame;
7065 }
7066
7067 public Rect getVisibleFrameLw() {
7068 return mVisibleFrame;
7069 }
7070
7071 public boolean getGivenInsetsPendingLw() {
7072 return mGivenInsetsPending;
7073 }
7074
7075 public Rect getGivenContentInsetsLw() {
7076 return mGivenContentInsets;
7077 }
Romain Guy06882f82009-06-10 13:36:04 -07007078
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007079 public Rect getGivenVisibleInsetsLw() {
7080 return mGivenVisibleInsets;
7081 }
Romain Guy06882f82009-06-10 13:36:04 -07007082
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007083 public WindowManager.LayoutParams getAttrs() {
7084 return mAttrs;
7085 }
7086
7087 public int getSurfaceLayer() {
7088 return mLayer;
7089 }
Romain Guy06882f82009-06-10 13:36:04 -07007090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007091 public IApplicationToken getAppToken() {
7092 return mAppToken != null ? mAppToken.appToken : null;
7093 }
Jeff Brown349703e2010-06-22 01:27:15 -07007094
7095 public long getInputDispatchingTimeoutNanos() {
7096 return mAppToken != null
7097 ? mAppToken.inputDispatchingTimeoutNanos
7098 : DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
7099 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007100
7101 public boolean hasAppShownWindows() {
7102 return mAppToken != null ? mAppToken.firstWindowDrawn : false;
7103 }
7104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007105 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007106 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007107 TAG, "Setting animation in " + this + ": " + anim);
7108 mAnimating = false;
7109 mLocalAnimating = false;
7110 mAnimation = anim;
7111 mAnimation.restrictDuration(MAX_ANIMATION_DURATION);
7112 mAnimation.scaleCurrentDuration(mWindowAnimationScale);
7113 }
7114
7115 public void clearAnimation() {
7116 if (mAnimation != null) {
7117 mAnimating = true;
7118 mLocalAnimating = false;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007119 mAnimation.cancel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007120 mAnimation = null;
7121 }
7122 }
Romain Guy06882f82009-06-10 13:36:04 -07007123
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007124 Surface createSurfaceLocked() {
7125 if (mSurface == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007126 mReportDestroySurface = false;
7127 mSurfacePendingDestroy = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007128 mDrawPending = true;
7129 mCommitDrawPending = false;
7130 mReadyToShow = false;
7131 if (mAppToken != null) {
7132 mAppToken.allDrawn = false;
7133 }
7134
7135 int flags = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007136
7137 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
7138 flags |= Surface.SECURE;
7139 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007140 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007141 TAG, "Creating surface in session "
7142 + mSession.mSurfaceSession + " window " + this
7143 + " w=" + mFrame.width()
7144 + " h=" + mFrame.height() + " format="
7145 + mAttrs.format + " flags=" + flags);
7146
7147 int w = mFrame.width();
7148 int h = mFrame.height();
7149 if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
7150 // for a scaled surface, we always want the requested
7151 // size.
7152 w = mRequestedWidth;
7153 h = mRequestedHeight;
7154 }
7155
Romain Guy9825ec62009-10-01 00:58:09 -07007156 // Something is wrong and SurfaceFlinger will not like this,
7157 // try to revert to sane values
7158 if (w <= 0) w = 1;
7159 if (h <= 0) h = 1;
7160
Dianne Hackborn16064f92010-03-25 00:47:24 -07007161 mSurfaceShown = false;
7162 mSurfaceLayer = 0;
7163 mSurfaceAlpha = 1;
7164 mSurfaceX = 0;
7165 mSurfaceY = 0;
7166 mSurfaceW = w;
7167 mSurfaceH = h;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007168 try {
Romain Guyd10cd572010-10-10 13:33:22 -07007169 final boolean isHwAccelerated = (mAttrs.flags &
7170 WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
7171 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : mAttrs.format;
7172 if (isHwAccelerated && mAttrs.format == PixelFormat.OPAQUE) {
7173 flags |= Surface.OPAQUE;
7174 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007175 mSurface = new Surface(
Romain Guy06882f82009-06-10 13:36:04 -07007176 mSession.mSurfaceSession, mSession.mPid,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08007177 mAttrs.getTitle().toString(),
Romain Guyd10cd572010-10-10 13:33:22 -07007178 0, w, h, format, flags);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007179 if (SHOW_TRANSACTIONS) Slog.i(TAG, " CREATE SURFACE "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007180 + mSurface + " IN SESSION "
7181 + mSession.mSurfaceSession
7182 + ": pid=" + mSession.mPid + " format="
7183 + mAttrs.format + " flags=0x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007184 + Integer.toHexString(flags)
7185 + " / " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007186 } catch (Surface.OutOfResourcesException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007187 Slog.w(TAG, "OutOfResourcesException creating surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007188 reclaimSomeSurfaceMemoryLocked(this, "create");
7189 return null;
7190 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007191 Slog.e(TAG, "Exception creating surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007192 return null;
7193 }
Romain Guy06882f82009-06-10 13:36:04 -07007194
Joe Onorato8a9b2202010-02-26 18:56:32 -08007195 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007196 TAG, "Got surface: " + mSurface
7197 + ", set left=" + mFrame.left + " top=" + mFrame.top
7198 + ", animLayer=" + mAnimLayer);
7199 if (SHOW_TRANSACTIONS) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007200 Slog.i(TAG, ">>> OPEN TRANSACTION");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007201 if (SHOW_TRANSACTIONS) logSurface(this,
7202 "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
7203 mFrame.width() + "x" + mFrame.height() + "), layer=" +
7204 mAnimLayer + " HIDE", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007205 }
7206 Surface.openTransaction();
7207 try {
7208 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07007209 mSurfaceX = mFrame.left + mXOffset;
Dianne Hackborn529bef62010-03-25 11:48:43 -07007210 mSurfaceY = mFrame.top + mYOffset;
Dianne Hackborn16064f92010-03-25 00:47:24 -07007211 mSurface.setPosition(mSurfaceX, mSurfaceY);
7212 mSurfaceLayer = mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007213 mSurface.setLayer(mAnimLayer);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007214 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007215 mSurface.hide();
7216 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007217 if (SHOW_TRANSACTIONS) logSurface(this, "DITHER", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007218 mSurface.setFlags(Surface.SURFACE_DITHER,
7219 Surface.SURFACE_DITHER);
7220 }
7221 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007222 Slog.w(TAG, "Error creating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007223 reclaimSomeSurfaceMemoryLocked(this, "create-init");
7224 }
7225 mLastHidden = true;
7226 } finally {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007227 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007228 Surface.closeTransaction();
7229 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007230 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007231 TAG, "Created surface " + this);
7232 }
7233 return mSurface;
7234 }
Romain Guy06882f82009-06-10 13:36:04 -07007235
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007236 void destroySurfaceLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007237 if (mAppToken != null && this == mAppToken.startingWindow) {
7238 mAppToken.startingDisplayed = false;
7239 }
Romain Guy06882f82009-06-10 13:36:04 -07007240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007241 if (mSurface != null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007242 mDrawPending = false;
7243 mCommitDrawPending = false;
7244 mReadyToShow = false;
7245
7246 int i = mChildWindows.size();
7247 while (i > 0) {
7248 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07007249 WindowState c = mChildWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007250 c.mAttachedHidden = true;
7251 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007252
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007253 if (mReportDestroySurface) {
7254 mReportDestroySurface = false;
7255 mSurfacePendingDestroy = true;
7256 try {
7257 mClient.dispatchGetNewSurface();
7258 // We'll really destroy on the next time around.
7259 return;
7260 } catch (RemoteException e) {
7261 }
7262 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007264 try {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007265 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007266 RuntimeException e = null;
7267 if (!HIDE_STACK_CRAWLS) {
7268 e = new RuntimeException();
7269 e.fillInStackTrace();
7270 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007271 Slog.w(TAG, "Window " + this + " destroying surface "
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007272 + mSurface + ", session " + mSession, e);
7273 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007274 if (SHOW_TRANSACTIONS) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007275 RuntimeException e = null;
7276 if (!HIDE_STACK_CRAWLS) {
7277 e = new RuntimeException();
7278 e.fillInStackTrace();
7279 }
7280 if (SHOW_TRANSACTIONS) logSurface(this, "DESTROY", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007281 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007282 mSurface.destroy();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007283 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007284 Slog.w(TAG, "Exception thrown when destroying Window " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007285 + " surface " + mSurface + " session " + mSession
7286 + ": " + e.toString());
7287 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007288
Dianne Hackborn16064f92010-03-25 00:47:24 -07007289 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007290 mSurface = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007291 }
7292 }
7293
7294 boolean finishDrawingLocked() {
7295 if (mDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007296 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007297 TAG, "finishDrawingLocked: " + mSurface);
7298 mCommitDrawPending = true;
7299 mDrawPending = false;
7300 return true;
7301 }
7302 return false;
7303 }
7304
7305 // This must be called while inside a transaction.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007306 boolean commitFinishDrawingLocked(long currentTime) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007307 //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007308 if (!mCommitDrawPending) {
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007309 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007310 }
7311 mCommitDrawPending = false;
7312 mReadyToShow = true;
7313 final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
7314 final AppWindowToken atoken = mAppToken;
7315 if (atoken == null || atoken.allDrawn || starting) {
7316 performShowLocked();
7317 }
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007318 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007319 }
7320
7321 // This must be called while inside a transaction.
7322 boolean performShowLocked() {
7323 if (DEBUG_VISIBILITY) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007324 RuntimeException e = null;
7325 if (!HIDE_STACK_CRAWLS) {
7326 e = new RuntimeException();
7327 e.fillInStackTrace();
7328 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007329 Slog.v(TAG, "performShow on " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007330 + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
7331 + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
7332 }
7333 if (mReadyToShow && isReadyForDisplay()) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007334 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) logSurface(this,
7335 "SHOW (performShowLocked)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007336 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007337 + " during animation: policyVis=" + mPolicyVisibility
7338 + " attHidden=" + mAttachedHidden
7339 + " tok.hiddenRequested="
7340 + (mAppToken != null ? mAppToken.hiddenRequested : false)
Dianne Hackborn248b1882009-09-16 16:46:44 -07007341 + " tok.hidden="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007342 + (mAppToken != null ? mAppToken.hidden : false)
7343 + " animating=" + mAnimating
7344 + " tok animating="
7345 + (mAppToken != null ? mAppToken.animating : false));
7346 if (!showSurfaceRobustlyLocked(this)) {
7347 return false;
7348 }
7349 mLastAlpha = -1;
7350 mHasDrawn = true;
7351 mLastHidden = false;
7352 mReadyToShow = false;
7353 enableScreenIfNeededLocked();
7354
7355 applyEnterAnimationLocked(this);
Romain Guy06882f82009-06-10 13:36:04 -07007356
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007357 int i = mChildWindows.size();
7358 while (i > 0) {
7359 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07007360 WindowState c = mChildWindows.get(i);
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07007361 if (c.mAttachedHidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007362 c.mAttachedHidden = false;
Dianne Hackbornf09c1a22010-04-22 15:59:21 -07007363 if (c.mSurface != null) {
7364 c.performShowLocked();
7365 // It hadn't been shown, which means layout not
7366 // performed on it, so now we want to make sure to
7367 // do a layout. If called from within the transaction
7368 // loop, this will cause it to restart with a new
7369 // layout.
7370 mLayoutNeeded = true;
7371 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007372 }
7373 }
Romain Guy06882f82009-06-10 13:36:04 -07007374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007375 if (mAttrs.type != TYPE_APPLICATION_STARTING
7376 && mAppToken != null) {
7377 mAppToken.firstWindowDrawn = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007378
Dianne Hackborn248b1882009-09-16 16:46:44 -07007379 if (mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007380 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007381 "Finish starting " + mToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007382 + ": first real window is shown, no animation");
Dianne Hackborn248b1882009-09-16 16:46:44 -07007383 // If this initial window is animating, stop it -- we
7384 // will do an animation to reveal it from behind the
7385 // starting window, so there is no need for it to also
7386 // be doing its own stuff.
7387 if (mAnimation != null) {
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007388 mAnimation.cancel();
Dianne Hackborn248b1882009-09-16 16:46:44 -07007389 mAnimation = null;
7390 // Make sure we clean up the animation.
7391 mAnimating = true;
7392 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007393 mFinishedStarting.add(mAppToken);
7394 mH.sendEmptyMessage(H.FINISHED_STARTING);
7395 }
7396 mAppToken.updateReportedVisibilityLocked();
7397 }
7398 }
7399 return true;
7400 }
Romain Guy06882f82009-06-10 13:36:04 -07007401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007402 // This must be called while inside a transaction. Returns true if
7403 // there is more animation to run.
7404 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007405 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007406 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07007407
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007408 if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
7409 mHasTransformation = true;
7410 mHasLocalTransformation = true;
7411 if (!mLocalAnimating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007412 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007413 TAG, "Starting animation in " + this +
7414 " @ " + currentTime + ": ww=" + mFrame.width() + " wh=" + mFrame.height() +
7415 " dw=" + dw + " dh=" + dh + " scale=" + mWindowAnimationScale);
7416 mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
7417 mAnimation.setStartTime(currentTime);
7418 mLocalAnimating = true;
7419 mAnimating = true;
7420 }
7421 mTransformation.clear();
7422 final boolean more = mAnimation.getTransformation(
7423 currentTime, mTransformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007424 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007425 TAG, "Stepped animation in " + this +
7426 ": more=" + more + ", xform=" + mTransformation);
7427 if (more) {
7428 // we're not done!
7429 return true;
7430 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007431 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007432 TAG, "Finished animation in " + this +
7433 " @ " + currentTime);
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007434
7435 if (mAnimation != null) {
7436 mAnimation.cancel();
7437 mAnimation = null;
7438 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007439 //WindowManagerService.this.dump();
7440 }
7441 mHasLocalTransformation = false;
7442 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007443 && mAppToken.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007444 // When our app token is animating, we kind-of pretend like
7445 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
7446 // part of this check means that we will only do this if
7447 // our window is not currently exiting, or it is not
7448 // locally animating itself. The idea being that one that
7449 // is exiting and doing a local animation should be removed
7450 // once that animation is done.
7451 mAnimating = true;
7452 mHasTransformation = true;
7453 mTransformation.clear();
7454 return false;
7455 } else if (mHasTransformation) {
7456 // Little trick to get through the path below to act like
7457 // we have finished an animation.
7458 mAnimating = true;
7459 } else if (isAnimating()) {
7460 mAnimating = true;
7461 }
7462 } else if (mAnimation != null) {
7463 // If the display is frozen, and there is a pending animation,
7464 // clear it and make sure we run the cleanup code.
7465 mAnimating = true;
7466 mLocalAnimating = true;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007467 mAnimation.cancel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007468 mAnimation = null;
7469 }
Romain Guy06882f82009-06-10 13:36:04 -07007470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007471 if (!mAnimating && !mLocalAnimating) {
7472 return false;
7473 }
7474
Joe Onorato8a9b2202010-02-26 18:56:32 -08007475 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007476 TAG, "Animation done in " + this + ": exiting=" + mExiting
7477 + ", reportedVisible="
7478 + (mAppToken != null ? mAppToken.reportedVisible : false));
Romain Guy06882f82009-06-10 13:36:04 -07007479
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007480 mAnimating = false;
7481 mLocalAnimating = false;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07007482 if (mAnimation != null) {
7483 mAnimation.cancel();
7484 mAnimation = null;
7485 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007486 mAnimLayer = mLayer;
7487 if (mIsImWindow) {
7488 mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007489 } else if (mIsWallpaper) {
7490 mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007491 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007492 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007493 + " anim layer: " + mAnimLayer);
7494 mHasTransformation = false;
7495 mHasLocalTransformation = false;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007496 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
7497 if (DEBUG_VISIBILITY) {
7498 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
7499 + mPolicyVisibilityAfterAnim);
7500 }
7501 mPolicyVisibility = mPolicyVisibilityAfterAnim;
7502 if (!mPolicyVisibility) {
7503 if (mCurrentFocus == this) {
7504 mFocusMayChange = true;
7505 }
7506 // Window is no longer visible -- make sure if we were waiting
7507 // for it to be displayed before enabling the display, that
7508 // we allow the display to be enabled now.
7509 enableScreenIfNeededLocked();
7510 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08007511 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007512 mTransformation.clear();
7513 if (mHasDrawn
7514 && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
7515 && mAppToken != null
7516 && mAppToken.firstWindowDrawn
7517 && mAppToken.startingData != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007518 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007519 + mToken + ": first real window done animating");
7520 mFinishedStarting.add(mAppToken);
7521 mH.sendEmptyMessage(H.FINISHED_STARTING);
7522 }
Romain Guy06882f82009-06-10 13:36:04 -07007523
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007524 finishExit();
7525
7526 if (mAppToken != null) {
7527 mAppToken.updateReportedVisibilityLocked();
7528 }
7529
7530 return false;
7531 }
7532
7533 void finishExit() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007534 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007535 TAG, "finishExit in " + this
7536 + ": exiting=" + mExiting
7537 + " remove=" + mRemoveOnExit
7538 + " windowAnimating=" + isWindowAnimating());
Romain Guy06882f82009-06-10 13:36:04 -07007539
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007540 final int N = mChildWindows.size();
7541 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07007542 mChildWindows.get(i).finishExit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007543 }
Romain Guy06882f82009-06-10 13:36:04 -07007544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007545 if (!mExiting) {
7546 return;
7547 }
Romain Guy06882f82009-06-10 13:36:04 -07007548
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007549 if (isWindowAnimating()) {
7550 return;
7551 }
7552
Joe Onorato8a9b2202010-02-26 18:56:32 -08007553 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007554 TAG, "Exit animation finished in " + this
7555 + ": remove=" + mRemoveOnExit);
7556 if (mSurface != null) {
7557 mDestroySurface.add(this);
7558 mDestroying = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007559 if (SHOW_TRANSACTIONS) logSurface(this, "HIDE (finishExit)", null);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007560 mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007561 try {
7562 mSurface.hide();
7563 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007564 Slog.w(TAG, "Error hiding surface in " + this, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007565 }
7566 mLastHidden = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007567 }
7568 mExiting = false;
7569 if (mRemoveOnExit) {
7570 mPendingRemove.add(this);
7571 mRemoveOnExit = false;
7572 }
7573 }
Romain Guy06882f82009-06-10 13:36:04 -07007574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007575 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
7576 if (dsdx < .99999f || dsdx > 1.00001f) return false;
7577 if (dtdy < .99999f || dtdy > 1.00001f) return false;
7578 if (dtdx < -.000001f || dtdx > .000001f) return false;
7579 if (dsdy < -.000001f || dsdy > .000001f) return false;
7580 return true;
7581 }
Romain Guy06882f82009-06-10 13:36:04 -07007582
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007583 void computeShownFrameLocked() {
7584 final boolean selfTransformation = mHasLocalTransformation;
7585 Transformation attachedTransformation =
7586 (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
7587 ? mAttachedWindow.mTransformation : null;
7588 Transformation appTransformation =
7589 (mAppToken != null && mAppToken.hasTransformation)
7590 ? mAppToken.transformation : null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007591
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007592 // Wallpapers are animated based on the "real" window they
7593 // are currently targeting.
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007594 if (mAttrs.type == TYPE_WALLPAPER && mLowerWallpaperTarget == null
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07007595 && mWallpaperTarget != null) {
Dianne Hackborn5baba162009-09-23 17:01:12 -07007596 if (mWallpaperTarget.mHasLocalTransformation &&
7597 mWallpaperTarget.mAnimation != null &&
7598 !mWallpaperTarget.mAnimation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007599 attachedTransformation = mWallpaperTarget.mTransformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07007600 if (DEBUG_WALLPAPER && attachedTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007601 Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07007602 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007603 }
7604 if (mWallpaperTarget.mAppToken != null &&
Dianne Hackborn5baba162009-09-23 17:01:12 -07007605 mWallpaperTarget.mAppToken.hasTransformation &&
7606 mWallpaperTarget.mAppToken.animation != null &&
7607 !mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007608 appTransformation = mWallpaperTarget.mAppToken.transformation;
Dianne Hackborn5baba162009-09-23 17:01:12 -07007609 if (DEBUG_WALLPAPER && appTransformation != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007610 Slog.v(TAG, "WP target app xform: " + appTransformation);
Dianne Hackborn5baba162009-09-23 17:01:12 -07007611 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007612 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -07007613 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007614
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007615 final boolean screenAnimation = mScreenRotationAnimation != null
7616 && mScreenRotationAnimation.isAnimating();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007617 if (selfTransformation || attachedTransformation != null
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007618 || appTransformation != null || screenAnimation) {
Romain Guy06882f82009-06-10 13:36:04 -07007619 // cache often used attributes locally
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007620 final Rect frame = mFrame;
7621 final float tmpFloats[] = mTmpFloats;
7622 final Matrix tmpMatrix = mTmpMatrix;
7623
7624 // Compute the desired transformation.
Dianne Hackborn65c23872009-09-18 17:47:02 -07007625 tmpMatrix.setTranslate(0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007626 if (selfTransformation) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007627 tmpMatrix.postConcat(mTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007628 }
Dianne Hackborn65c23872009-09-18 17:47:02 -07007629 tmpMatrix.postTranslate(frame.left, frame.top);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007630 if (attachedTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007631 tmpMatrix.postConcat(attachedTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007632 }
7633 if (appTransformation != null) {
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007634 tmpMatrix.postConcat(appTransformation.getMatrix());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007635 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007636 if (screenAnimation) {
7637 tmpMatrix.postConcat(
7638 mScreenRotationAnimation.getEnterTransformation().getMatrix());
7639 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007640
7641 // "convert" it into SurfaceFlinger's format
7642 // (a 2x2 matrix + an offset)
7643 // Here we must not transform the position of the surface
7644 // since it is already included in the transformation.
Joe Onorato8a9b2202010-02-26 18:56:32 -08007645 //Slog.i(TAG, "Transform: " + matrix);
Romain Guy06882f82009-06-10 13:36:04 -07007646
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08007647 mHaveMatrix = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007648 tmpMatrix.getValues(tmpFloats);
7649 mDsDx = tmpFloats[Matrix.MSCALE_X];
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007650 mDtDx = tmpFloats[Matrix.MSKEW_Y];
7651 mDsDy = tmpFloats[Matrix.MSKEW_X];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007652 mDtDy = tmpFloats[Matrix.MSCALE_Y];
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007653 int x = (int)tmpFloats[Matrix.MTRANS_X] + mXOffset;
7654 int y = (int)tmpFloats[Matrix.MTRANS_Y] + mYOffset;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007655 int w = frame.width();
7656 int h = frame.height();
7657 mShownFrame.set(x, y, x+w, y+h);
7658
7659 // Now set the alpha... but because our current hardware
7660 // can't do alpha transformation on a non-opaque surface,
7661 // turn it off if we are running an animation that is also
7662 // transforming since it is more important to have that
7663 // animation be smooth.
7664 mShownAlpha = mAlpha;
7665 if (!mLimitedAlphaCompositing
7666 || (!PixelFormat.formatHasAlpha(mAttrs.format)
7667 || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
7668 && x == frame.left && y == frame.top))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007669 //Slog.i(TAG, "Applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007670 if (selfTransformation) {
7671 mShownAlpha *= mTransformation.getAlpha();
7672 }
7673 if (attachedTransformation != null) {
7674 mShownAlpha *= attachedTransformation.getAlpha();
7675 }
7676 if (appTransformation != null) {
7677 mShownAlpha *= appTransformation.getAlpha();
7678 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007679 if (screenAnimation) {
7680 mShownAlpha *=
7681 mScreenRotationAnimation.getEnterTransformation().getAlpha();
7682 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007683 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007684 //Slog.i(TAG, "Not applying alpha transform");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007685 }
Romain Guy06882f82009-06-10 13:36:04 -07007686
Joe Onorato8a9b2202010-02-26 18:56:32 -08007687 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007688 TAG, "Continuing animation in " + this +
7689 ": " + mShownFrame +
7690 ", alpha=" + mTransformation.getAlpha());
7691 return;
7692 }
Romain Guy06882f82009-06-10 13:36:04 -07007693
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007694 mShownFrame.set(mFrame);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07007695 if (mXOffset != 0 || mYOffset != 0) {
7696 mShownFrame.offset(mXOffset, mYOffset);
7697 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007698 mShownAlpha = mAlpha;
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08007699 mHaveMatrix = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007700 mDsDx = 1;
7701 mDtDx = 0;
7702 mDsDy = 0;
7703 mDtDy = 1;
7704 }
Romain Guy06882f82009-06-10 13:36:04 -07007705
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007706 /**
7707 * Is this window visible? It is not visible if there is no
7708 * surface, or we are in the process of running an exit animation
7709 * that will remove the surface, or its app token has been hidden.
7710 */
7711 public boolean isVisibleLw() {
7712 final AppWindowToken atoken = mAppToken;
7713 return mSurface != null && mPolicyVisibility && !mAttachedHidden
7714 && (atoken == null || !atoken.hiddenRequested)
7715 && !mExiting && !mDestroying;
7716 }
7717
7718 /**
Dianne Hackborn3d163f072009-10-07 21:26:57 -07007719 * Like {@link #isVisibleLw}, but also counts a window that is currently
7720 * "hidden" behind the keyguard as visible. This allows us to apply
7721 * things like window flags that impact the keyguard.
7722 * XXX I am starting to think we need to have ANOTHER visibility flag
7723 * for this "hidden behind keyguard" state rather than overloading
7724 * mPolicyVisibility. Ungh.
7725 */
7726 public boolean isVisibleOrBehindKeyguardLw() {
7727 final AppWindowToken atoken = mAppToken;
7728 return mSurface != null && !mAttachedHidden
7729 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007730 && !mDrawPending && !mCommitDrawPending
Dianne Hackborn3d163f072009-10-07 21:26:57 -07007731 && !mExiting && !mDestroying;
7732 }
7733
7734 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007735 * Is this window visible, ignoring its app token? It is not visible
7736 * if there is no surface, or we are in the process of running an exit animation
7737 * that will remove the surface.
7738 */
7739 public boolean isWinVisibleLw() {
7740 final AppWindowToken atoken = mAppToken;
7741 return mSurface != null && mPolicyVisibility && !mAttachedHidden
7742 && (atoken == null || !atoken.hiddenRequested || atoken.animating)
7743 && !mExiting && !mDestroying;
7744 }
7745
7746 /**
7747 * The same as isVisible(), but follows the current hidden state of
7748 * the associated app token, not the pending requested hidden state.
7749 */
7750 boolean isVisibleNow() {
7751 return mSurface != null && mPolicyVisibility && !mAttachedHidden
The Android Open Source Project10592532009-03-18 17:39:46 -07007752 && !mRootToken.hidden && !mExiting && !mDestroying;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007753 }
7754
7755 /**
Christopher Tatea53146c2010-09-07 11:57:52 -07007756 * Can this window possibly be a drag/drop target? The test here is
7757 * a combination of the above "visible now" with the check that the
7758 * Input Manager uses when discarding windows from input consideration.
7759 */
7760 boolean isPotentialDragTarget() {
7761 return isVisibleNow() && (mInputChannel != null) && !mRemoved;
7762 }
7763
7764 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007765 * Same as isVisible(), but we also count it as visible between the
7766 * call to IWindowSession.add() and the first relayout().
7767 */
7768 boolean isVisibleOrAdding() {
7769 final AppWindowToken atoken = mAppToken;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007770 return ((mSurface != null && !mReportDestroySurface)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007771 || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
7772 && mPolicyVisibility && !mAttachedHidden
7773 && (atoken == null || !atoken.hiddenRequested)
7774 && !mExiting && !mDestroying;
7775 }
7776
7777 /**
7778 * Is this window currently on-screen? It is on-screen either if it
7779 * is visible or it is currently running an animation before no longer
7780 * being visible.
7781 */
7782 boolean isOnScreen() {
7783 final AppWindowToken atoken = mAppToken;
7784 if (atoken != null) {
7785 return mSurface != null && mPolicyVisibility && !mDestroying
7786 && ((!mAttachedHidden && !atoken.hiddenRequested)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007787 || mAnimation != null || atoken.animation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007788 } else {
7789 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007790 && (!mAttachedHidden || mAnimation != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007791 }
7792 }
Romain Guy06882f82009-06-10 13:36:04 -07007793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007794 /**
7795 * Like isOnScreen(), but we don't return true if the window is part
7796 * of a transition that has not yet been started.
7797 */
7798 boolean isReadyForDisplay() {
Dianne Hackborna8f60182009-09-01 19:01:50 -07007799 if (mRootToken.waitingToShow &&
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07007800 mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07007801 return false;
7802 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007803 final AppWindowToken atoken = mAppToken;
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007804 final boolean animating = atoken != null
7805 ? (atoken.animation != null) : false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007806 return mSurface != null && mPolicyVisibility && !mDestroying
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007807 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
7808 && !mRootToken.hidden)
Dianne Hackborn0cd48872009-08-13 18:51:59 -07007809 || mAnimation != null || animating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007810 }
7811
7812 /** Is the window or its container currently animating? */
7813 boolean isAnimating() {
7814 final WindowState attached = mAttachedWindow;
7815 final AppWindowToken atoken = mAppToken;
7816 return mAnimation != null
7817 || (attached != null && attached.mAnimation != null)
Romain Guy06882f82009-06-10 13:36:04 -07007818 || (atoken != null &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007819 (atoken.animation != null
7820 || atoken.inPendingTransaction));
7821 }
7822
7823 /** Is this window currently animating? */
7824 boolean isWindowAnimating() {
7825 return mAnimation != null;
7826 }
7827
7828 /**
7829 * Like isOnScreen, but returns false if the surface hasn't yet
7830 * been drawn.
7831 */
7832 public boolean isDisplayedLw() {
7833 final AppWindowToken atoken = mAppToken;
7834 return mSurface != null && mPolicyVisibility && !mDestroying
7835 && !mDrawPending && !mCommitDrawPending
7836 && ((!mAttachedHidden &&
7837 (atoken == null || !atoken.hiddenRequested))
7838 || mAnimating);
7839 }
7840
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07007841 /**
7842 * Returns true if the window has a surface that it has drawn a
7843 * complete UI in to.
7844 */
7845 public boolean isDrawnLw() {
7846 final AppWindowToken atoken = mAppToken;
7847 return mSurface != null && !mDestroying
7848 && !mDrawPending && !mCommitDrawPending;
7849 }
7850
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007851 /**
Dianne Hackborn25994b42009-09-04 14:21:19 -07007852 * Return true if the window is opaque and fully drawn. This indicates
7853 * it may obscure windows behind it.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007854 */
7855 boolean isOpaqueDrawn() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07007856 return (mAttrs.format == PixelFormat.OPAQUE
7857 || mAttrs.type == TYPE_WALLPAPER)
7858 && mSurface != null && mAnimation == null
7859 && (mAppToken == null || mAppToken.animation == null)
7860 && !mDrawPending && !mCommitDrawPending;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007861 }
7862
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007863 /**
7864 * Return whether this window is wanting to have a translation
7865 * animation applied to it for an in-progress move. (Only makes
7866 * sense to call from performLayoutAndPlaceSurfacesLockedInner().)
7867 */
7868 boolean shouldAnimateMove() {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08007869 return mContentChanged && !mExiting && !mLastHidden && !mDisplayFrozen
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007870 && (mFrame.top != mLastFrame.top
7871 || mFrame.left != mLastFrame.left)
Dianne Hackborn0f761d62010-11-30 22:06:10 -08007872 && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove())
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007873 && mPolicy.isScreenOn();
7874 }
7875
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007876 boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
7877 return
7878 // only if the application is requesting compatible window
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007879 (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
7880 // only if it's visible
7881 mHasDrawn && mViewVisibility == View.VISIBLE &&
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007882 // and only if the application fills the compatible screen
7883 mFrame.left <= mCompatibleScreenFrame.left &&
7884 mFrame.top <= mCompatibleScreenFrame.top &&
7885 mFrame.right >= mCompatibleScreenFrame.right &&
7886 mFrame.bottom >= mCompatibleScreenFrame.bottom &&
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007887 // and starting window do not need background filler
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07007888 mAttrs.type != mAttrs.TYPE_APPLICATION_STARTING;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007889 }
7890
7891 boolean isFullscreen(int screenWidth, int screenHeight) {
7892 return mFrame.left <= 0 && mFrame.top <= 0 &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007893 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007894 }
7895
7896 void removeLocked() {
Jeff Brownc5ed5912010-07-14 18:48:53 -07007897 disposeInputChannel();
7898
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007899 if (mAttachedWindow != null) {
7900 mAttachedWindow.mChildWindows.remove(this);
7901 }
7902 destroySurfaceLocked();
7903 mSession.windowRemovedLocked();
7904 try {
7905 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
7906 } catch (RuntimeException e) {
7907 // Ignore if it has already been removed (usually because
7908 // we are doing this as part of processing a death note.)
7909 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07007910 }
7911
7912 void disposeInputChannel() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07007913 if (mInputChannel != null) {
7914 mInputManager.unregisterInputChannel(mInputChannel);
7915
7916 mInputChannel.dispose();
7917 mInputChannel = null;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07007918 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007919 }
7920
7921 private class DeathRecipient implements IBinder.DeathRecipient {
7922 public void binderDied() {
7923 try {
7924 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007925 WindowState win = windowForClientLocked(mSession, mClient, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007926 Slog.i(TAG, "WIN DEATH: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007927 if (win != null) {
7928 removeWindowLocked(mSession, win);
7929 }
7930 }
7931 } catch (IllegalArgumentException ex) {
7932 // This will happen if the window has already been
7933 // removed.
7934 }
7935 }
7936 }
7937
7938 /** Returns true if this window desires key events. */
7939 public final boolean canReceiveKeys() {
7940 return isVisibleOrAdding()
7941 && (mViewVisibility == View.VISIBLE)
7942 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
7943 }
7944
7945 public boolean hasDrawnLw() {
7946 return mHasDrawn;
7947 }
7948
7949 public boolean showLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007950 return showLw(doAnimation, true);
7951 }
7952
7953 boolean showLw(boolean doAnimation, boolean requestAnim) {
7954 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
7955 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007956 }
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007957 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007958 if (doAnimation) {
7959 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
7960 + mPolicyVisibility + " mAnimation=" + mAnimation);
7961 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
7962 doAnimation = false;
7963 } else if (mPolicyVisibility && mAnimation == null) {
7964 // Check for the case where we are currently visible and
7965 // not animating; we do not want to do animation at such a
7966 // point to become visible when we already are.
7967 doAnimation = false;
7968 }
7969 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007970 mPolicyVisibility = true;
7971 mPolicyVisibilityAfterAnim = true;
7972 if (doAnimation) {
7973 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
7974 }
7975 if (requestAnim) {
7976 requestAnimationLocked(0);
7977 }
7978 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007979 }
7980
7981 public boolean hideLw(boolean doAnimation) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007982 return hideLw(doAnimation, true);
7983 }
7984
7985 boolean hideLw(boolean doAnimation, boolean requestAnim) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007986 if (doAnimation) {
7987 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
7988 doAnimation = false;
7989 }
7990 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007991 boolean current = doAnimation ? mPolicyVisibilityAfterAnim
7992 : mPolicyVisibility;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007993 if (!current) {
7994 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007995 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007996 if (doAnimation) {
7997 applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
7998 if (mAnimation == null) {
7999 doAnimation = false;
8000 }
8001 }
8002 if (doAnimation) {
8003 mPolicyVisibilityAfterAnim = false;
8004 } else {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008005 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008006 mPolicyVisibilityAfterAnim = false;
8007 mPolicyVisibility = false;
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08008008 // Window is no longer visible -- make sure if we were waiting
8009 // for it to be displayed before enabling the display, that
8010 // we allow the display to be enabled now.
8011 enableScreenIfNeededLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008012 if (mCurrentFocus == this) {
8013 mFocusMayChange = true;
8014 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008015 }
8016 if (requestAnim) {
8017 requestAnimationLocked(0);
8018 }
8019 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008020 }
8021
8022 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008023 pw.print(prefix); pw.print("mSession="); pw.print(mSession);
8024 pw.print(" mClient="); pw.println(mClient.asBinder());
8025 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
8026 if (mAttachedWindow != null || mLayoutAttached) {
8027 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
8028 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
8029 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07008030 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
8031 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
8032 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008033 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
8034 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008035 }
8036 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
8037 pw.print(" mSubLayer="); pw.print(mSubLayer);
8038 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
8039 pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
8040 : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
8041 pw.print("="); pw.print(mAnimLayer);
8042 pw.print(" mLastLayer="); pw.println(mLastLayer);
8043 if (mSurface != null) {
8044 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
Dianne Hackborn16064f92010-03-25 00:47:24 -07008045 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
8046 pw.print(" layer="); pw.print(mSurfaceLayer);
8047 pw.print(" alpha="); pw.print(mSurfaceAlpha);
8048 pw.print(" rect=("); pw.print(mSurfaceX);
8049 pw.print(","); pw.print(mSurfaceY);
8050 pw.print(") "); pw.print(mSurfaceW);
8051 pw.print(" x "); pw.println(mSurfaceH);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008052 }
8053 pw.print(prefix); pw.print("mToken="); pw.println(mToken);
8054 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
8055 if (mAppToken != null) {
8056 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
8057 }
8058 if (mTargetAppToken != null) {
8059 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
8060 }
8061 pw.print(prefix); pw.print("mViewVisibility=0x");
8062 pw.print(Integer.toHexString(mViewVisibility));
8063 pw.print(" mLastHidden="); pw.print(mLastHidden);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008064 pw.print(" mHaveFrame="); pw.print(mHaveFrame);
8065 pw.print(" mObscured="); pw.println(mObscured);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008066 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
8067 pw.print(prefix); pw.print("mPolicyVisibility=");
8068 pw.print(mPolicyVisibility);
8069 pw.print(" mPolicyVisibilityAfterAnim=");
8070 pw.print(mPolicyVisibilityAfterAnim);
8071 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
8072 }
Dianne Hackborn9b52a212009-12-11 14:51:35 -08008073 if (!mRelayoutCalled) {
8074 pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
8075 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008076 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008077 pw.print(" h="); pw.print(mRequestedHeight);
8078 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008079 if (mXOffset != 0 || mYOffset != 0) {
8080 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
8081 pw.print(" y="); pw.println(mYOffset);
8082 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008083 pw.print(prefix); pw.print("mGivenContentInsets=");
8084 mGivenContentInsets.printShortString(pw);
8085 pw.print(" mGivenVisibleInsets=");
8086 mGivenVisibleInsets.printShortString(pw);
8087 pw.println();
8088 if (mTouchableInsets != 0 || mGivenInsetsPending) {
8089 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
8090 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
8091 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008092 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008093 pw.print(prefix); pw.print("mShownFrame=");
8094 mShownFrame.printShortString(pw);
8095 pw.print(" last="); mLastShownFrame.printShortString(pw);
8096 pw.println();
8097 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
8098 pw.print(" last="); mLastFrame.printShortString(pw);
8099 pw.println();
8100 pw.print(prefix); pw.print("mContainingFrame=");
8101 mContainingFrame.printShortString(pw);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008102 pw.print(" mParentFrame=");
8103 mParentFrame.printShortString(pw);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008104 pw.print(" mDisplayFrame=");
8105 mDisplayFrame.printShortString(pw);
8106 pw.println();
8107 pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
8108 pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
8109 pw.println();
8110 pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
8111 pw.print(" last="); mLastContentInsets.printShortString(pw);
8112 pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
8113 pw.print(" last="); mLastVisibleInsets.printShortString(pw);
8114 pw.println();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008115 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
8116 || mAnimation != null) {
8117 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
8118 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
8119 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
8120 pw.print(" mAnimation="); pw.println(mAnimation);
8121 }
8122 if (mHasTransformation || mHasLocalTransformation) {
8123 pw.print(prefix); pw.print("XForm: has=");
8124 pw.print(mHasTransformation);
8125 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
8126 pw.print(" "); mTransformation.printShortString(pw);
8127 pw.println();
8128 }
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08008129 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
8130 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
8131 pw.print(" mAlpha="); pw.print(mAlpha);
8132 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
8133 }
8134 if (mHaveMatrix) {
8135 pw.print(prefix); pw.print("mDsDx="); pw.print(mDsDx);
8136 pw.print(" mDtDx="); pw.print(mDtDx);
8137 pw.print(" mDsDy="); pw.print(mDsDy);
8138 pw.print(" mDtDy="); pw.println(mDtDy);
8139 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008140 pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
8141 pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
8142 pw.print(" mReadyToShow="); pw.print(mReadyToShow);
8143 pw.print(" mHasDrawn="); pw.println(mHasDrawn);
8144 if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
8145 pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
8146 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
8147 pw.print(" mDestroying="); pw.print(mDestroying);
8148 pw.print(" mRemoved="); pw.println(mRemoved);
8149 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008150 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008151 pw.print(prefix); pw.print("mOrientationChanging=");
8152 pw.print(mOrientationChanging);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008153 pw.print(" mAppFreezing="); pw.print(mAppFreezing);
8154 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008155 }
Mitsuru Oshima589cebe2009-07-22 20:38:58 -07008156 if (mHScale != 1 || mVScale != 1) {
8157 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
8158 pw.print(" mVScale="); pw.println(mVScale);
8159 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07008160 if (mWallpaperX != -1 || mWallpaperY != -1) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008161 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
8162 pw.print(" mWallpaperY="); pw.println(mWallpaperY);
8163 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08008164 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
8165 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
8166 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
8167 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008168 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07008169
8170 String makeInputChannelName() {
8171 return Integer.toHexString(System.identityHashCode(this))
8172 + " " + mAttrs.getTitle();
8173 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008174
8175 @Override
8176 public String toString() {
Mattias Petersson1622eee2010-12-21 10:15:11 +01008177 if (mStringNameCache == null || mLastTitle != mAttrs.getTitle()
8178 || mWasPaused != mToken.paused) {
8179 mLastTitle = mAttrs.getTitle();
8180 mWasPaused = mToken.paused;
8181 mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
8182 + " " + mLastTitle + " paused=" + mWasPaused + "}";
8183 }
8184 return mStringNameCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008185 }
8186 }
Romain Guy06882f82009-06-10 13:36:04 -07008187
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008188 // -------------------------------------------------------------
8189 // Window Token State
8190 // -------------------------------------------------------------
8191
8192 class WindowToken {
8193 // The actual token.
8194 final IBinder token;
8195
8196 // The type of window this token is for, as per WindowManager.LayoutParams.
8197 final int windowType;
Romain Guy06882f82009-06-10 13:36:04 -07008198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008199 // Set if this token was explicitly added by a client, so should
8200 // not be removed when all windows are removed.
8201 final boolean explicit;
Romain Guy06882f82009-06-10 13:36:04 -07008202
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008203 // For printing.
8204 String stringName;
Romain Guy06882f82009-06-10 13:36:04 -07008205
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008206 // If this is an AppWindowToken, this is non-null.
8207 AppWindowToken appWindowToken;
Romain Guy06882f82009-06-10 13:36:04 -07008208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008209 // All of the windows associated with this token.
8210 final ArrayList<WindowState> windows = new ArrayList<WindowState>();
8211
8212 // Is key dispatching paused for this token?
8213 boolean paused = false;
8214
8215 // Should this token's windows be hidden?
8216 boolean hidden;
8217
8218 // Temporary for finding which tokens no longer have visible windows.
8219 boolean hasVisible;
8220
Dianne Hackborna8f60182009-09-01 19:01:50 -07008221 // Set to true when this token is in a pending transaction where it
8222 // will be shown.
8223 boolean waitingToShow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008224
Dianne Hackborna8f60182009-09-01 19:01:50 -07008225 // Set to true when this token is in a pending transaction where it
8226 // will be hidden.
8227 boolean waitingToHide;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008228
Dianne Hackborna8f60182009-09-01 19:01:50 -07008229 // Set to true when this token is in a pending transaction where its
8230 // windows will be put to the bottom of the list.
8231 boolean sendingToBottom;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008232
Dianne Hackborna8f60182009-09-01 19:01:50 -07008233 // Set to true when this token is in a pending transaction where its
8234 // windows will be put to the top of the list.
8235 boolean sendingToTop;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008236
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008237 WindowToken(IBinder _token, int type, boolean _explicit) {
8238 token = _token;
8239 windowType = type;
8240 explicit = _explicit;
8241 }
8242
8243 void dump(PrintWriter pw, String prefix) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008244 pw.print(prefix); pw.print("token="); pw.println(token);
8245 pw.print(prefix); pw.print("windows="); pw.println(windows);
8246 pw.print(prefix); pw.print("windowType="); pw.print(windowType);
8247 pw.print(" hidden="); pw.print(hidden);
8248 pw.print(" hasVisible="); pw.println(hasVisible);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008249 if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) {
8250 pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
8251 pw.print(" waitingToHide="); pw.print(waitingToHide);
8252 pw.print(" sendingToBottom="); pw.print(sendingToBottom);
8253 pw.print(" sendingToTop="); pw.println(sendingToTop);
8254 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008255 }
8256
8257 @Override
8258 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008259 if (stringName == null) {
8260 StringBuilder sb = new StringBuilder();
8261 sb.append("WindowToken{");
8262 sb.append(Integer.toHexString(System.identityHashCode(this)));
8263 sb.append(" token="); sb.append(token); sb.append('}');
8264 stringName = sb.toString();
8265 }
8266 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008267 }
8268 };
8269
8270 class AppWindowToken extends WindowToken {
8271 // Non-null only for application tokens.
8272 final IApplicationToken appToken;
8273
8274 // All of the windows and child windows that are included in this
8275 // application token. Note this list is NOT sorted!
8276 final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
8277
8278 int groupId = -1;
8279 boolean appFullscreen;
8280 int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Jeff Brown349703e2010-06-22 01:27:15 -07008281
8282 // The input dispatching timeout for this application token in nanoseconds.
8283 long inputDispatchingTimeoutNanos;
Romain Guy06882f82009-06-10 13:36:04 -07008284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008285 // These are used for determining when all windows associated with
8286 // an activity have been drawn, so they can be made visible together
8287 // at the same time.
8288 int lastTransactionSequence = mTransactionSequence-1;
8289 int numInterestingWindows;
8290 int numDrawnWindows;
8291 boolean inPendingTransaction;
8292 boolean allDrawn;
Romain Guy06882f82009-06-10 13:36:04 -07008293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008294 // Is this token going to be hidden in a little while? If so, it
8295 // won't be taken into account for setting the screen orientation.
8296 boolean willBeHidden;
Romain Guy06882f82009-06-10 13:36:04 -07008297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008298 // Is this window's surface needed? This is almost like hidden, except
8299 // it will sometimes be true a little earlier: when the token has
8300 // been shown, but is still waiting for its app transition to execute
8301 // before making its windows shown.
8302 boolean hiddenRequested;
Romain Guy06882f82009-06-10 13:36:04 -07008303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008304 // Have we told the window clients to hide themselves?
8305 boolean clientHidden;
Romain Guy06882f82009-06-10 13:36:04 -07008306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008307 // Last visibility state we reported to the app token.
8308 boolean reportedVisible;
8309
8310 // Set to true when the token has been removed from the window mgr.
8311 boolean removed;
8312
8313 // Have we been asked to have this token keep the screen frozen?
8314 boolean freezingScreen;
Romain Guy06882f82009-06-10 13:36:04 -07008315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008316 boolean animating;
8317 Animation animation;
8318 boolean hasTransformation;
8319 final Transformation transformation = new Transformation();
Romain Guy06882f82009-06-10 13:36:04 -07008320
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008321 // Offset to the window of all layers in the token, for use by
8322 // AppWindowToken animations.
8323 int animLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -07008324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008325 // Information about an application starting window if displayed.
8326 StartingData startingData;
8327 WindowState startingWindow;
8328 View startingView;
8329 boolean startingDisplayed;
8330 boolean startingMoved;
8331 boolean firstWindowDrawn;
8332
Jeff Brown928e0542011-01-10 11:17:36 -08008333 // Input application handle used by the input dispatcher.
8334 InputApplicationHandle mInputApplicationHandle;
8335
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008336 AppWindowToken(IApplicationToken _token) {
8337 super(_token.asBinder(),
8338 WindowManager.LayoutParams.TYPE_APPLICATION, true);
8339 appWindowToken = this;
8340 appToken = _token;
Jeff Brown928e0542011-01-10 11:17:36 -08008341 mInputApplicationHandle = new InputApplicationHandle(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008342 }
Romain Guy06882f82009-06-10 13:36:04 -07008343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008344 public void setAnimation(Animation anim) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008345 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008346 TAG, "Setting animation in " + this + ": " + anim);
8347 animation = anim;
8348 animating = false;
8349 anim.restrictDuration(MAX_ANIMATION_DURATION);
8350 anim.scaleCurrentDuration(mTransitionAnimationScale);
8351 int zorder = anim.getZAdjustment();
8352 int adj = 0;
8353 if (zorder == Animation.ZORDER_TOP) {
8354 adj = TYPE_LAYER_OFFSET;
8355 } else if (zorder == Animation.ZORDER_BOTTOM) {
8356 adj = -TYPE_LAYER_OFFSET;
8357 }
Romain Guy06882f82009-06-10 13:36:04 -07008358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008359 if (animLayerAdjustment != adj) {
8360 animLayerAdjustment = adj;
8361 updateLayers();
8362 }
8363 }
Romain Guy06882f82009-06-10 13:36:04 -07008364
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008365 public void setDummyAnimation() {
8366 if (animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008367 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008368 TAG, "Setting dummy animation in " + this);
8369 animation = sDummyAnimation;
8370 }
8371 }
8372
8373 public void clearAnimation() {
8374 if (animation != null) {
8375 animation = null;
8376 animating = true;
8377 }
8378 }
Romain Guy06882f82009-06-10 13:36:04 -07008379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008380 void updateLayers() {
8381 final int N = allAppWindows.size();
8382 final int adj = animLayerAdjustment;
8383 for (int i=0; i<N; i++) {
8384 WindowState w = allAppWindows.get(i);
8385 w.mAnimLayer = w.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008386 if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008387 + w.mAnimLayer);
8388 if (w == mInputMethodTarget) {
8389 setInputMethodAnimLayerAdjustment(adj);
8390 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008391 if (w == mWallpaperTarget && mLowerWallpaperTarget == null) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07008392 setWallpaperAnimLayerAdjustmentLocked(adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008393 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008394 }
8395 }
Romain Guy06882f82009-06-10 13:36:04 -07008396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008397 void sendAppVisibilityToClients() {
8398 final int N = allAppWindows.size();
8399 for (int i=0; i<N; i++) {
8400 WindowState win = allAppWindows.get(i);
8401 if (win == startingWindow && clientHidden) {
8402 // Don't hide the starting window.
8403 continue;
8404 }
8405 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008406 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008407 "Setting visibility of " + win + ": " + (!clientHidden));
8408 win.mClient.dispatchAppVisibility(!clientHidden);
8409 } catch (RemoteException e) {
8410 }
8411 }
8412 }
Romain Guy06882f82009-06-10 13:36:04 -07008413
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008414 void showAllWindowsLocked() {
8415 final int NW = allAppWindows.size();
8416 for (int i=0; i<NW; i++) {
8417 WindowState w = allAppWindows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008418 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008419 "performing show on: " + w);
8420 w.performShowLocked();
8421 }
8422 }
Romain Guy06882f82009-06-10 13:36:04 -07008423
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008424 // This must be called while inside a transaction.
8425 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008426 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008427 // We will run animations as long as the display isn't frozen.
Romain Guy06882f82009-06-10 13:36:04 -07008428
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008429 if (animation == sDummyAnimation) {
8430 // This guy is going to animate, but not yet. For now count
Dianne Hackborn3be63c02009-08-20 19:31:38 -07008431 // it as not animating for purposes of scheduling transactions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008432 // when it is really time to animate, this will be set to
8433 // a real animation and the next call will execute normally.
8434 return false;
8435 }
Romain Guy06882f82009-06-10 13:36:04 -07008436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008437 if ((allDrawn || animating || startingDisplayed) && animation != null) {
8438 if (!animating) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008439 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008440 TAG, "Starting animation in " + this +
8441 " @ " + currentTime + ": dw=" + dw + " dh=" + dh
8442 + " scale=" + mTransitionAnimationScale
8443 + " allDrawn=" + allDrawn + " animating=" + animating);
8444 animation.initialize(dw, dh, dw, dh);
8445 animation.setStartTime(currentTime);
8446 animating = true;
8447 }
8448 transformation.clear();
8449 final boolean more = animation.getTransformation(
8450 currentTime, transformation);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008451 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008452 TAG, "Stepped animation in " + this +
8453 ": more=" + more + ", xform=" + transformation);
8454 if (more) {
8455 // we're done!
8456 hasTransformation = true;
8457 return true;
8458 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008459 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008460 TAG, "Finished animation in " + this +
8461 " @ " + currentTime);
8462 animation = null;
8463 }
8464 } else if (animation != null) {
8465 // If the display is frozen, and there is a pending animation,
8466 // clear it and make sure we run the cleanup code.
8467 animating = true;
8468 animation = null;
8469 }
8470
8471 hasTransformation = false;
Romain Guy06882f82009-06-10 13:36:04 -07008472
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008473 if (!animating) {
8474 return false;
8475 }
8476
8477 clearAnimation();
8478 animating = false;
8479 if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == this) {
8480 moveInputMethodWindowsIfNeededLocked(true);
8481 }
Romain Guy06882f82009-06-10 13:36:04 -07008482
Joe Onorato8a9b2202010-02-26 18:56:32 -08008483 if (DEBUG_ANIM) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008484 TAG, "Animation done in " + this
8485 + ": reportedVisible=" + reportedVisible);
8486
8487 transformation.clear();
8488 if (animLayerAdjustment != 0) {
8489 animLayerAdjustment = 0;
8490 updateLayers();
8491 }
Romain Guy06882f82009-06-10 13:36:04 -07008492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008493 final int N = windows.size();
8494 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07008495 windows.get(i).finishExit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008496 }
8497 updateReportedVisibilityLocked();
Romain Guy06882f82009-06-10 13:36:04 -07008498
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008499 return false;
8500 }
8501
8502 void updateReportedVisibilityLocked() {
8503 if (appToken == null) {
8504 return;
8505 }
Romain Guy06882f82009-06-10 13:36:04 -07008506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008507 int numInteresting = 0;
8508 int numVisible = 0;
8509 boolean nowGone = true;
Romain Guy06882f82009-06-10 13:36:04 -07008510
Joe Onorato8a9b2202010-02-26 18:56:32 -08008511 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008512 final int N = allAppWindows.size();
8513 for (int i=0; i<N; i++) {
8514 WindowState win = allAppWindows.get(i);
Dianne Hackborn6cf67fa2009-12-21 16:46:34 -08008515 if (win == startingWindow || win.mAppFreezing
The Android Open Source Project727cec02010-04-08 11:35:37 -07008516 || win.mViewVisibility != View.VISIBLE
Ulf Rosdahl39357702010-09-29 12:34:38 +02008517 || win.mAttrs.type == TYPE_APPLICATION_STARTING
8518 || win.mDestroying) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008519 continue;
8520 }
8521 if (DEBUG_VISIBILITY) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008522 Slog.v(TAG, "Win " + win + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008523 + win.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008524 + ", isAnimating=" + win.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008525 if (!win.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008526 Slog.v(TAG, "Not displayed: s=" + win.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008527 + " pv=" + win.mPolicyVisibility
8528 + " dp=" + win.mDrawPending
8529 + " cdp=" + win.mCommitDrawPending
8530 + " ah=" + win.mAttachedHidden
8531 + " th="
8532 + (win.mAppToken != null
8533 ? win.mAppToken.hiddenRequested : false)
8534 + " a=" + win.mAnimating);
8535 }
8536 }
8537 numInteresting++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07008538 if (win.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008539 if (!win.isAnimating()) {
8540 numVisible++;
8541 }
8542 nowGone = false;
8543 } else if (win.isAnimating()) {
8544 nowGone = false;
8545 }
8546 }
Romain Guy06882f82009-06-10 13:36:04 -07008547
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008548 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008549 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008550 + numInteresting + " visible=" + numVisible);
8551 if (nowVisible != reportedVisible) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008552 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008553 TAG, "Visibility changed in " + this
8554 + ": vis=" + nowVisible);
8555 reportedVisible = nowVisible;
8556 Message m = mH.obtainMessage(
8557 H.REPORT_APPLICATION_TOKEN_WINDOWS,
8558 nowVisible ? 1 : 0,
8559 nowGone ? 1 : 0,
8560 this);
8561 mH.sendMessage(m);
8562 }
8563 }
Romain Guy06882f82009-06-10 13:36:04 -07008564
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07008565 WindowState findMainWindow() {
8566 int j = windows.size();
8567 while (j > 0) {
8568 j--;
8569 WindowState win = windows.get(j);
8570 if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
8571 || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
8572 return win;
8573 }
8574 }
8575 return null;
8576 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008577
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008578 void dump(PrintWriter pw, String prefix) {
8579 super.dump(pw, prefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008580 if (appToken != null) {
8581 pw.print(prefix); pw.println("app=true");
8582 }
8583 if (allAppWindows.size() > 0) {
8584 pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
8585 }
8586 pw.print(prefix); pw.print("groupId="); pw.print(groupId);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008587 pw.print(" appFullscreen="); pw.print(appFullscreen);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008588 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
8589 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
8590 pw.print(" clientHidden="); pw.print(clientHidden);
8591 pw.print(" willBeHidden="); pw.print(willBeHidden);
8592 pw.print(" reportedVisible="); pw.println(reportedVisible);
8593 if (paused || freezingScreen) {
8594 pw.print(prefix); pw.print("paused="); pw.print(paused);
8595 pw.print(" freezingScreen="); pw.println(freezingScreen);
8596 }
8597 if (numInterestingWindows != 0 || numDrawnWindows != 0
8598 || inPendingTransaction || allDrawn) {
8599 pw.print(prefix); pw.print("numInterestingWindows=");
8600 pw.print(numInterestingWindows);
8601 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
8602 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
8603 pw.print(" allDrawn="); pw.println(allDrawn);
8604 }
8605 if (animating || animation != null) {
8606 pw.print(prefix); pw.print("animating="); pw.print(animating);
8607 pw.print(" animation="); pw.println(animation);
8608 }
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08008609 if (hasTransformation) {
8610 pw.print(prefix); pw.print("XForm: ");
8611 transformation.printShortString(pw);
8612 pw.println();
8613 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008614 if (animLayerAdjustment != 0) {
8615 pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
8616 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008617 if (startingData != null || removed || firstWindowDrawn) {
8618 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
8619 pw.print(" removed="); pw.print(removed);
8620 pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn);
8621 }
8622 if (startingWindow != null || startingView != null
8623 || startingDisplayed || startingMoved) {
8624 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
8625 pw.print(" startingView="); pw.print(startingView);
8626 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
8627 pw.print(" startingMoved"); pw.println(startingMoved);
8628 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008629 }
8630
8631 @Override
8632 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008633 if (stringName == null) {
8634 StringBuilder sb = new StringBuilder();
8635 sb.append("AppWindowToken{");
8636 sb.append(Integer.toHexString(System.identityHashCode(this)));
8637 sb.append(" token="); sb.append(token); sb.append('}');
8638 stringName = sb.toString();
8639 }
8640 return stringName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008641 }
8642 }
Romain Guy06882f82009-06-10 13:36:04 -07008643
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008644 // -------------------------------------------------------------
8645 // DummyAnimation
8646 // -------------------------------------------------------------
8647
8648 // This is an animation that does nothing: it just immediately finishes
8649 // itself every time it is called. It is used as a stub animation in cases
8650 // where we want to synchronize multiple things that may be animating.
8651 static final class DummyAnimation extends Animation {
8652 public boolean getTransformation(long currentTime, Transformation outTransformation) {
8653 return false;
8654 }
8655 }
8656 static final Animation sDummyAnimation = new DummyAnimation();
Romain Guy06882f82009-06-10 13:36:04 -07008657
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008658 // -------------------------------------------------------------
8659 // Async Handler
8660 // -------------------------------------------------------------
8661
8662 static final class StartingData {
8663 final String pkg;
8664 final int theme;
8665 final CharSequence nonLocalizedLabel;
8666 final int labelRes;
8667 final int icon;
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08008668 final int windowFlags;
Romain Guy06882f82009-06-10 13:36:04 -07008669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008670 StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08008671 int _labelRes, int _icon, int _windowFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008672 pkg = _pkg;
8673 theme = _theme;
8674 nonLocalizedLabel = _nonLocalizedLabel;
8675 labelRes = _labelRes;
8676 icon = _icon;
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08008677 windowFlags = _windowFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008678 }
8679 }
8680
8681 private final class H extends Handler {
8682 public static final int REPORT_FOCUS_CHANGE = 2;
8683 public static final int REPORT_LOSING_FOCUS = 3;
8684 public static final int ANIMATE = 4;
8685 public static final int ADD_STARTING = 5;
8686 public static final int REMOVE_STARTING = 6;
8687 public static final int FINISHED_STARTING = 7;
8688 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008689 public static final int WINDOW_FREEZE_TIMEOUT = 11;
8690 public static final int HOLD_SCREEN_CHANGED = 12;
8691 public static final int APP_TRANSITION_TIMEOUT = 13;
8692 public static final int PERSIST_ANIMATION_SCALE = 14;
8693 public static final int FORCE_GC = 15;
8694 public static final int ENABLE_SCREEN = 16;
8695 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008696 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008697 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07008698 public static final int DRAG_START_TIMEOUT = 20;
Chris Tated4533f142010-10-19 15:15:08 -07008699 public static final int DRAG_END_TIMEOUT = 21;
Romain Guy06882f82009-06-10 13:36:04 -07008700
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008701 private Session mLastReportedHold;
Romain Guy06882f82009-06-10 13:36:04 -07008702
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008703 public H() {
8704 }
Romain Guy06882f82009-06-10 13:36:04 -07008705
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008706 @Override
8707 public void handleMessage(Message msg) {
8708 switch (msg.what) {
8709 case REPORT_FOCUS_CHANGE: {
8710 WindowState lastFocus;
8711 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07008712
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008713 synchronized(mWindowMap) {
8714 lastFocus = mLastFocus;
8715 newFocus = mCurrentFocus;
8716 if (lastFocus == newFocus) {
8717 // Focus is not changing, so nothing to do.
8718 return;
8719 }
8720 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008721 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008722 // + " to " + newFocus);
8723 if (newFocus != null && lastFocus != null
8724 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008725 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008726 mLosingFocus.add(lastFocus);
8727 lastFocus = null;
8728 }
8729 }
8730
8731 if (lastFocus != newFocus) {
8732 //System.out.println("Changing focus from " + lastFocus
8733 // + " to " + newFocus);
8734 if (newFocus != null) {
8735 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008736 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008737 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
8738 } catch (RemoteException e) {
8739 // Ignore if process has died.
8740 }
Konstantin Lopyrev5e7833a2010-08-09 17:01:11 -07008741 notifyFocusChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008742 }
8743
8744 if (lastFocus != null) {
8745 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008746 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008747 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
8748 } catch (RemoteException e) {
8749 // Ignore if process has died.
8750 }
8751 }
8752 }
8753 } break;
8754
8755 case REPORT_LOSING_FOCUS: {
8756 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07008757
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008758 synchronized(mWindowMap) {
8759 losers = mLosingFocus;
8760 mLosingFocus = new ArrayList<WindowState>();
8761 }
8762
8763 final int N = losers.size();
8764 for (int i=0; i<N; i++) {
8765 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008766 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008767 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
8768 } catch (RemoteException e) {
8769 // Ignore if process has died.
8770 }
8771 }
8772 } break;
8773
8774 case ANIMATE: {
8775 synchronized(mWindowMap) {
8776 mAnimationPending = false;
8777 performLayoutAndPlaceSurfacesLocked();
8778 }
8779 } break;
8780
8781 case ADD_STARTING: {
8782 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8783 final StartingData sd = wtoken.startingData;
8784
8785 if (sd == null) {
8786 // Animation has been canceled... do nothing.
8787 return;
8788 }
Romain Guy06882f82009-06-10 13:36:04 -07008789
Joe Onorato8a9b2202010-02-26 18:56:32 -08008790 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008791 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07008792
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008793 View view = null;
8794 try {
8795 view = mPolicy.addStartingWindow(
8796 wtoken.token, sd.pkg,
8797 sd.theme, sd.nonLocalizedLabel, sd.labelRes,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08008798 sd.icon, sd.windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008799 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008800 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008801 }
8802
8803 if (view != null) {
8804 boolean abort = false;
8805
8806 synchronized(mWindowMap) {
8807 if (wtoken.removed || wtoken.startingData == null) {
8808 // If the window was successfully added, then
8809 // we need to remove it.
8810 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008811 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008812 "Aborted starting " + wtoken
8813 + ": removed=" + wtoken.removed
8814 + " startingData=" + wtoken.startingData);
8815 wtoken.startingWindow = null;
8816 wtoken.startingData = null;
8817 abort = true;
8818 }
8819 } else {
8820 wtoken.startingView = view;
8821 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008822 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008823 "Added starting " + wtoken
8824 + ": startingWindow="
8825 + wtoken.startingWindow + " startingView="
8826 + wtoken.startingView);
8827 }
8828
8829 if (abort) {
8830 try {
8831 mPolicy.removeStartingWindow(wtoken.token, view);
8832 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008833 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008834 }
8835 }
8836 }
8837 } break;
8838
8839 case REMOVE_STARTING: {
8840 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8841 IBinder token = null;
8842 View view = null;
8843 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008844 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008845 + wtoken + ": startingWindow="
8846 + wtoken.startingWindow + " startingView="
8847 + wtoken.startingView);
8848 if (wtoken.startingWindow != null) {
8849 view = wtoken.startingView;
8850 token = wtoken.token;
8851 wtoken.startingData = null;
8852 wtoken.startingView = null;
8853 wtoken.startingWindow = null;
8854 }
8855 }
8856 if (view != null) {
8857 try {
8858 mPolicy.removeStartingWindow(token, view);
8859 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008860 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008861 }
8862 }
8863 } break;
8864
8865 case FINISHED_STARTING: {
8866 IBinder token = null;
8867 View view = null;
8868 while (true) {
8869 synchronized (mWindowMap) {
8870 final int N = mFinishedStarting.size();
8871 if (N <= 0) {
8872 break;
8873 }
8874 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
8875
Joe Onorato8a9b2202010-02-26 18:56:32 -08008876 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008877 "Finished starting " + wtoken
8878 + ": startingWindow=" + wtoken.startingWindow
8879 + " startingView=" + wtoken.startingView);
8880
8881 if (wtoken.startingWindow == null) {
8882 continue;
8883 }
8884
8885 view = wtoken.startingView;
8886 token = wtoken.token;
8887 wtoken.startingData = null;
8888 wtoken.startingView = null;
8889 wtoken.startingWindow = null;
8890 }
8891
8892 try {
8893 mPolicy.removeStartingWindow(token, view);
8894 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008895 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008896 }
8897 }
8898 } break;
8899
8900 case REPORT_APPLICATION_TOKEN_WINDOWS: {
8901 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
8902
8903 boolean nowVisible = msg.arg1 != 0;
8904 boolean nowGone = msg.arg2 != 0;
8905
8906 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008907 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008908 TAG, "Reporting visible in " + wtoken
8909 + " visible=" + nowVisible
8910 + " gone=" + nowGone);
8911 if (nowVisible) {
8912 wtoken.appToken.windowsVisible();
8913 } else {
8914 wtoken.appToken.windowsGone();
8915 }
8916 } catch (RemoteException ex) {
8917 }
8918 } break;
Romain Guy06882f82009-06-10 13:36:04 -07008919
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008920 case WINDOW_FREEZE_TIMEOUT: {
8921 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008922 Slog.w(TAG, "Window freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008923 int i = mWindows.size();
8924 while (i > 0) {
8925 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07008926 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008927 if (w.mOrientationChanging) {
8928 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008929 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008930 }
8931 }
8932 performLayoutAndPlaceSurfacesLocked();
8933 }
8934 break;
8935 }
Romain Guy06882f82009-06-10 13:36:04 -07008936
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008937 case HOLD_SCREEN_CHANGED: {
8938 Session oldHold;
8939 Session newHold;
8940 synchronized (mWindowMap) {
8941 oldHold = mLastReportedHold;
8942 newHold = (Session)msg.obj;
8943 mLastReportedHold = newHold;
8944 }
Romain Guy06882f82009-06-10 13:36:04 -07008945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008946 if (oldHold != newHold) {
8947 try {
8948 if (oldHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008949 mBatteryStats.noteStopWakelock(oldHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008950 "window",
8951 BatteryStats.WAKE_TYPE_WINDOW);
8952 }
8953 if (newHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008954 mBatteryStats.noteStartWakelock(newHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008955 "window",
8956 BatteryStats.WAKE_TYPE_WINDOW);
8957 }
8958 } catch (RemoteException e) {
8959 }
8960 }
8961 break;
8962 }
Romain Guy06882f82009-06-10 13:36:04 -07008963
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008964 case APP_TRANSITION_TIMEOUT: {
8965 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07008966 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008967 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008968 "*** APP TRANSITION TIMEOUT");
8969 mAppTransitionReady = true;
8970 mAppTransitionTimeout = true;
8971 performLayoutAndPlaceSurfacesLocked();
8972 }
8973 }
8974 break;
8975 }
Romain Guy06882f82009-06-10 13:36:04 -07008976
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008977 case PERSIST_ANIMATION_SCALE: {
8978 Settings.System.putFloat(mContext.getContentResolver(),
8979 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
8980 Settings.System.putFloat(mContext.getContentResolver(),
8981 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
8982 break;
8983 }
Romain Guy06882f82009-06-10 13:36:04 -07008984
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008985 case FORCE_GC: {
8986 synchronized(mWindowMap) {
8987 if (mAnimationPending) {
8988 // If we are animating, don't do the gc now but
8989 // delay a bit so we don't interrupt the animation.
8990 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
8991 2000);
8992 return;
8993 }
8994 // If we are currently rotating the display, it will
8995 // schedule a new message when done.
8996 if (mDisplayFrozen) {
8997 return;
8998 }
8999 mFreezeGcPending = 0;
9000 }
9001 Runtime.getRuntime().gc();
9002 break;
9003 }
Romain Guy06882f82009-06-10 13:36:04 -07009004
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009005 case ENABLE_SCREEN: {
9006 performEnableScreen();
9007 break;
9008 }
Romain Guy06882f82009-06-10 13:36:04 -07009009
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009010 case APP_FREEZE_TIMEOUT: {
9011 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009012 Slog.w(TAG, "App freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009013 int i = mAppTokens.size();
9014 while (i > 0) {
9015 i--;
9016 AppWindowToken tok = mAppTokens.get(i);
9017 if (tok.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009018 Slog.w(TAG, "Force clearing freeze: " + tok);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009019 unsetAppFreezingScreenLocked(tok, true, true);
9020 }
9021 }
9022 }
9023 break;
9024 }
Romain Guy06882f82009-06-10 13:36:04 -07009025
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009026 case SEND_NEW_CONFIGURATION: {
9027 removeMessages(SEND_NEW_CONFIGURATION);
9028 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07009029 break;
9030 }
Romain Guy06882f82009-06-10 13:36:04 -07009031
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07009032 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07009033 if (mWindowsChanged) {
9034 synchronized (mWindowMap) {
9035 mWindowsChanged = false;
9036 }
9037 notifyWindowsChanged();
9038 }
9039 break;
9040 }
9041
Christopher Tatea53146c2010-09-07 11:57:52 -07009042 case DRAG_START_TIMEOUT: {
9043 IBinder win = (IBinder)msg.obj;
9044 if (DEBUG_DRAG) {
9045 Slog.w(TAG, "Timeout starting drag by win " + win);
9046 }
9047 synchronized (mWindowMap) {
9048 // !!! TODO: ANR the app that has failed to start the drag in time
9049 if (mDragState != null) {
Chris Tated4533f142010-10-19 15:15:08 -07009050 mDragState.unregister();
9051 mInputMonitor.updateInputWindowsLw();
Christopher Tatea53146c2010-09-07 11:57:52 -07009052 mDragState.reset();
9053 mDragState = null;
9054 }
9055 }
Chris Tated4533f142010-10-19 15:15:08 -07009056 break;
Christopher Tatea53146c2010-09-07 11:57:52 -07009057 }
9058
Chris Tated4533f142010-10-19 15:15:08 -07009059 case DRAG_END_TIMEOUT: {
9060 IBinder win = (IBinder)msg.obj;
9061 if (DEBUG_DRAG) {
9062 Slog.w(TAG, "Timeout ending drag to win " + win);
9063 }
9064 synchronized (mWindowMap) {
9065 // !!! TODO: ANR the drag-receiving app
9066 mDragState.mDragResult = false;
9067 mDragState.endDragLw();
9068 }
9069 break;
9070 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009071 }
9072 }
9073 }
9074
9075 // -------------------------------------------------------------
9076 // IWindowManager API
9077 // -------------------------------------------------------------
9078
9079 public IWindowSession openSession(IInputMethodClient client,
9080 IInputContext inputContext) {
9081 if (client == null) throw new IllegalArgumentException("null client");
9082 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07009083 Session session = new Session(client, inputContext);
9084 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009085 }
9086
9087 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
9088 synchronized (mWindowMap) {
9089 // The focus for the client is the window immediately below
9090 // where we would place the input method window.
9091 int idx = findDesiredInputMethodWindowIndexLocked(false);
9092 WindowState imFocus;
9093 if (idx > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07009094 imFocus = mWindows.get(idx-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009095 if (imFocus != null) {
9096 if (imFocus.mSession.mClient != null &&
9097 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
9098 return true;
9099 }
9100 }
9101 }
9102 }
9103 return false;
9104 }
Romain Guy06882f82009-06-10 13:36:04 -07009105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009106 // -------------------------------------------------------------
9107 // Internals
9108 // -------------------------------------------------------------
9109
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009110 final WindowState windowForClientLocked(Session session, IWindow client,
9111 boolean throwOnError) {
9112 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009113 }
Romain Guy06882f82009-06-10 13:36:04 -07009114
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009115 final WindowState windowForClientLocked(Session session, IBinder client,
9116 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009117 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009118 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009119 TAG, "Looking up client " + client + ": " + win);
9120 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009121 RuntimeException ex = new IllegalArgumentException(
9122 "Requested window " + client + " does not exist");
9123 if (throwOnError) {
9124 throw ex;
9125 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009126 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009127 return null;
9128 }
9129 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009130 RuntimeException ex = new IllegalArgumentException(
9131 "Requested window " + client + " is in session " +
9132 win.mSession + ", not " + session);
9133 if (throwOnError) {
9134 throw ex;
9135 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009136 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009137 return null;
9138 }
9139
9140 return win;
9141 }
9142
Dianne Hackborna8f60182009-09-01 19:01:50 -07009143 final void rebuildAppWindowListLocked() {
9144 int NW = mWindows.size();
9145 int i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009146 int lastWallpaper = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009147 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009148
Dianne Hackborna8f60182009-09-01 19:01:50 -07009149 // First remove all existing app windows.
9150 i=0;
9151 while (i < NW) {
Jeff Browne33348b2010-07-15 23:54:05 -07009152 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009153 if (w.mAppToken != null) {
Jeff Browne33348b2010-07-15 23:54:05 -07009154 WindowState win = mWindows.remove(i);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07009155 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009156 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009157 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07009158 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009159 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009160 continue;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009161 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER
9162 && lastWallpaper == i-1) {
9163 lastWallpaper = i;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009164 }
9165 i++;
9166 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009167
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009168 // The wallpaper window(s) typically live at the bottom of the stack,
9169 // so skip them before adding app tokens.
9170 lastWallpaper++;
9171 i = lastWallpaper;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009172
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009173 // First add all of the exiting app tokens... these are no longer
9174 // in the main app list, but still have windows shown. We put them
9175 // in the back because now that the animation is over we no longer
9176 // will care about them.
9177 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009178 for (int j=0; j<NT; j++) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009179 i = reAddAppWindowsLocked(i, mExitingAppTokens.get(j));
9180 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009181
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009182 // And add in the still active app tokens in Z order.
9183 NT = mAppTokens.size();
9184 for (int j=0; j<NT; j++) {
9185 i = reAddAppWindowsLocked(i, mAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07009186 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009187
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009188 i -= lastWallpaper;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009189 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009190 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009191 + " windows but added " + i);
9192 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07009193 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009194
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009195 private final void assignLayersLocked() {
9196 int N = mWindows.size();
9197 int curBaseLayer = 0;
9198 int curLayer = 0;
9199 int i;
Romain Guy06882f82009-06-10 13:36:04 -07009200
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009201 if (DEBUG_LAYERS) {
9202 RuntimeException here = new RuntimeException("here");
9203 here.fillInStackTrace();
9204 Log.v(TAG, "Assigning layers", here);
9205 }
9206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009207 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07009208 WindowState w = mWindows.get(i);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009209 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
9210 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009211 curLayer += WINDOW_LAYER_MULTIPLIER;
9212 w.mLayer = curLayer;
9213 } else {
9214 curBaseLayer = curLayer = w.mBaseLayer;
9215 w.mLayer = curLayer;
9216 }
9217 if (w.mTargetAppToken != null) {
9218 w.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
9219 } else if (w.mAppToken != null) {
9220 w.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
9221 } else {
9222 w.mAnimLayer = w.mLayer;
9223 }
9224 if (w.mIsImWindow) {
9225 w.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07009226 } else if (w.mIsWallpaper) {
9227 w.mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009228 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009229 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009230 + w.mAnimLayer);
9231 //System.out.println(
9232 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
9233 }
9234 }
9235
9236 private boolean mInLayout = false;
9237 private final void performLayoutAndPlaceSurfacesLocked() {
9238 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07009239 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009240 throw new RuntimeException("Recursive call!");
9241 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009242 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009243 return;
9244 }
9245
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009246 if (mWaitingForConfig) {
9247 // Our configuration has changed (most likely rotation), but we
9248 // don't yet have the complete configuration to report to
9249 // applications. Don't do any window layout until we have it.
9250 return;
9251 }
9252
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009253 if (mDisplay == null) {
9254 // Not yet initialized, nothing to do.
9255 return;
9256 }
9257
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08009258 mInLayout = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009259 boolean recoveringMemory = false;
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08009260
9261 try {
9262 if (mForceRemoves != null) {
9263 recoveringMemory = true;
9264 // Wait a little it for things to settle down, and off we go.
9265 for (int i=0; i<mForceRemoves.size(); i++) {
9266 WindowState ws = mForceRemoves.get(i);
9267 Slog.i(TAG, "Force removing: " + ws);
9268 removeWindowInnerLocked(ws.mSession, ws);
9269 }
9270 mForceRemoves = null;
9271 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
9272 Object tmp = new Object();
9273 synchronized (tmp) {
9274 try {
9275 tmp.wait(250);
9276 } catch (InterruptedException e) {
9277 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009278 }
9279 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08009280 } catch (RuntimeException e) {
9281 Slog.e(TAG, "Unhandled exception while force removing for memory", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009282 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08009283
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009284 try {
9285 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Romain Guy06882f82009-06-10 13:36:04 -07009286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009287 int i = mPendingRemove.size()-1;
9288 if (i >= 0) {
9289 while (i >= 0) {
9290 WindowState w = mPendingRemove.get(i);
9291 removeWindowInnerLocked(w.mSession, w);
9292 i--;
9293 }
9294 mPendingRemove.clear();
9295
9296 mInLayout = false;
9297 assignLayersLocked();
9298 mLayoutNeeded = true;
9299 performLayoutAndPlaceSurfacesLocked();
9300
9301 } else {
9302 mInLayout = false;
9303 if (mLayoutNeeded) {
9304 requestAnimationLocked(0);
9305 }
9306 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07009307 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07009308 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
9309 mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07009310 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009311 } catch (RuntimeException e) {
9312 mInLayout = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009313 Slog.e(TAG, "Unhandled exception while layout out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009314 }
9315 }
9316
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009317 private final int performLayoutLockedInner(boolean initial) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009318 if (!mLayoutNeeded) {
9319 return 0;
9320 }
9321
9322 mLayoutNeeded = false;
9323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009324 final int dw = mDisplay.getWidth();
9325 final int dh = mDisplay.getHeight();
9326
9327 final int N = mWindows.size();
9328 int i;
9329
Joe Onorato8a9b2202010-02-26 18:56:32 -08009330 if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
Dianne Hackborn9b52a212009-12-11 14:51:35 -08009331 + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
9332
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009333 mPolicy.beginLayoutLw(dw, dh);
Romain Guy06882f82009-06-10 13:36:04 -07009334
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009335 int seq = mLayoutSeq+1;
9336 if (seq < 0) seq = 0;
9337 mLayoutSeq = seq;
9338
9339 // First perform layout of any root windows (not attached
9340 // to another window).
9341 int topAttached = -1;
9342 for (i = N-1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009343 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009344
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009345 // Don't do layout of a window if it is not visible, or
9346 // soon won't be visible, to avoid wasting time and funky
9347 // changes while a window is animating away.
9348 final AppWindowToken atoken = win.mAppToken;
9349 final boolean gone = win.mViewVisibility == View.GONE
9350 || !win.mRelayoutCalled
9351 || win.mRootToken.hidden
9352 || (atoken != null && atoken.hiddenRequested)
9353 || win.mAttachedHidden
9354 || win.mExiting || win.mDestroying;
9355
Dianne Hackborn1c24e952010-11-23 00:34:30 -08009356 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
9357 Slog.v(TAG, "First pass " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009358 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
9359 + " mLayoutAttached=" + win.mLayoutAttached);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08009360 if (gone) Slog.v(TAG, " (mViewVisibility="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009361 + win.mViewVisibility + " mRelayoutCalled="
9362 + win.mRelayoutCalled + " hidden="
9363 + win.mRootToken.hidden + " hiddenRequested="
9364 + (atoken != null && atoken.hiddenRequested)
9365 + " mAttachedHidden=" + win.mAttachedHidden);
9366 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009367
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009368 // If this view is GONE, then skip it -- keep the current
9369 // frame, and let the caller know so they can ignore it
9370 // if they want. (We do the normal layout for INVISIBLE
9371 // windows, since that means "perform layout as normal,
9372 // just don't display").
9373 if (!gone || !win.mHaveFrame) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08009374 if (!win.mLayoutAttached) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009375 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08009376 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009377 win.mContentChanged = false;
9378 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009379 mPolicy.layoutWindowLw(win, win.mAttrs, null);
9380 win.mLayoutSeq = seq;
9381 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
9382 + win.mFrame + " mContainingFrame="
9383 + win.mContainingFrame + " mDisplayFrame="
9384 + win.mDisplayFrame);
9385 } else {
9386 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009387 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07009388 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009389 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009390
9391 // Now perform layout of attached windows, which usually
9392 // depend on the position of the window they are attached to.
9393 // XXX does not deal with windows that are attached to windows
9394 // that are themselves attached.
9395 for (i = topAttached; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009396 WindowState win = mWindows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009397
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009398 if (win.mLayoutAttached) {
9399 if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
9400 + " mHaveFrame=" + win.mHaveFrame
9401 + " mViewVisibility=" + win.mViewVisibility
9402 + " mRelayoutCalled=" + win.mRelayoutCalled);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08009403 // If this view is GONE, then skip it -- keep the current
9404 // frame, and let the caller know so they can ignore it
9405 // if they want. (We do the normal layout for INVISIBLE
9406 // windows, since that means "perform layout as normal,
9407 // just don't display").
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009408 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
9409 || !win.mHaveFrame) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009410 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08009411 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009412 win.mContentChanged = false;
9413 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009414 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
9415 win.mLayoutSeq = seq;
9416 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
9417 + win.mFrame + " mContainingFrame="
9418 + win.mContainingFrame + " mDisplayFrame="
9419 + win.mDisplayFrame);
9420 }
9421 }
9422 }
Jeff Brown349703e2010-06-22 01:27:15 -07009423
9424 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown00fa7bd2010-07-02 15:37:36 -07009425 mInputMonitor.updateInputWindowsLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009426
9427 return mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009428 }
Romain Guy06882f82009-06-10 13:36:04 -07009429
Brad Fitzpatrick68044332010-11-22 18:19:48 -08009430 // "Something has changed! Let's make it correct now."
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009431 private final void performLayoutAndPlaceSurfacesLockedInner(
9432 boolean recoveringMemory) {
Joe Onorato34bcebc2010-07-07 18:05:01 -04009433 if (mDisplay == null) {
9434 Slog.i(TAG, "skipping performLayoutAndPlaceSurfacesLockedInner with no mDisplay");
9435 return;
9436 }
9437
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009438 final long currentTime = SystemClock.uptimeMillis();
9439 final int dw = mDisplay.getWidth();
9440 final int dh = mDisplay.getHeight();
9441
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009442 int i;
9443
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009444 if (mFocusMayChange) {
9445 mFocusMayChange = false;
9446 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
9447 }
9448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009449 // Initialize state of exiting tokens.
9450 for (i=mExitingTokens.size()-1; i>=0; i--) {
9451 mExitingTokens.get(i).hasVisible = false;
9452 }
9453
9454 // Initialize state of exiting applications.
9455 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
9456 mExitingAppTokens.get(i).hasVisible = false;
9457 }
9458
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009459 boolean orientationChangeComplete = true;
9460 Session holdScreen = null;
9461 float screenBrightness = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009462 float buttonBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009463 boolean focusDisplayed = false;
9464 boolean animating = false;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009465 boolean createWatermark = false;
9466
9467 if (mFxSession == null) {
9468 mFxSession = new SurfaceSession();
9469 createWatermark = true;
9470 }
9471
9472 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009473
9474 Surface.openTransaction();
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009475
9476 if (createWatermark) {
9477 createWatermark();
9478 }
9479 if (mWatermark != null) {
9480 mWatermark.positionSurface(dw, dh);
9481 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08009482 if (mStrictModeFlash != null) {
9483 mStrictModeFlash.positionSurface(dw, dh);
9484 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009486 try {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009487 boolean wallpaperForceHidingChanged = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009488 int repeats = 0;
9489 int changes = 0;
9490
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009491 do {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009492 repeats++;
9493 if (repeats > 6) {
9494 Slog.w(TAG, "Animation repeat aborted after too many iterations");
9495 mLayoutNeeded = false;
9496 break;
9497 }
9498
9499 if ((changes&(WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER
9500 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG
9501 | WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
9502 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
9503 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
9504 assignLayersLocked();
9505 mLayoutNeeded = true;
9506 }
9507 }
9508 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
9509 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
9510 if (updateOrientationFromAppTokensLocked()) {
9511 mLayoutNeeded = true;
9512 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
9513 }
9514 }
9515 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
9516 mLayoutNeeded = true;
9517 }
9518 }
9519
9520 // FIRST LOOP: Perform a layout, if needed.
9521 if (repeats < 4) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009522 changes = performLayoutLockedInner(repeats == 0);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009523 if (changes != 0) {
9524 continue;
9525 }
9526 } else {
9527 Slog.w(TAG, "Layout repeat skipped after too many iterations");
9528 changes = 0;
9529 }
9530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009531 final int transactionSequence = ++mTransactionSequence;
9532
9533 // Update animations of all applications, including those
9534 // associated with exiting/removed apps
9535 boolean tokensAnimating = false;
9536 final int NAT = mAppTokens.size();
9537 for (i=0; i<NAT; i++) {
9538 if (mAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
9539 tokensAnimating = true;
9540 }
9541 }
9542 final int NEAT = mExitingAppTokens.size();
9543 for (i=0; i<NEAT; i++) {
9544 if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
9545 tokensAnimating = true;
9546 }
9547 }
9548
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009549 // SECOND LOOP: Execute animations and update visibility of windows.
9550
Joe Onorato8a9b2202010-02-26 18:56:32 -08009551 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009552 + transactionSequence + " tokensAnimating="
9553 + tokensAnimating);
9554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009555 animating = tokensAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009556
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08009557 if (mScreenRotationAnimation != null) {
9558 if (mScreenRotationAnimation.isAnimating()) {
9559 if (mScreenRotationAnimation.stepAnimation(currentTime)) {
9560 animating = true;
9561 } else {
9562 mScreenRotationAnimation = null;
9563 }
9564 }
9565 }
9566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009567 boolean tokenMayBeDrawn = false;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009568 boolean wallpaperMayChange = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009569 boolean forceHiding = false;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009570 WindowState windowDetachedWallpaper = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009571
9572 mPolicy.beginAnimationLw(dw, dh);
9573
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07009574 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009576 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07009577 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009578
9579 final WindowManager.LayoutParams attrs = w.mAttrs;
9580
9581 if (w.mSurface != null) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009582 // Take care of the window being ready to display.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009583 if (w.commitFinishDrawingLocked(currentTime)) {
9584 if ((w.mAttrs.flags
9585 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009586 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009587 "First draw done in potential wallpaper target " + w);
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009588 wallpaperMayChange = true;
9589 }
9590 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009591
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009592 final boolean wasAnimating = w.mAnimating;
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009593
9594 int animDw = dw;
9595 int animDh = dh;
9596
9597 // If the window has moved due to its containing
9598 // content frame changing, then we'd like to animate
9599 // it. The checks here are ordered by what is least
Joe Onorato3fe7f2f2010-11-20 13:48:58 -08009600 // likely to be true first.
Dianne Hackborn1c24e952010-11-23 00:34:30 -08009601 if (w.shouldAnimateMove()) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08009602 // Frame has moved, containing content frame
9603 // has also moved, and we're not currently animating...
9604 // let's do something.
9605 Animation a = AnimationUtils.loadAnimation(mContext,
9606 com.android.internal.R.anim.window_move_from_decor);
9607 w.setAnimation(a);
9608 animDw = w.mLastFrame.left - w.mFrame.left;
9609 animDh = w.mLastFrame.top - w.mFrame.top;
9610 }
9611
9612 // Execute animation.
9613 final boolean nowAnimating = w.stepAnimationLocked(currentTime,
9614 animDw, animDh);
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009615
9616 // If this window is animating, make a note that we have
9617 // an animating window and take care of a request to run
9618 // a detached wallpaper animation.
9619 if (nowAnimating) {
9620 if (w.mAnimation != null && w.mAnimation.getDetachWallpaper()) {
9621 windowDetachedWallpaper = w;
9622 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009623 animating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009624 }
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009625
9626 // If this window's app token is running a detached wallpaper
9627 // animation, make a note so we can ensure the wallpaper is
9628 // displayed behind it.
9629 if (w.mAppToken != null && w.mAppToken.animation != null
9630 && w.mAppToken.animation.getDetachWallpaper()) {
9631 windowDetachedWallpaper = w;
9632 }
9633
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07009634 if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
9635 wallpaperMayChange = true;
9636 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009637
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009638 if (mPolicy.doesForceHide(w, attrs)) {
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009639 if (!wasAnimating && nowAnimating) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009640 if (DEBUG_VISIBILITY) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08009641 "Animation started that could impact force hide: "
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009642 + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009643 wallpaperForceHidingChanged = true;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009644 mFocusMayChange = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009645 } else if (w.isReadyForDisplay() && w.mAnimation == null) {
9646 forceHiding = true;
9647 }
9648 } else if (mPolicy.canBeForceHidden(w, attrs)) {
9649 boolean changed;
9650 if (forceHiding) {
9651 changed = w.hideLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009652 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
9653 "Now policy hidden: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009654 } else {
9655 changed = w.showLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009656 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
9657 "Now policy shown: " + w);
9658 if (changed) {
9659 if (wallpaperForceHidingChanged
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009660 && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009661 // Assume we will need to animate. If
9662 // we don't (because the wallpaper will
9663 // stay with the lock screen), then we will
9664 // clean up later.
9665 Animation a = mPolicy.createForceHideEnterAnimation();
9666 if (a != null) {
9667 w.setAnimation(a);
9668 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009669 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08009670 if (mCurrentFocus == null ||
9671 mCurrentFocus.mLayer < w.mLayer) {
9672 // We are showing on to of the current
9673 // focus, so re-evaluate focus to make
9674 // sure it is correct.
9675 mFocusMayChange = true;
9676 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009677 }
9678 }
9679 if (changed && (attrs.flags
9680 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
9681 wallpaperMayChange = true;
9682 }
9683 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009684
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009685 mPolicy.animatingWindowLw(w, attrs);
9686 }
9687
9688 final AppWindowToken atoken = w.mAppToken;
9689 if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
9690 if (atoken.lastTransactionSequence != transactionSequence) {
9691 atoken.lastTransactionSequence = transactionSequence;
9692 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
9693 atoken.startingDisplayed = false;
9694 }
9695 if ((w.isOnScreen() || w.mAttrs.type
9696 == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
9697 && !w.mExiting && !w.mDestroying) {
9698 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009699 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009700 + w.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009701 + ", isAnimating=" + w.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009702 if (!w.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009703 Slog.v(TAG, "Not displayed: s=" + w.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009704 + " pv=" + w.mPolicyVisibility
9705 + " dp=" + w.mDrawPending
9706 + " cdp=" + w.mCommitDrawPending
9707 + " ah=" + w.mAttachedHidden
9708 + " th=" + atoken.hiddenRequested
9709 + " a=" + w.mAnimating);
9710 }
9711 }
9712 if (w != atoken.startingWindow) {
9713 if (!atoken.freezingScreen || !w.mAppFreezing) {
9714 atoken.numInterestingWindows++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009715 if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009716 atoken.numDrawnWindows++;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009717 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009718 "tokenMayBeDrawn: " + atoken
9719 + " freezingScreen=" + atoken.freezingScreen
9720 + " mAppFreezing=" + w.mAppFreezing);
9721 tokenMayBeDrawn = true;
9722 }
9723 }
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07009724 } else if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009725 atoken.startingDisplayed = true;
9726 }
9727 }
9728 } else if (w.mReadyToShow) {
9729 w.performShowLocked();
9730 }
9731 }
9732
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009733 changes |= mPolicy.finishAnimationLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009734
9735 if (tokenMayBeDrawn) {
9736 // See if any windows have been drawn, so they (and others
9737 // associated with them) can now be shown.
9738 final int NT = mTokenList.size();
9739 for (i=0; i<NT; i++) {
9740 AppWindowToken wtoken = mTokenList.get(i).appWindowToken;
9741 if (wtoken == null) {
9742 continue;
9743 }
9744 if (wtoken.freezingScreen) {
9745 int numInteresting = wtoken.numInterestingWindows;
9746 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009747 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009748 "allDrawn: " + wtoken
9749 + " interesting=" + numInteresting
9750 + " drawn=" + wtoken.numDrawnWindows);
9751 wtoken.showAllWindowsLocked();
9752 unsetAppFreezingScreenLocked(wtoken, false, true);
9753 orientationChangeComplete = true;
9754 }
9755 } else if (!wtoken.allDrawn) {
9756 int numInteresting = wtoken.numInterestingWindows;
9757 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009758 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009759 "allDrawn: " + wtoken
9760 + " interesting=" + numInteresting
9761 + " drawn=" + wtoken.numDrawnWindows);
9762 wtoken.allDrawn = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009763 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009764
9765 // We can now show all of the drawn windows!
9766 if (!mOpeningApps.contains(wtoken)) {
9767 wtoken.showAllWindowsLocked();
9768 }
9769 }
9770 }
9771 }
9772 }
9773
9774 // If we are ready to perform an app transition, check through
9775 // all of the app tokens to be shown and see if they are ready
9776 // to go.
9777 if (mAppTransitionReady) {
9778 int NN = mOpeningApps.size();
9779 boolean goodToGo = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009780 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009781 "Checking " + NN + " opening apps (frozen="
9782 + mDisplayFrozen + " timeout="
9783 + mAppTransitionTimeout + ")...");
9784 if (!mDisplayFrozen && !mAppTransitionTimeout) {
9785 // If the display isn't frozen, wait to do anything until
9786 // all of the apps are ready. Otherwise just go because
9787 // we'll unfreeze the display when everyone is ready.
9788 for (i=0; i<NN && goodToGo; i++) {
9789 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009790 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009791 "Check opening app" + wtoken + ": allDrawn="
9792 + wtoken.allDrawn + " startingDisplayed="
9793 + wtoken.startingDisplayed);
9794 if (!wtoken.allDrawn && !wtoken.startingDisplayed
9795 && !wtoken.startingMoved) {
9796 goodToGo = false;
9797 }
9798 }
9799 }
9800 if (goodToGo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009801 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009802 int transit = mNextAppTransition;
9803 if (mSkipAppTransitionAnimation) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009804 transit = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009805 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07009806 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009807 mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009808 mAppTransitionRunning = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009809 mAppTransitionTimeout = false;
9810 mStartingIconInTransition = false;
9811 mSkipAppTransitionAnimation = false;
9812
9813 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
9814
Dianne Hackborna8f60182009-09-01 19:01:50 -07009815 // If there are applications waiting to come to the
9816 // top of the stack, now is the time to move their windows.
9817 // (Note that we don't do apps going to the bottom
9818 // here -- we want to keep their windows in the old
9819 // Z-order until the animation completes.)
9820 if (mToTopApps.size() > 0) {
9821 NN = mAppTokens.size();
9822 for (i=0; i<NN; i++) {
9823 AppWindowToken wtoken = mAppTokens.get(i);
9824 if (wtoken.sendingToTop) {
9825 wtoken.sendingToTop = false;
9826 moveAppWindowsLocked(wtoken, NN, false);
9827 }
9828 }
9829 mToTopApps.clear();
9830 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009831
Dianne Hackborn25994b42009-09-04 14:21:19 -07009832 WindowState oldWallpaper = mWallpaperTarget;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009833
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009834 adjustWallpaperWindowsLocked();
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07009835 wallpaperMayChange = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009836
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009837 // The top-most window will supply the layout params,
9838 // and we will determine it below.
9839 LayoutParams animLp = null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009840 AppWindowToken animToken = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009841 int bestAnimLayer = -1;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009842
Joe Onorato8a9b2202010-02-26 18:56:32 -08009843 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07009844 "New wallpaper target=" + mWallpaperTarget
9845 + ", lower target=" + mLowerWallpaperTarget
9846 + ", upper target=" + mUpperWallpaperTarget);
Dianne Hackborn25994b42009-09-04 14:21:19 -07009847 int foundWallpapers = 0;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009848 // Do a first pass through the tokens for two
9849 // things:
9850 // (1) Determine if both the closing and opening
9851 // app token sets are wallpaper targets, in which
9852 // case special animations are needed
9853 // (since the wallpaper needs to stay static
9854 // behind them).
9855 // (2) Find the layout params of the top-most
9856 // application window in the tokens, which is
9857 // what will control the animation theme.
9858 final int NC = mClosingApps.size();
9859 NN = NC + mOpeningApps.size();
9860 for (i=0; i<NN; i++) {
9861 AppWindowToken wtoken;
9862 int mode;
9863 if (i < NC) {
9864 wtoken = mClosingApps.get(i);
9865 mode = 1;
9866 } else {
9867 wtoken = mOpeningApps.get(i-NC);
9868 mode = 2;
9869 }
9870 if (mLowerWallpaperTarget != null) {
9871 if (mLowerWallpaperTarget.mAppToken == wtoken
9872 || mUpperWallpaperTarget.mAppToken == wtoken) {
9873 foundWallpapers |= mode;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07009874 }
9875 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009876 if (wtoken.appFullscreen) {
9877 WindowState ws = wtoken.findMainWindow();
9878 if (ws != null) {
9879 // If this is a compatibility mode
9880 // window, we will always use its anim.
9881 if ((ws.mAttrs.flags&FLAG_COMPATIBLE_WINDOW) != 0) {
9882 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009883 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009884 bestAnimLayer = Integer.MAX_VALUE;
9885 } else if (ws.mLayer > bestAnimLayer) {
9886 animLp = ws.mAttrs;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07009887 animToken = ws.mAppToken;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009888 bestAnimLayer = ws.mLayer;
9889 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07009890 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07009891 }
9892 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009893
Dianne Hackborn25994b42009-09-04 14:21:19 -07009894 if (foundWallpapers == 3) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009895 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009896 "Wallpaper animation!");
9897 switch (transit) {
9898 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
9899 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
9900 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
9901 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
9902 break;
9903 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
9904 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
9905 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
9906 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
9907 break;
9908 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009909 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009910 "New transit: " + transit);
9911 } else if (oldWallpaper != null) {
9912 // We are transitioning from an activity with
9913 // a wallpaper to one without.
9914 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009915 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009916 "New transit away from wallpaper: " + transit);
9917 } else if (mWallpaperTarget != null) {
9918 // We are transitioning from an activity without
9919 // a wallpaper to now showing the wallpaper
9920 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009921 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07009922 "New transit into wallpaper: " + transit);
9923 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009924
Dianne Hackbornde2606d2009-12-18 16:53:55 -08009925 // If all closing windows are obscured, then there is
9926 // no need to do an animation. This is the case, for
9927 // example, when this transition is being done behind
9928 // the lock screen.
9929 if (!mPolicy.allowAppAnimationsLw()) {
9930 animLp = null;
9931 }
9932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009933 NN = mOpeningApps.size();
9934 for (i=0; i<NN; i++) {
9935 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009936 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009937 "Now opening app" + wtoken);
9938 wtoken.reportedVisible = false;
9939 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07009940 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009941 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009942 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009943 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009944 wtoken.showAllWindowsLocked();
9945 }
9946 NN = mClosingApps.size();
9947 for (i=0; i<NN; i++) {
9948 AppWindowToken wtoken = mClosingApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009949 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009950 "Now closing app" + wtoken);
9951 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07009952 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07009953 setTokenVisibilityLocked(wtoken, animLp, false, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009954 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07009955 wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009956 // Force the allDrawn flag, because we want to start
9957 // this guy's animations regardless of whether it's
9958 // gotten drawn.
9959 wtoken.allDrawn = true;
9960 }
9961
Dianne Hackborn8b571a82009-09-25 16:09:43 -07009962 mNextAppTransitionPackage = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009963
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009964 mOpeningApps.clear();
9965 mClosingApps.clear();
9966
9967 // This has changed the visibility of windows, so perform
9968 // a new layout to get them all up-to-date.
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009969 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009970 mLayoutNeeded = true;
Dianne Hackborn20583ff2009-07-27 21:51:05 -07009971 if (!moveInputMethodWindowsIfNeededLocked(true)) {
9972 assignLayersLocked();
9973 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009974 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009975 mFocusMayChange = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009976 }
9977 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009978
Dianne Hackborn16064f92010-03-25 00:47:24 -07009979 int adjResult = 0;
9980
Dianne Hackborna8f60182009-09-01 19:01:50 -07009981 if (!animating && mAppTransitionRunning) {
9982 // We have finished the animation of an app transition. To do
9983 // this, we have delayed a lot of operations like showing and
9984 // hiding apps, moving apps in Z-order, etc. The app token list
9985 // reflects the correct Z-order, but the window list may now
9986 // be out of sync with it. So here we will just rebuild the
9987 // entire app window list. Fun!
9988 mAppTransitionRunning = false;
9989 // Clear information about apps that were moving.
9990 mToBottomApps.clear();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009991
Dianne Hackborna8f60182009-09-01 19:01:50 -07009992 rebuildAppWindowListLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08009993 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn16064f92010-03-25 00:47:24 -07009994 adjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborna8f60182009-09-01 19:01:50 -07009995 moveInputMethodWindowsIfNeededLocked(false);
9996 wallpaperMayChange = true;
Suchi Amalapurapuc9568e32009-11-05 18:51:16 -08009997 // Since the window list has been rebuilt, focus might
9998 // have to be recomputed since the actual order of windows
9999 // might have changed again.
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010000 mFocusMayChange = true;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010001 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010002
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010003 if (wallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010004 // At this point, there was a window with a wallpaper that
10005 // was force hiding other windows behind it, but now it
10006 // is going away. This may be simple -- just animate
10007 // away the wallpaper and its window -- or it may be
10008 // hard -- the wallpaper now needs to be shown behind
10009 // something that was hidden.
10010 WindowState oldWallpaper = mWallpaperTarget;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010011 if (mLowerWallpaperTarget != null
10012 && mLowerWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010013 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010014 "wallpaperForceHiding changed with lower="
10015 + mLowerWallpaperTarget);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010016 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010017 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
10018 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
10019 if (mLowerWallpaperTarget.mAppToken.hidden) {
10020 // The lower target has become hidden before we
10021 // actually started the animation... let's completely
10022 // re-evaluate everything.
10023 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010024 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010025 }
10026 }
Dianne Hackborn16064f92010-03-25 00:47:24 -070010027 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010028 wallpaperMayChange = false;
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010029 wallpaperForceHidingChanged = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010030 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010031 + " NEW: " + mWallpaperTarget
10032 + " LOWER: " + mLowerWallpaperTarget);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010033 if (mLowerWallpaperTarget == null) {
10034 // Whoops, we don't need a special wallpaper animation.
10035 // Clear them out.
10036 forceHiding = false;
10037 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -070010038 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010039 if (w.mSurface != null) {
10040 final WindowManager.LayoutParams attrs = w.mAttrs;
Suchi Amalapurapuc03d28b2009-10-28 14:32:05 -070010041 if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010042 if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010043 forceHiding = true;
10044 } else if (mPolicy.canBeForceHidden(w, attrs)) {
10045 if (!w.mAnimating) {
10046 // We set the animation above so it
10047 // is not yet running.
10048 w.clearAnimation();
10049 }
10050 }
10051 }
10052 }
10053 }
10054 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010055
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -080010056 if (mWindowDetachedWallpaper != windowDetachedWallpaper) {
10057 if (DEBUG_WALLPAPER) Slog.v(TAG,
10058 "Detached wallpaper changed from " + mWindowDetachedWallpaper
10059 + windowDetachedWallpaper);
10060 mWindowDetachedWallpaper = windowDetachedWallpaper;
10061 wallpaperMayChange = true;
10062 }
10063
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010064 if (wallpaperMayChange) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010065 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010066 "Wallpaper may change! Adjusting");
Dianne Hackborn16064f92010-03-25 00:47:24 -070010067 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010068 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010069
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010070 if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010071 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010072 "Wallpaper layer changed: assigning layers + relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010073 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010074 assignLayersLocked();
10075 } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010076 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010077 "Wallpaper visibility changed: relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010078 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010079 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010080
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010081 if (mFocusMayChange) {
10082 mFocusMayChange = false;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010083 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010084 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010085 adjResult = 0;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010086 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010087 }
10088
10089 if (mLayoutNeeded) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010090 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -070010091 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010092
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010093 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
10094 + Integer.toHexString(changes));
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010095
Jeff Browne33348b2010-07-15 23:54:05 -070010096 mInputMonitor.updateInputWindowsLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010097 } while (changes != 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010098
10099 // THIRD LOOP: Update the surfaces of all windows.
10100
10101 final boolean someoneLosingFocus = mLosingFocus.size() != 0;
10102
10103 boolean obscured = false;
10104 boolean blurring = false;
10105 boolean dimming = false;
10106 boolean covered = false;
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010107 boolean syswin = false;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010108 boolean backgroundFillerShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010109
Dianne Hackbornbdd52b22009-09-02 21:46:19 -070010110 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010111
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010112 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -070010113 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010114
10115 boolean displayed = false;
10116 final WindowManager.LayoutParams attrs = w.mAttrs;
10117 final int attrFlags = attrs.flags;
10118
10119 if (w.mSurface != null) {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010120 // XXX NOTE: The logic here could be improved. We have
10121 // the decision about whether to resize a window separated
10122 // from whether to hide the surface. This can cause us to
10123 // resize a surface even if we are going to hide it. You
10124 // can see this by (1) holding device in landscape mode on
10125 // home screen; (2) tapping browser icon (device will rotate
10126 // to landscape; (3) tap home. The wallpaper will be resized
10127 // in step 2 but then immediately hidden, causing us to
10128 // have to resize and then redraw it again in step 3. It
10129 // would be nice to figure out how to avoid this, but it is
10130 // difficult because we do need to resize surfaces in some
10131 // cases while they are hidden such as when first showing a
10132 // window.
10133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010134 w.computeShownFrameLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010135 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010136 TAG, "Placing surface #" + i + " " + w.mSurface
10137 + ": new=" + w.mShownFrame + ", old="
10138 + w.mLastShownFrame);
10139
10140 boolean resize;
10141 int width, height;
10142 if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
10143 resize = w.mLastRequestedWidth != w.mRequestedWidth ||
10144 w.mLastRequestedHeight != w.mRequestedHeight;
10145 // for a scaled surface, we just want to use
10146 // the requested size.
10147 width = w.mRequestedWidth;
10148 height = w.mRequestedHeight;
10149 w.mLastRequestedWidth = width;
10150 w.mLastRequestedHeight = height;
10151 w.mLastShownFrame.set(w.mShownFrame);
10152 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010153 if (SHOW_TRANSACTIONS) logSurface(w,
10154 "POS " + w.mShownFrame.left
10155 + ", " + w.mShownFrame.top, null);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010156 w.mSurfaceX = w.mShownFrame.left;
10157 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010158 w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
10159 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010160 Slog.w(TAG, "Error positioning surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010161 if (!recoveringMemory) {
10162 reclaimSomeSurfaceMemoryLocked(w, "position");
10163 }
10164 }
10165 } else {
10166 resize = !w.mLastShownFrame.equals(w.mShownFrame);
10167 width = w.mShownFrame.width();
10168 height = w.mShownFrame.height();
10169 w.mLastShownFrame.set(w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010170 }
10171
10172 if (resize) {
10173 if (width < 1) width = 1;
10174 if (height < 1) height = 1;
10175 if (w.mSurface != null) {
10176 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010177 if (SHOW_TRANSACTIONS) logSurface(w,
10178 "POS " + w.mShownFrame.left + ","
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010179 + w.mShownFrame.top + " SIZE "
10180 + w.mShownFrame.width() + "x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010181 + w.mShownFrame.height(), null);
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010182 w.mSurfaceResized = true;
Dianne Hackborn16064f92010-03-25 00:47:24 -070010183 w.mSurfaceW = width;
10184 w.mSurfaceH = height;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010185 w.mSurface.setSize(width, height);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010186 w.mSurfaceX = w.mShownFrame.left;
10187 w.mSurfaceY = w.mShownFrame.top;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010188 w.mSurface.setPosition(w.mShownFrame.left,
10189 w.mShownFrame.top);
10190 } catch (RuntimeException e) {
10191 // If something goes wrong with the surface (such
10192 // as running out of memory), don't take down the
10193 // entire system.
Joe Onorato8a9b2202010-02-26 18:56:32 -080010194 Slog.e(TAG, "Failure updating surface of " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010195 + "size=(" + width + "x" + height
10196 + "), pos=(" + w.mShownFrame.left
10197 + "," + w.mShownFrame.top + ")", e);
10198 if (!recoveringMemory) {
10199 reclaimSomeSurfaceMemoryLocked(w, "size");
10200 }
10201 }
10202 }
10203 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010204 if (!w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010205 w.mContentInsetsChanged =
10206 !w.mLastContentInsets.equals(w.mContentInsets);
10207 w.mVisibleInsetsChanged =
10208 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010209 boolean configChanged =
10210 w.mConfiguration != mCurConfiguration
10211 && (w.mConfiguration == null
10212 || mCurConfiguration.diff(w.mConfiguration) != 0);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010213 if (DEBUG_CONFIGURATION && configChanged) {
10214 Slog.v(TAG, "Win " + w + " config changed: "
10215 + mCurConfiguration);
10216 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010217 if (localLOGV) Slog.v(TAG, "Resizing " + w
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010218 + ": configChanged=" + configChanged
10219 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
Romain Guy06882f82009-06-10 13:36:04 -070010220 if (!w.mLastFrame.equals(w.mFrame)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010221 || w.mContentInsetsChanged
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010222 || w.mVisibleInsetsChanged
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010223 || w.mSurfaceResized
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010224 || configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010225 w.mLastFrame.set(w.mFrame);
10226 w.mLastContentInsets.set(w.mContentInsets);
10227 w.mLastVisibleInsets.set(w.mVisibleInsets);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010228 // If the screen is currently frozen, then keep
10229 // it frozen until this window draws at its new
10230 // orientation.
10231 if (mDisplayFrozen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010232 if (DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010233 "Resizing while display frozen: " + w);
10234 w.mOrientationChanging = true;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010235 if (!mWindowsFreezingScreen) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010236 mWindowsFreezingScreen = true;
10237 // XXX should probably keep timeout from
10238 // when we first froze the display.
10239 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
10240 mH.sendMessageDelayed(mH.obtainMessage(
10241 H.WINDOW_FREEZE_TIMEOUT), 2000);
10242 }
10243 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010244 // If the orientation is changing, then we need to
10245 // hold off on unfreezing the display until this
10246 // window has been redrawn; to do that, we need
10247 // to go through the process of getting informed
10248 // by the application when it has finished drawing.
10249 if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010250 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010251 "Orientation start waiting for draw in "
10252 + w + ", surface " + w.mSurface);
10253 w.mDrawPending = true;
10254 w.mCommitDrawPending = false;
10255 w.mReadyToShow = false;
10256 if (w.mAppToken != null) {
10257 w.mAppToken.allDrawn = false;
10258 }
10259 }
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010260 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010261 "Resizing window " + w + " to " + w.mFrame);
10262 mResizingWindows.add(w);
10263 } else if (w.mOrientationChanging) {
10264 if (!w.mDrawPending && !w.mCommitDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010265 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010266 "Orientation not waiting for draw in "
10267 + w + ", surface " + w.mSurface);
10268 w.mOrientationChanging = false;
10269 }
10270 }
10271 }
10272
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010273 if (w.mAttachedHidden || !w.isReadyForDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010274 if (!w.mLastHidden) {
10275 //dump();
10276 w.mLastHidden = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010277 if (SHOW_TRANSACTIONS) logSurface(w,
10278 "HIDE (performLayout)", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010279 if (w.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010280 w.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010281 try {
10282 w.mSurface.hide();
10283 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010284 Slog.w(TAG, "Exception hiding surface in " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010285 }
10286 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010287 }
10288 // If we are waiting for this window to handle an
10289 // orientation change, well, it is hidden, so
10290 // doesn't really matter. Note that this does
10291 // introduce a potential glitch if the window
10292 // becomes unhidden before it has drawn for the
10293 // new orientation.
10294 if (w.mOrientationChanging) {
10295 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010296 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010297 "Orientation change skips hidden " + w);
10298 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010299 } else if (w.mLastLayer != w.mAnimLayer
10300 || w.mLastAlpha != w.mShownAlpha
10301 || w.mLastDsDx != w.mDsDx
10302 || w.mLastDtDx != w.mDtDx
10303 || w.mLastDsDy != w.mDsDy
10304 || w.mLastDtDy != w.mDtDy
10305 || w.mLastHScale != w.mHScale
10306 || w.mLastVScale != w.mVScale
10307 || w.mLastHidden) {
10308 displayed = true;
10309 w.mLastAlpha = w.mShownAlpha;
10310 w.mLastLayer = w.mAnimLayer;
10311 w.mLastDsDx = w.mDsDx;
10312 w.mLastDtDx = w.mDtDx;
10313 w.mLastDsDy = w.mDsDy;
10314 w.mLastDtDy = w.mDtDy;
10315 w.mLastHScale = w.mHScale;
10316 w.mLastVScale = w.mVScale;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010317 if (SHOW_TRANSACTIONS) logSurface(w,
10318 "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010319 + " matrix=[" + (w.mDsDx*w.mHScale)
10320 + "," + (w.mDtDx*w.mVScale)
10321 + "][" + (w.mDsDy*w.mHScale)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010322 + "," + (w.mDtDy*w.mVScale) + "]", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010323 if (w.mSurface != null) {
10324 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010325 w.mSurfaceAlpha = w.mShownAlpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010326 w.mSurface.setAlpha(w.mShownAlpha);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010327 w.mSurfaceLayer = w.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010328 w.mSurface.setLayer(w.mAnimLayer);
10329 w.mSurface.setMatrix(
10330 w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
10331 w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
10332 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010333 Slog.w(TAG, "Error updating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010334 if (!recoveringMemory) {
10335 reclaimSomeSurfaceMemoryLocked(w, "update");
10336 }
10337 }
10338 }
10339
10340 if (w.mLastHidden && !w.mDrawPending
10341 && !w.mCommitDrawPending
10342 && !w.mReadyToShow) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010343 if (SHOW_TRANSACTIONS) logSurface(w,
10344 "SHOW (performLayout)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010345 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010346 + " during relayout");
10347 if (showSurfaceRobustlyLocked(w)) {
10348 w.mHasDrawn = true;
10349 w.mLastHidden = false;
10350 } else {
10351 w.mOrientationChanging = false;
10352 }
10353 }
10354 if (w.mSurface != null) {
10355 w.mToken.hasVisible = true;
10356 }
10357 } else {
10358 displayed = true;
10359 }
10360
10361 if (displayed) {
10362 if (!covered) {
Romain Guy980a9382010-01-08 15:06:28 -080010363 if (attrs.width == LayoutParams.MATCH_PARENT
10364 && attrs.height == LayoutParams.MATCH_PARENT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010365 covered = true;
10366 }
10367 }
10368 if (w.mOrientationChanging) {
10369 if (w.mDrawPending || w.mCommitDrawPending) {
10370 orientationChangeComplete = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010371 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010372 "Orientation continue waiting for draw in " + w);
10373 } else {
10374 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010375 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010376 "Orientation change complete in " + w);
10377 }
10378 }
10379 w.mToken.hasVisible = true;
10380 }
10381 } else if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010382 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010383 "Orientation change skips hidden " + w);
10384 w.mOrientationChanging = false;
10385 }
10386
Dianne Hackborn0f761d62010-11-30 22:06:10 -080010387 if (w.mContentChanged) {
10388 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
10389 w.mContentChanged = false;
10390 }
10391
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010392 final boolean canBeSeen = w.isDisplayedLw();
10393
10394 if (someoneLosingFocus && w == mCurrentFocus && canBeSeen) {
10395 focusDisplayed = true;
10396 }
10397
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070010398 final boolean obscuredChanged = w.mObscured != obscured;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010400 // Update effect.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010401 if (!(w.mObscured=obscured)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010402 if (w.mSurface != null) {
10403 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
10404 holdScreen = w.mSession;
10405 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010406 if (!syswin && w.mAttrs.screenBrightness >= 0
10407 && screenBrightness < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010408 screenBrightness = w.mAttrs.screenBrightness;
10409 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010410 if (!syswin && w.mAttrs.buttonBrightness >= 0
10411 && buttonBrightness < 0) {
10412 buttonBrightness = w.mAttrs.buttonBrightness;
10413 }
Mike Lockwood46af6a82010-03-09 08:28:22 -050010414 if (canBeSeen
10415 && (attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
10416 || attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD
10417 || attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_ERROR)) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -070010418 syswin = true;
10419 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010420 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010421
Dianne Hackborn25994b42009-09-04 14:21:19 -070010422 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
10423 if (opaqueDrawn && w.isFullscreen(dw, dh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010424 // This window completely covers everything behind it,
10425 // so we want to leave all of them as unblurred (for
10426 // performance reasons).
10427 obscured = true;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010428 } else if (opaqueDrawn && w.needsBackgroundFiller(dw, dh)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010429 if (SHOW_TRANSACTIONS) Slog.d(TAG, "showing background filler");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010430 // This window is in compatibility mode, and needs background filler.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010431 obscured = true;
10432 if (mBackgroundFillerSurface == null) {
10433 try {
10434 mBackgroundFillerSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080010435 "BackGroundFiller",
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010436 0, dw, dh,
10437 PixelFormat.OPAQUE,
10438 Surface.FX_SURFACE_NORMAL);
10439 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010440 Slog.e(TAG, "Exception creating filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010441 }
10442 }
10443 try {
10444 mBackgroundFillerSurface.setPosition(0, 0);
10445 mBackgroundFillerSurface.setSize(dw, dh);
10446 // Using the same layer as Dim because they will never be shown at the
10447 // same time.
10448 mBackgroundFillerSurface.setLayer(w.mAnimLayer - 1);
10449 mBackgroundFillerSurface.show();
10450 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010451 Slog.e(TAG, "Exception showing filler surface");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010452 }
10453 backgroundFillerShown = true;
10454 mBackgroundFillerShown = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010455 } else if (canBeSeen && !obscured &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010456 (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010457 if (localLOGV) Slog.v(TAG, "Win " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010458 + ": blurring=" + blurring
10459 + " obscured=" + obscured
10460 + " displayed=" + displayed);
10461 if ((attrFlags&FLAG_DIM_BEHIND) != 0) {
10462 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010463 //Slog.i(TAG, "DIM BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010464 dimming = true;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010465 if (mDimAnimator == null) {
10466 mDimAnimator = new DimAnimator(mFxSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010467 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010468 mDimAnimator.show(dw, dh);
Dianne Hackborn1c24e952010-11-23 00:34:30 -080010469 mDimAnimator.updateParameters(mContext.getResources(),
10470 w, currentTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010471 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010472 }
10473 if ((attrFlags&FLAG_BLUR_BEHIND) != 0) {
10474 if (!blurring) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010475 //Slog.i(TAG, "BLUR BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010476 blurring = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010477 if (mBlurSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010478 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010479 + mBlurSurface + ": CREATE");
10480 try {
Romain Guy06882f82009-06-10 13:36:04 -070010481 mBlurSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080010482 "BlurSurface",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010483 -1, 16, 16,
10484 PixelFormat.OPAQUE,
10485 Surface.FX_SURFACE_BLUR);
10486 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010487 Slog.e(TAG, "Exception creating Blur surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010488 }
10489 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010490 if (mBlurSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010491 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10492 + mBlurSurface + ": pos=(0,0) (" +
10493 dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010494 mBlurSurface.setPosition(0, 0);
10495 mBlurSurface.setSize(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -070010496 mBlurSurface.setLayer(w.mAnimLayer-2);
10497 if (!mBlurShown) {
10498 try {
10499 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
10500 + mBlurSurface + ": SHOW");
10501 mBlurSurface.show();
10502 } catch (RuntimeException e) {
10503 Slog.w(TAG, "Failure showing blur surface", e);
10504 }
10505 mBlurShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010506 }
10507 }
10508 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010509 }
10510 }
10511 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010512
Dianne Hackborne9e9bca2009-08-18 15:08:22 -070010513 if (obscuredChanged && mWallpaperTarget == w) {
10514 // This is the wallpaper target and its obscured state
10515 // changed... make sure the current wallaper's visibility
10516 // has been updated accordingly.
10517 updateWallpaperVisibilityLocked();
10518 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010519 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010520
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010521 if (backgroundFillerShown == false && mBackgroundFillerShown) {
10522 mBackgroundFillerShown = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010523 if (SHOW_TRANSACTIONS) Slog.d(TAG, "hiding background filler");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010524 try {
10525 mBackgroundFillerSurface.hide();
10526 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010527 Slog.e(TAG, "Exception hiding filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070010528 }
10529 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010530
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070010531 if (mDimAnimator != null && mDimAnimator.mDimShown) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -080010532 animating |= mDimAnimator.updateSurface(dimming, currentTime,
10533 mDisplayFrozen || !mPolicy.isScreenOn());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010534 }
Romain Guy06882f82009-06-10 13:36:04 -070010535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010536 if (!blurring && mBlurShown) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010537 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR " + mBlurSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010538 + ": HIDE");
10539 try {
10540 mBlurSurface.hide();
10541 } catch (IllegalArgumentException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010542 Slog.w(TAG, "Illegal argument exception hiding blur surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010543 }
10544 mBlurShown = false;
10545 }
10546
Joe Onorato8a9b2202010-02-26 18:56:32 -080010547 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010548 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010549 Slog.e(TAG, "Unhandled exception in Window Manager", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010550 }
10551
Jeff Browne33348b2010-07-15 23:54:05 -070010552 mInputMonitor.updateInputWindowsLw();
10553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010554 Surface.closeTransaction();
Romain Guy06882f82009-06-10 13:36:04 -070010555
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010556 if (mWatermark != null) {
10557 mWatermark.drawIfNeeded();
10558 }
10559
Joe Onorato8a9b2202010-02-26 18:56:32 -080010560 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010561 "With display frozen, orientationChangeComplete="
10562 + orientationChangeComplete);
10563 if (orientationChangeComplete) {
10564 if (mWindowsFreezingScreen) {
10565 mWindowsFreezingScreen = false;
10566 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
10567 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010568 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010569 }
Romain Guy06882f82009-06-10 13:36:04 -070010570
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010571 i = mResizingWindows.size();
10572 if (i > 0) {
10573 do {
10574 i--;
10575 WindowState win = mResizingWindows.get(i);
10576 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010577 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
10578 "Reporting new frame to " + win + ": " + win.mFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010579 int diff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010580 boolean configChanged =
10581 win.mConfiguration != mCurConfiguration
10582 && (win.mConfiguration == null
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010583 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0);
10584 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
10585 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010586 Slog.i(TAG, "Sending new config to window " + win + ": "
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010587 + win.mFrame.width() + "x" + win.mFrame.height()
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010588 + " / " + mCurConfiguration + " / 0x"
10589 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010590 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -070010591 win.mConfiguration = mCurConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010592 win.mClient.resized(win.mFrame.width(),
10593 win.mFrame.height(), win.mLastContentInsets,
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010594 win.mLastVisibleInsets, win.mDrawPending,
10595 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010596 win.mContentInsetsChanged = false;
10597 win.mVisibleInsetsChanged = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080010598 win.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010599 } catch (RemoteException e) {
10600 win.mOrientationChanging = false;
10601 }
10602 } while (i > 0);
10603 mResizingWindows.clear();
10604 }
Romain Guy06882f82009-06-10 13:36:04 -070010605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010606 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010607 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010608 i = mDestroySurface.size();
10609 if (i > 0) {
10610 do {
10611 i--;
10612 WindowState win = mDestroySurface.get(i);
10613 win.mDestroying = false;
10614 if (mInputMethodWindow == win) {
10615 mInputMethodWindow = null;
10616 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010617 if (win == mWallpaperTarget) {
10618 wallpaperDestroyed = true;
10619 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010620 win.destroySurfaceLocked();
10621 } while (i > 0);
10622 mDestroySurface.clear();
10623 }
10624
10625 // Time to remove any exiting tokens?
10626 for (i=mExitingTokens.size()-1; i>=0; i--) {
10627 WindowToken token = mExitingTokens.get(i);
10628 if (!token.hasVisible) {
10629 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070010630 if (token.windowType == TYPE_WALLPAPER) {
10631 mWallpaperTokens.remove(token);
10632 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010633 }
10634 }
10635
10636 // Time to remove any exiting applications?
10637 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
10638 AppWindowToken token = mExitingAppTokens.get(i);
10639 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -070010640 // Make sure there is no animation running on this token,
10641 // so any windows associated with it will be removed as
10642 // soon as their animations are complete
10643 token.animation = null;
10644 token.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010645 mAppTokens.remove(token);
10646 mExitingAppTokens.remove(i);
10647 }
10648 }
10649
Dianne Hackborna8f60182009-09-01 19:01:50 -070010650 boolean needRelayout = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010651
Dianne Hackborna8f60182009-09-01 19:01:50 -070010652 if (!animating && mAppTransitionRunning) {
10653 // We have finished the animation of an app transition. To do
10654 // this, we have delayed a lot of operations like showing and
10655 // hiding apps, moving apps in Z-order, etc. The app token list
10656 // reflects the correct Z-order, but the window list may now
10657 // be out of sync with it. So here we will just rebuild the
10658 // entire app window list. Fun!
10659 mAppTransitionRunning = false;
10660 needRelayout = true;
10661 rebuildAppWindowListLocked();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010662 assignLayersLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -070010663 // Clear information about apps that were moving.
10664 mToBottomApps.clear();
10665 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010666
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010667 if (focusDisplayed) {
10668 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
10669 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010670 if (wallpaperDestroyed) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010671 needRelayout = adjustWallpaperWindowsLocked() != 0;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010672 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010673 if (needRelayout) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -070010674 requestAnimationLocked(0);
10675 } else if (animating) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010676 requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
10677 }
Jeff Browneb857f12010-07-16 10:06:33 -070010678
Jeff Browne33348b2010-07-15 23:54:05 -070010679 mInputMonitor.updateInputWindowsLw();
Jeff Browneb857f12010-07-16 10:06:33 -070010680
Jeff Brown8e03b752010-06-13 19:16:55 -070010681 setHoldScreenLocked(holdScreen != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010682 if (screenBrightness < 0 || screenBrightness > 1.0f) {
10683 mPowerManager.setScreenBrightnessOverride(-1);
10684 } else {
10685 mPowerManager.setScreenBrightnessOverride((int)
10686 (screenBrightness * Power.BRIGHTNESS_ON));
10687 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -050010688 if (buttonBrightness < 0 || buttonBrightness > 1.0f) {
10689 mPowerManager.setButtonBrightnessOverride(-1);
10690 } else {
10691 mPowerManager.setButtonBrightnessOverride((int)
10692 (buttonBrightness * Power.BRIGHTNESS_ON));
10693 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010694 if (holdScreen != mHoldingScreenOn) {
10695 mHoldingScreenOn = holdScreen;
10696 Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
10697 mH.sendMessage(m);
10698 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010699
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010700 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010701 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010702 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
10703 LocalPowerManager.BUTTON_EVENT, true);
10704 mTurnOnScreen = false;
10705 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -080010706
10707 // Check to see if we are now in a state where the screen should
10708 // be enabled, because the window obscured flags have changed.
10709 enableScreenIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010710 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070010711
10712 /**
10713 * Must be called with the main window manager lock held.
10714 */
10715 void setHoldScreenLocked(boolean holding) {
10716 boolean state = mHoldingScreenWakeLock.isHeld();
10717 if (holding != state) {
10718 if (holding) {
10719 mHoldingScreenWakeLock.acquire();
10720 } else {
10721 mPolicy.screenOnStoppedLw();
10722 mHoldingScreenWakeLock.release();
10723 }
10724 }
10725 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010726
10727 void requestAnimationLocked(long delay) {
10728 if (!mAnimationPending) {
10729 mAnimationPending = true;
10730 mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
10731 }
10732 }
Romain Guy06882f82009-06-10 13:36:04 -070010733
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010734 /**
10735 * Have the surface flinger show a surface, robustly dealing with
10736 * error conditions. In particular, if there is not enough memory
10737 * to show the surface, then we will try to get rid of other surfaces
10738 * in order to succeed.
Romain Guy06882f82009-06-10 13:36:04 -070010739 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010740 * @return Returns true if the surface was successfully shown.
10741 */
10742 boolean showSurfaceRobustlyLocked(WindowState win) {
10743 try {
10744 if (win.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070010745 win.mSurfaceShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010746 win.mSurface.show();
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010747 if (win.mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -080010748 if (DEBUG_VISIBILITY) Slog.v(TAG,
10749 "Show surface turning screen on: " + win);
Dianne Hackborn93e462b2009-09-15 22:50:40 -070010750 win.mTurnOnScreen = false;
10751 mTurnOnScreen = true;
10752 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010753 }
10754 return true;
10755 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010756 Slog.w(TAG, "Failure showing surface " + win.mSurface + " in " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010757 }
Romain Guy06882f82009-06-10 13:36:04 -070010758
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010759 reclaimSomeSurfaceMemoryLocked(win, "show");
Romain Guy06882f82009-06-10 13:36:04 -070010760
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010761 return false;
10762 }
Romain Guy06882f82009-06-10 13:36:04 -070010763
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010764 void reclaimSomeSurfaceMemoryLocked(WindowState win, String operation) {
10765 final Surface surface = win.mSurface;
Romain Guy06882f82009-06-10 13:36:04 -070010766
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010767 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, win.toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010768 win.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -070010769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010770 if (mForceRemoves == null) {
10771 mForceRemoves = new ArrayList<WindowState>();
10772 }
Romain Guy06882f82009-06-10 13:36:04 -070010773
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010774 long callingIdentity = Binder.clearCallingIdentity();
10775 try {
10776 // There was some problem... first, do a sanity check of the
10777 // window list to make sure we haven't left any dangling surfaces
10778 // around.
10779 int N = mWindows.size();
10780 boolean leakedSurface = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010781 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010782 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -070010783 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010784 if (ws.mSurface != null) {
10785 if (!mSessions.contains(ws.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010786 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010787 + ws + " surface=" + ws.mSurface
10788 + " token=" + win.mToken
10789 + " pid=" + ws.mSession.mPid
10790 + " uid=" + ws.mSession.mUid);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010791 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010792 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010793 ws.mSurface = null;
10794 mForceRemoves.add(ws);
10795 i--;
10796 N--;
10797 leakedSurface = true;
10798 } else if (win.mAppToken != null && win.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010799 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010800 + ws + " surface=" + ws.mSurface
10801 + " token=" + win.mAppToken);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010802 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010803 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010804 ws.mSurface = null;
10805 leakedSurface = true;
10806 }
10807 }
10808 }
Romain Guy06882f82009-06-10 13:36:04 -070010809
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010810 boolean killedApps = false;
10811 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010812 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010813 SparseIntArray pidCandidates = new SparseIntArray();
10814 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -070010815 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010816 if (ws.mSurface != null) {
10817 pidCandidates.append(ws.mSession.mPid, ws.mSession.mPid);
10818 }
10819 }
10820 if (pidCandidates.size() > 0) {
10821 int[] pids = new int[pidCandidates.size()];
10822 for (int i=0; i<pids.length; i++) {
10823 pids[i] = pidCandidates.keyAt(i);
10824 }
10825 try {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -070010826 if (mActivityManager.killPids(pids, "Free memory")) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010827 killedApps = true;
10828 }
10829 } catch (RemoteException e) {
10830 }
10831 }
10832 }
Romain Guy06882f82009-06-10 13:36:04 -070010833
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010834 if (leakedSurface || killedApps) {
10835 // We managed to reclaim some memory, so get rid of the trouble
10836 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -080010837 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010838 if (surface != null) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010839 surface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -070010840 win.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010841 win.mSurface = null;
10842 }
Romain Guy06882f82009-06-10 13:36:04 -070010843
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010844 try {
10845 win.mClient.dispatchGetNewSurface();
10846 } catch (RemoteException e) {
10847 }
10848 }
10849 } finally {
10850 Binder.restoreCallingIdentity(callingIdentity);
10851 }
10852 }
Romain Guy06882f82009-06-10 13:36:04 -070010853
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010854 private boolean updateFocusedWindowLocked(int mode) {
10855 WindowState newFocus = computeFocusedWindowLocked();
10856 if (mCurrentFocus != newFocus) {
10857 // This check makes sure that we don't already have the focus
10858 // change message pending.
10859 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
10860 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010861 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010862 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
10863 final WindowState oldFocus = mCurrentFocus;
10864 mCurrentFocus = newFocus;
10865 mLosingFocus.remove(newFocus);
Romain Guy06882f82009-06-10 13:36:04 -070010866
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010867 final WindowState imWindow = mInputMethodWindow;
10868 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010869 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010870 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010871 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
10872 mLayoutNeeded = true;
10873 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010874 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -080010875 performLayoutLockedInner(true);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010876 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
10877 // Client will do the layout, but we need to assign layers
10878 // for handleNewWindowLocked() below.
10879 assignLayersLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010880 }
10881 }
Jeff Brown349703e2010-06-22 01:27:15 -070010882
10883 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
10884 // If we defer assigning layers, then the caller is responsible for
10885 // doing this part.
10886 finishUpdateFocusedWindowAfterAssignLayersLocked();
The Android Open Source Projectc474dec2009-03-04 09:49:09 -080010887 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010888 return true;
10889 }
10890 return false;
10891 }
Jeff Brown349703e2010-06-22 01:27:15 -070010892
10893 private void finishUpdateFocusedWindowAfterAssignLayersLocked() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010894 mInputMonitor.setInputFocusLw(mCurrentFocus);
Jeff Brown349703e2010-06-22 01:27:15 -070010895 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010896
10897 private WindowState computeFocusedWindowLocked() {
10898 WindowState result = null;
10899 WindowState win;
10900
10901 int i = mWindows.size() - 1;
10902 int nextAppIndex = mAppTokens.size()-1;
10903 WindowToken nextApp = nextAppIndex >= 0
10904 ? mAppTokens.get(nextAppIndex) : null;
10905
10906 while (i >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -070010907 win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010908
Joe Onorato8a9b2202010-02-26 18:56:32 -080010909 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010910 TAG, "Looking for focus: " + i
10911 + " = " + win
10912 + ", flags=" + win.mAttrs.flags
10913 + ", canReceive=" + win.canReceiveKeys());
10914
10915 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -070010916
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010917 // If this window's application has been removed, just skip it.
10918 if (thisApp != null && thisApp.removed) {
10919 i--;
10920 continue;
10921 }
Romain Guy06882f82009-06-10 13:36:04 -070010922
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010923 // If there is a focused app, don't allow focus to go to any
10924 // windows below it. If this is an application window, step
10925 // through the app tokens until we find its app.
10926 if (thisApp != null && nextApp != null && thisApp != nextApp
10927 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
10928 int origAppIndex = nextAppIndex;
10929 while (nextAppIndex > 0) {
10930 if (nextApp == mFocusedApp) {
10931 // Whoops, we are below the focused app... no focus
10932 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -080010933 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010934 TAG, "Reached focused app: " + mFocusedApp);
10935 return null;
10936 }
10937 nextAppIndex--;
10938 nextApp = mAppTokens.get(nextAppIndex);
10939 if (nextApp == thisApp) {
10940 break;
10941 }
10942 }
10943 if (thisApp != nextApp) {
10944 // Uh oh, the app token doesn't exist! This shouldn't
10945 // happen, but if it does we can get totally hosed...
10946 // so restart at the original app.
10947 nextAppIndex = origAppIndex;
10948 nextApp = mAppTokens.get(nextAppIndex);
10949 }
10950 }
10951
10952 // Dispatch to this window if it is wants key events.
10953 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010954 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010955 TAG, "Found focus @ " + i + " = " + win);
10956 result = win;
10957 break;
10958 }
10959
10960 i--;
10961 }
10962
10963 return result;
10964 }
10965
10966 private void startFreezingDisplayLocked() {
10967 if (mDisplayFrozen) {
10968 return;
10969 }
Romain Guy06882f82009-06-10 13:36:04 -070010970
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010971 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -070010972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010973 long now = SystemClock.uptimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010974 //Slog.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010975 if (mFreezeGcPending != 0) {
10976 if (now > (mFreezeGcPending+1000)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010977 //Slog.i(TAG, "Gc! " + now + " > " + (mFreezeGcPending+1000));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010978 mH.removeMessages(H.FORCE_GC);
10979 Runtime.getRuntime().gc();
10980 mFreezeGcPending = now;
10981 }
10982 } else {
10983 mFreezeGcPending = now;
10984 }
Romain Guy06882f82009-06-10 13:36:04 -070010985
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010986 mDisplayFrozen = true;
Jeff Brown349703e2010-06-22 01:27:15 -070010987
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010988 mInputMonitor.freezeInputDispatchingLw();
Jeff Brown349703e2010-06-22 01:27:15 -070010989
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070010990 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
10991 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010992 mNextAppTransitionPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010993 mAppTransitionReady = true;
10994 }
Romain Guy06882f82009-06-10 13:36:04 -070010995
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010996 if (PROFILE_ORIENTATION) {
10997 File file = new File("/data/system/frozen");
10998 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
10999 }
Dianne Hackborna1111872010-11-23 20:55:11 -080011000
11001 if (CUSTOM_SCREEN_ROTATION) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080011002 if (mScreenRotationAnimation != null && mScreenRotationAnimation.isAnimating()) {
11003 mScreenRotationAnimation.kill();
11004 mScreenRotationAnimation = null;
11005 }
Dianne Hackborna1111872010-11-23 20:55:11 -080011006 if (mScreenRotationAnimation == null) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080011007 mScreenRotationAnimation = new ScreenRotationAnimation(mContext,
11008 mDisplay, mFxSession);
Dianne Hackborna1111872010-11-23 20:55:11 -080011009 }
11010 } else {
11011 Surface.freezeDisplay(0);
11012 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011013 }
Romain Guy06882f82009-06-10 13:36:04 -070011014
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011015 private void stopFreezingDisplayLocked() {
11016 if (!mDisplayFrozen) {
11017 return;
11018 }
Romain Guy06882f82009-06-10 13:36:04 -070011019
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011020 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
11021 return;
11022 }
11023
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011024 mDisplayFrozen = false;
11025 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
11026 if (PROFILE_ORIENTATION) {
11027 Debug.stopMethodTracing();
11028 }
Dianne Hackborna1111872010-11-23 20:55:11 -080011029
11030 if (CUSTOM_SCREEN_ROTATION) {
11031 if (mScreenRotationAnimation != null) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080011032 if (mScreenRotationAnimation.dismiss(MAX_ANIMATION_DURATION,
11033 mTransitionAnimationScale)) {
11034 requestAnimationLocked(0);
11035 } else {
11036 mScreenRotationAnimation = null;
11037 }
Dianne Hackborna1111872010-11-23 20:55:11 -080011038 }
11039 } else {
11040 Surface.unfreezeDisplay(0);
11041 }
Romain Guy06882f82009-06-10 13:36:04 -070011042
Jeff Brown00fa7bd2010-07-02 15:37:36 -070011043 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011044
Christopher Tateb696aee2010-04-02 19:08:30 -070011045 // While the display is frozen we don't re-compute the orientation
11046 // to avoid inconsistent states. However, something interesting
11047 // could have actually changed during that time so re-evaluate it
11048 // now to catch that.
11049 if (updateOrientationFromAppTokensLocked()) {
11050 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
11051 }
11052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011053 // A little kludge: a lot could have happened while the
11054 // display was frozen, so now that we are coming back we
11055 // do a gc so that any remote references the system
11056 // processes holds on others can be released if they are
11057 // no longer needed.
11058 mH.removeMessages(H.FORCE_GC);
11059 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
11060 2000);
Romain Guy06882f82009-06-10 13:36:04 -070011061
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011062 mScreenFrozenLock.release();
11063 }
Romain Guy06882f82009-06-10 13:36:04 -070011064
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011065 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
11066 DisplayMetrics dm) {
11067 if (index < tokens.length) {
11068 String str = tokens[index];
11069 if (str != null && str.length() > 0) {
11070 try {
11071 int val = Integer.parseInt(str);
11072 return val;
11073 } catch (Exception e) {
11074 }
11075 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011076 }
11077 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
11078 return defDps;
11079 }
11080 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
11081 return val;
11082 }
11083
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011084 static class Watermark {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011085 final String[] mTokens;
11086 final String mText;
11087 final Paint mTextPaint;
11088 final int mTextWidth;
11089 final int mTextHeight;
11090 final int mTextAscent;
11091 final int mTextDescent;
11092 final int mDeltaX;
11093 final int mDeltaY;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011094
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011095 Surface mSurface;
11096 int mLastDW;
11097 int mLastDH;
11098 boolean mDrawNeeded;
11099
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011100 Watermark(Display display, SurfaceSession session, String[] tokens) {
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011101 final DisplayMetrics dm = new DisplayMetrics();
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011102 display.getMetrics(dm);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011103
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011104 if (false) {
11105 Log.i(TAG, "*********************** WATERMARK");
11106 for (int i=0; i<tokens.length; i++) {
11107 Log.i(TAG, " TOKEN #" + i + ": " + tokens[i]);
11108 }
11109 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011110
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011111 mTokens = tokens;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011112
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011113 StringBuilder builder = new StringBuilder(32);
11114 int len = mTokens[0].length();
11115 len = len & ~1;
11116 for (int i=0; i<len; i+=2) {
11117 int c1 = mTokens[0].charAt(i);
11118 int c2 = mTokens[0].charAt(i+1);
11119 if (c1 >= 'a' && c1 <= 'f') c1 = c1 - 'a' + 10;
11120 else if (c1 >= 'A' && c1 <= 'F') c1 = c1 - 'A' + 10;
11121 else c1 -= '0';
11122 if (c2 >= 'a' && c2 <= 'f') c2 = c2 - 'a' + 10;
11123 else if (c2 >= 'A' && c2 <= 'F') c2 = c2 - 'A' + 10;
11124 else c2 -= '0';
11125 builder.append((char)(255-((c1*16)+c2)));
11126 }
11127 mText = builder.toString();
11128 if (false) {
11129 Log.i(TAG, "Final text: " + mText);
11130 }
11131
11132 int fontSize = getPropertyInt(tokens, 1,
11133 TypedValue.COMPLEX_UNIT_DIP, 20, dm);
11134
11135 mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
11136 mTextPaint.setTextSize(fontSize);
11137 mTextPaint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD));
11138
11139 FontMetricsInt fm = mTextPaint.getFontMetricsInt();
11140 mTextWidth = (int)mTextPaint.measureText(mText);
11141 mTextAscent = fm.ascent;
11142 mTextDescent = fm.descent;
11143 mTextHeight = fm.descent - fm.ascent;
11144
11145 mDeltaX = getPropertyInt(tokens, 2,
11146 TypedValue.COMPLEX_UNIT_PX, mTextWidth*2, dm);
11147 mDeltaY = getPropertyInt(tokens, 3,
11148 TypedValue.COMPLEX_UNIT_PX, mTextHeight*3, dm);
11149 int shadowColor = getPropertyInt(tokens, 4,
11150 TypedValue.COMPLEX_UNIT_PX, 0xb0000000, dm);
11151 int color = getPropertyInt(tokens, 5,
11152 TypedValue.COMPLEX_UNIT_PX, 0x60ffffff, dm);
11153 int shadowRadius = getPropertyInt(tokens, 6,
11154 TypedValue.COMPLEX_UNIT_PX, 7, dm);
11155 int shadowDx = getPropertyInt(tokens, 8,
11156 TypedValue.COMPLEX_UNIT_PX, 0, dm);
11157 int shadowDy = getPropertyInt(tokens, 9,
11158 TypedValue.COMPLEX_UNIT_PX, 0, dm);
11159
11160 mTextPaint.setColor(color);
11161 mTextPaint.setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011162
11163 try {
11164 mSurface = new Surface(session, 0,
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011165 "WatermarkSurface", -1, 1, 1, PixelFormat.TRANSLUCENT, 0);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011166 mSurface.setLayer(TYPE_LAYER_MULTIPLIER*100);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011167 mSurface.setPosition(0, 0);
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011168 mSurface.show();
11169 } catch (OutOfResourcesException e) {
11170 }
11171 }
11172
11173 void positionSurface(int dw, int dh) {
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011174 if (mLastDW != dw || mLastDH != dh) {
11175 mLastDW = dw;
11176 mLastDH = dh;
11177 mSurface.setSize(dw, dh);
11178 mDrawNeeded = true;
11179 }
11180 }
11181
11182 void drawIfNeeded() {
11183 if (mDrawNeeded) {
11184 final int dw = mLastDW;
11185 final int dh = mLastDH;
11186
11187 mDrawNeeded = false;
11188 Rect dirty = new Rect(0, 0, dw, dh);
11189 Canvas c = null;
11190 try {
11191 c = mSurface.lockCanvas(dirty);
11192 } catch (IllegalArgumentException e) {
11193 } catch (OutOfResourcesException e) {
11194 }
11195 if (c != null) {
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011196 c.drawColor(0, PorterDuff.Mode.CLEAR);
11197
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011198 int deltaX = mDeltaX;
11199 int deltaY = mDeltaY;
11200
11201 // deltaX shouldn't be close to a round fraction of our
11202 // x step, or else things will line up too much.
11203 int div = (dw+mTextWidth)/deltaX;
11204 int rem = (dw+mTextWidth) - (div*deltaX);
11205 int qdelta = deltaX/4;
11206 if (rem < qdelta || rem > (deltaX-qdelta)) {
11207 deltaX += deltaX/3;
11208 }
11209
11210 int y = -mTextHeight;
11211 int x = -mTextWidth;
11212 while (y < (dh+mTextHeight)) {
11213 c.drawText(mText, x, y, mTextPaint);
11214 x += deltaX;
11215 if (x >= dw) {
11216 x -= (dw+mTextWidth);
11217 y += deltaY;
11218 }
11219 }
11220 mSurface.unlockCanvasAndPost(c);
11221 }
11222 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011223 }
11224 }
11225
11226 void createWatermark() {
11227 if (mWatermark != null) {
11228 return;
11229 }
11230
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011231 File file = new File("/system/etc/setup.conf");
11232 FileInputStream in = null;
11233 try {
11234 in = new FileInputStream(file);
11235 DataInputStream ind = new DataInputStream(in);
11236 String line = ind.readLine();
11237 if (line != null) {
11238 String[] toks = line.split("%");
11239 if (toks != null && toks.length > 0) {
Dianne Hackborned7bfbf2010-11-05 13:08:35 -070011240 mWatermark = new Watermark(mDisplay, mFxSession, toks);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070011241 }
11242 }
11243 } catch (FileNotFoundException e) {
11244 } catch (IOException e) {
11245 } finally {
11246 if (in != null) {
11247 try {
11248 in.close();
11249 } catch (IOException e) {
11250 }
11251 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011252 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070011253 }
11254
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011255 @Override
11256 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11257 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
11258 != PackageManager.PERMISSION_GRANTED) {
11259 pw.println("Permission Denial: can't dump WindowManager from from pid="
11260 + Binder.getCallingPid()
11261 + ", uid=" + Binder.getCallingUid());
11262 return;
11263 }
Romain Guy06882f82009-06-10 13:36:04 -070011264
Jeff Brown00fa7bd2010-07-02 15:37:36 -070011265 mInputManager.dump(pw);
Dianne Hackborna2e92262010-03-02 17:19:29 -080011266 pw.println(" ");
11267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011268 synchronized(mWindowMap) {
11269 pw.println("Current Window Manager state:");
11270 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -070011271 WindowState w = mWindows.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011272 pw.print(" Window #"); pw.print(i); pw.print(' ');
11273 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011274 w.dump(pw, " ");
11275 }
11276 if (mInputMethodDialogs.size() > 0) {
11277 pw.println(" ");
11278 pw.println(" Input method dialogs:");
11279 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
11280 WindowState w = mInputMethodDialogs.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011281 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011282 }
11283 }
11284 if (mPendingRemove.size() > 0) {
11285 pw.println(" ");
11286 pw.println(" Remove pending for:");
11287 for (int i=mPendingRemove.size()-1; i>=0; i--) {
11288 WindowState w = mPendingRemove.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011289 pw.print(" Remove #"); pw.print(i); pw.print(' ');
11290 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011291 w.dump(pw, " ");
11292 }
11293 }
11294 if (mForceRemoves != null && mForceRemoves.size() > 0) {
11295 pw.println(" ");
11296 pw.println(" Windows force removing:");
11297 for (int i=mForceRemoves.size()-1; i>=0; i--) {
11298 WindowState w = mForceRemoves.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011299 pw.print(" Removing #"); pw.print(i); pw.print(' ');
11300 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011301 w.dump(pw, " ");
11302 }
11303 }
11304 if (mDestroySurface.size() > 0) {
11305 pw.println(" ");
11306 pw.println(" Windows waiting to destroy their surface:");
11307 for (int i=mDestroySurface.size()-1; i>=0; i--) {
11308 WindowState w = mDestroySurface.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011309 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
11310 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011311 w.dump(pw, " ");
11312 }
11313 }
11314 if (mLosingFocus.size() > 0) {
11315 pw.println(" ");
11316 pw.println(" Windows losing focus:");
11317 for (int i=mLosingFocus.size()-1; i>=0; i--) {
11318 WindowState w = mLosingFocus.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011319 pw.print(" Losing #"); pw.print(i); pw.print(' ');
11320 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011321 w.dump(pw, " ");
11322 }
11323 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011324 if (mResizingWindows.size() > 0) {
11325 pw.println(" ");
11326 pw.println(" Windows waiting to resize:");
11327 for (int i=mResizingWindows.size()-1; i>=0; i--) {
11328 WindowState w = mResizingWindows.get(i);
11329 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
11330 pw.print(w); pw.println(":");
11331 w.dump(pw, " ");
11332 }
11333 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011334 if (mSessions.size() > 0) {
11335 pw.println(" ");
11336 pw.println(" All active sessions:");
11337 Iterator<Session> it = mSessions.iterator();
11338 while (it.hasNext()) {
11339 Session s = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011340 pw.print(" Session "); pw.print(s); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011341 s.dump(pw, " ");
11342 }
11343 }
11344 if (mTokenMap.size() > 0) {
11345 pw.println(" ");
11346 pw.println(" All tokens:");
11347 Iterator<WindowToken> it = mTokenMap.values().iterator();
11348 while (it.hasNext()) {
11349 WindowToken token = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011350 pw.print(" Token "); pw.print(token.token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011351 token.dump(pw, " ");
11352 }
11353 }
11354 if (mTokenList.size() > 0) {
11355 pw.println(" ");
11356 pw.println(" Window token list:");
11357 for (int i=0; i<mTokenList.size(); i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011358 pw.print(" #"); pw.print(i); pw.print(": ");
11359 pw.println(mTokenList.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011360 }
11361 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070011362 if (mWallpaperTokens.size() > 0) {
11363 pw.println(" ");
11364 pw.println(" Wallpaper tokens:");
11365 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
11366 WindowToken token = mWallpaperTokens.get(i);
11367 pw.print(" Wallpaper #"); pw.print(i);
11368 pw.print(' '); pw.print(token); pw.println(':');
11369 token.dump(pw, " ");
11370 }
11371 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011372 if (mAppTokens.size() > 0) {
11373 pw.println(" ");
11374 pw.println(" Application tokens in Z order:");
11375 for (int i=mAppTokens.size()-1; i>=0; i--) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011376 pw.print(" App #"); pw.print(i); pw.print(": ");
11377 pw.println(mAppTokens.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011378 }
11379 }
11380 if (mFinishedStarting.size() > 0) {
11381 pw.println(" ");
11382 pw.println(" Finishing start of application tokens:");
11383 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
11384 WindowToken token = mFinishedStarting.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011385 pw.print(" Finished Starting #"); pw.print(i);
11386 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011387 token.dump(pw, " ");
11388 }
11389 }
11390 if (mExitingTokens.size() > 0) {
11391 pw.println(" ");
11392 pw.println(" Exiting tokens:");
11393 for (int i=mExitingTokens.size()-1; i>=0; i--) {
11394 WindowToken token = mExitingTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011395 pw.print(" Exiting #"); pw.print(i);
11396 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011397 token.dump(pw, " ");
11398 }
11399 }
11400 if (mExitingAppTokens.size() > 0) {
11401 pw.println(" ");
11402 pw.println(" Exiting application tokens:");
11403 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
11404 WindowToken token = mExitingAppTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011405 pw.print(" Exiting App #"); pw.print(i);
11406 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011407 token.dump(pw, " ");
11408 }
11409 }
11410 pw.println(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011411 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
11412 pw.print(" mLastFocus="); pw.println(mLastFocus);
11413 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
11414 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
11415 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
Dianne Hackbornf21adf62009-08-13 10:20:21 -070011416 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011417 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
11418 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
11419 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
11420 }
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -080011421 if (mWindowDetachedWallpaper != null) {
11422 pw.print(" mWindowDetachedWallpaper="); pw.println(mWindowDetachedWallpaper);
11423 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011424 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
11425 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
11426 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011427 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
11428 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
11429 pw.print(" mLayoutNeeded="); pw.print(mLayoutNeeded);
11430 pw.print(" mBlurShown="); pw.println(mBlurShown);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011431 if (mDimAnimator != null) {
11432 mDimAnimator.printTo(pw);
11433 } else {
Dianne Hackborna2e92262010-03-02 17:19:29 -080011434 pw.println( " no DimAnimator ");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011435 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011436 pw.print(" mInputMethodAnimLayerAdjustment=");
Dianne Hackborn759a39e2009-08-09 17:20:27 -070011437 pw.print(mInputMethodAnimLayerAdjustment);
11438 pw.print(" mWallpaperAnimLayerAdjustment=");
11439 pw.println(mWallpaperAnimLayerAdjustment);
Dianne Hackborn284ac932009-08-28 10:34:25 -070011440 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
11441 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011442 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
11443 pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011444 pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
11445 pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011446 pw.print(" mRotation="); pw.print(mRotation);
11447 pw.print(", mForcedAppOrientation="); pw.print(mForcedAppOrientation);
11448 pw.print(", mRequestedRotation="); pw.println(mRequestedRotation);
11449 pw.print(" mAnimationPending="); pw.print(mAnimationPending);
11450 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
11451 pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale);
11452 pw.print(" mNextAppTransition=0x");
11453 pw.print(Integer.toHexString(mNextAppTransition));
11454 pw.print(", mAppTransitionReady="); pw.print(mAppTransitionReady);
Dianne Hackborna8f60182009-09-01 19:01:50 -070011455 pw.print(", mAppTransitionRunning="); pw.print(mAppTransitionRunning);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011456 pw.print(", mAppTransitionTimeout="); pw.println( mAppTransitionTimeout);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070011457 if (mNextAppTransitionPackage != null) {
11458 pw.print(" mNextAppTransitionPackage=");
11459 pw.print(mNextAppTransitionPackage);
11460 pw.print(", mNextAppTransitionEnter=0x");
11461 pw.print(Integer.toHexString(mNextAppTransitionEnter));
11462 pw.print(", mNextAppTransitionExit=0x");
11463 pw.print(Integer.toHexString(mNextAppTransitionExit));
11464 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070011465 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
11466 pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
11467 if (mOpeningApps.size() > 0) {
11468 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
11469 }
11470 if (mClosingApps.size() > 0) {
11471 pw.print(" mClosingApps="); pw.println(mClosingApps);
11472 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070011473 if (mToTopApps.size() > 0) {
11474 pw.print(" mToTopApps="); pw.println(mToTopApps);
11475 }
11476 if (mToBottomApps.size() > 0) {
11477 pw.print(" mToBottomApps="); pw.println(mToBottomApps);
11478 }
Dianne Hackborn87fc3082010-12-03 13:09:12 -080011479 if (mDisplay != null) {
11480 pw.print(" DisplayWidth="); pw.print(mDisplay.getWidth());
11481 pw.print(" DisplayHeight="); pw.println(mDisplay.getHeight());
11482 } else {
11483 pw.println(" NO DISPLAY");
11484 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011485 }
11486 }
11487
Jeff Brown349703e2010-06-22 01:27:15 -070011488 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011489 public void monitor() {
11490 synchronized (mWindowMap) { }
Mike Lockwood983ee092009-11-22 01:42:24 -050011491 synchronized (mKeyguardTokenWatcher) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070011492 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011493
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011494 /**
11495 * DimAnimator class that controls the dim animation. This holds the surface and
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011496 * all state used for dim animation.
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011497 */
11498 private static class DimAnimator {
11499 Surface mDimSurface;
11500 boolean mDimShown = false;
11501 float mDimCurrentAlpha;
11502 float mDimTargetAlpha;
11503 float mDimDeltaPerMs;
11504 long mLastDimAnimTime;
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011505
11506 int mLastDimWidth, mLastDimHeight;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011507
11508 DimAnimator (SurfaceSession session) {
11509 if (mDimSurface == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011510 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011511 + mDimSurface + ": CREATE");
11512 try {
Mathias Agopian5d26c1e2010-03-01 16:09:43 -080011513 mDimSurface = new Surface(session, 0,
11514 "DimSurface",
11515 -1, 16, 16, PixelFormat.OPAQUE,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011516 Surface.FX_SURFACE_DIM);
Maciej Białka9ee5c222010-03-24 10:25:40 +010011517 mDimSurface.setAlpha(0.0f);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011518 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011519 Slog.e(TAG, "Exception creating Dim surface", e);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011520 }
11521 }
11522 }
11523
11524 /**
11525 * Show the dim surface.
11526 */
11527 void show(int dw, int dh) {
Dianne Hackborn16064f92010-03-25 00:47:24 -070011528 if (!mDimShown) {
11529 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
11530 dw + "x" + dh + ")");
11531 mDimShown = true;
11532 try {
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011533 mLastDimWidth = dw;
11534 mLastDimHeight = dh;
Dianne Hackborn16064f92010-03-25 00:47:24 -070011535 mDimSurface.setPosition(0, 0);
11536 mDimSurface.setSize(dw, dh);
11537 mDimSurface.show();
11538 } catch (RuntimeException e) {
11539 Slog.w(TAG, "Failure showing dim surface", e);
11540 }
Dianne Hackbornf83c5552010-03-31 22:19:32 -070011541 } else if (mLastDimWidth != dw || mLastDimHeight != dh) {
11542 mLastDimWidth = dw;
11543 mLastDimHeight = dh;
11544 mDimSurface.setSize(dw, dh);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011545 }
11546 }
11547
11548 /**
11549 * Set's the dim surface's layer and update dim parameters that will be used in
11550 * {@link updateSurface} after all windows are examined.
11551 */
Dianne Hackborn1c24e952010-11-23 00:34:30 -080011552 void updateParameters(Resources res, WindowState w, long currentTime) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011553 mDimSurface.setLayer(w.mAnimLayer-1);
11554
11555 final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011556 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070011557 + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011558 if (mDimTargetAlpha != target) {
11559 // If the desired dim level has changed, then
11560 // start an animation to it.
11561 mLastDimAnimTime = currentTime;
11562 long duration = (w.mAnimating && w.mAnimation != null)
11563 ? w.mAnimation.computeDurationHint()
11564 : DEFAULT_DIM_DURATION;
11565 if (target > mDimTargetAlpha) {
Dianne Hackborn1c24e952010-11-23 00:34:30 -080011566 TypedValue tv = new TypedValue();
11567 res.getValue(com.android.internal.R.fraction.config_dimBehindFadeDuration,
11568 tv, true);
11569 if (tv.type == TypedValue.TYPE_FRACTION) {
11570 duration = (long)tv.getFraction((float)duration, (float)duration);
11571 } else if (tv.type >= TypedValue.TYPE_FIRST_INT
11572 && tv.type <= TypedValue.TYPE_LAST_INT) {
11573 duration = tv.data;
11574 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011575 }
11576 if (duration < 1) {
11577 // Don't divide by zero
11578 duration = 1;
11579 }
11580 mDimTargetAlpha = target;
11581 mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration;
11582 }
11583 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011584
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011585 /**
11586 * Updating the surface's alpha. Returns true if the animation continues, or returns
11587 * false when the animation is finished and the dim surface is hidden.
11588 */
11589 boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) {
11590 if (!dimming) {
11591 if (mDimTargetAlpha != 0) {
11592 mLastDimAnimTime = currentTime;
11593 mDimTargetAlpha = 0;
11594 mDimDeltaPerMs = (-mDimCurrentAlpha) / DEFAULT_DIM_DURATION;
11595 }
11596 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080011597
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011598 boolean animating = false;
11599 if (mLastDimAnimTime != 0) {
11600 mDimCurrentAlpha += mDimDeltaPerMs
11601 * (currentTime-mLastDimAnimTime);
11602 boolean more = true;
11603 if (displayFrozen) {
11604 // If the display is frozen, there is no reason to animate.
11605 more = false;
11606 } else if (mDimDeltaPerMs > 0) {
11607 if (mDimCurrentAlpha > mDimTargetAlpha) {
11608 more = false;
11609 }
11610 } else if (mDimDeltaPerMs < 0) {
11611 if (mDimCurrentAlpha < mDimTargetAlpha) {
11612 more = false;
11613 }
11614 } else {
11615 more = false;
11616 }
11617
11618 // Do we need to continue animating?
11619 if (more) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011620 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011621 + mDimSurface + ": alpha=" + mDimCurrentAlpha);
11622 mLastDimAnimTime = currentTime;
11623 mDimSurface.setAlpha(mDimCurrentAlpha);
11624 animating = true;
11625 } else {
11626 mDimCurrentAlpha = mDimTargetAlpha;
11627 mLastDimAnimTime = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011628 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011629 + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
11630 mDimSurface.setAlpha(mDimCurrentAlpha);
11631 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011632 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011633 + ": HIDE");
11634 try {
11635 mDimSurface.hide();
11636 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011637 Slog.w(TAG, "Illegal argument exception hiding dim surface");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011638 }
11639 mDimShown = false;
11640 }
11641 }
11642 }
11643 return animating;
11644 }
11645
11646 public void printTo(PrintWriter pw) {
11647 pw.print(" mDimShown="); pw.print(mDimShown);
11648 pw.print(" current="); pw.print(mDimCurrentAlpha);
11649 pw.print(" target="); pw.print(mDimTargetAlpha);
11650 pw.print(" delta="); pw.print(mDimDeltaPerMs);
11651 pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
11652 }
11653 }
11654
11655 /**
11656 * Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
11657 * This is used for opening/closing transition for apps in compatible mode.
11658 */
11659 private static class FadeInOutAnimation extends Animation {
11660 int mWidth;
11661 boolean mFadeIn;
11662
11663 public FadeInOutAnimation(boolean fadeIn) {
11664 setInterpolator(new AccelerateInterpolator());
11665 setDuration(DEFAULT_FADE_IN_OUT_DURATION);
11666 mFadeIn = fadeIn;
11667 }
11668
11669 @Override
11670 protected void applyTransformation(float interpolatedTime, Transformation t) {
11671 float x = interpolatedTime;
11672 if (!mFadeIn) {
11673 x = 1.0f - x; // reverse the interpolation for fade out
11674 }
11675 if (x < 0.5) {
11676 // move the window out of the screen.
11677 t.getMatrix().setTranslate(mWidth, 0);
11678 } else {
11679 t.getMatrix().setTranslate(0, 0);// show
11680 t.setAlpha((x - 0.5f) * 2);
11681 }
11682 }
11683
11684 @Override
11685 public void initialize(int width, int height, int parentWidth, int parentHeight) {
11686 // width is the screen width {@see AppWindowToken#stepAnimatinoLocked}
11687 mWidth = width;
11688 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011689
11690 @Override
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -070011691 public int getZAdjustment() {
11692 return Animation.ZORDER_TOP;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070011693 }
11694 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011695}